From 8547fe8b10df59a4e3935f9ab59bef16c394103e Mon Sep 17 00:00:00 2001 From: Nimesh Khandelwal Date: Mon, 18 Mar 2024 15:51:40 -0400 Subject: [PATCH] Updated simulator with plant time publishing and communication --- .../custom/include/CommunicationManager.hpp | 6 + .../custom/include/Controller/Controller.hpp | 62 +- locomotion/custom/include/Executor.hpp | 5 +- locomotion/custom/include/Planner/Gait.hpp | 2 + locomotion/custom/include/Planner/Planner.hpp | 5 +- locomotion/custom/include/QuadROSComm.hpp | 8 + locomotion/setup_libraries.sh | 15 + locomotion/src/communication/CMakeLists.txt | 18 +- .../include/CommunicationManager.hpp | 6 + .../src/communication/include/QuadROSComm.hpp | 8 + .../src/CommunicationManager.cpp | 20 + .../src/communication/src/QuadROSComm.cpp | 20 + locomotion/src/execution/CMakeLists.txt | 12 +- locomotion/src/execution/include/Executor.hpp | 2 +- .../include/sim_passive_viewer.hpp | 30 +- .../src/sim_passive_viewer.cpp | 31 +- .../third_party/qpOASES/.coin-or/projDesc.xml | 60 + .../src/third_party/qpOASES/.gitattributes | 238 + locomotion/src/third_party/qpOASES/.gitignore | 1 + .../src/third_party/qpOASES/.gitmodules | 3 + locomotion/src/third_party/qpOASES/AUTHORS | 94 + .../src/third_party/qpOASES/AUTHORS.txt | 94 + .../src/third_party/qpOASES/CMakeLists.txt | 200 + locomotion/src/third_party/qpOASES/INSTALL | 79 + .../src/third_party/qpOASES/INSTALL.txt | 79 + locomotion/src/third_party/qpOASES/LICENSE | 503 + .../src/third_party/qpOASES/LICENSE.txt | 503 + locomotion/src/third_party/qpOASES/Makefile | 118 + locomotion/src/third_party/qpOASES/README | 84 + locomotion/src/third_party/qpOASES/README.txt | 84 + locomotion/src/third_party/qpOASES/VERSIONS | 124 + .../src/third_party/qpOASES/VERSIONS.txt | 124 + .../third_party/qpOASES/doc/DoxygenLayout.xml | 189 + .../src/third_party/qpOASES/doc/Makefile | 66 + .../third_party/qpOASES/doc/doxygen.config | 310 + .../src/third_party/qpOASES/doc/mainpage.dox | 135 + .../src/third_party/qpOASES/doc/manual.pdf | Bin 0 -> 823967 bytes .../src/third_party/qpOASES/examples/Makefile | 107 + .../third_party/qpOASES/examples/example1.cpp | 100 + .../qpOASES/examples/example1a.cpp | 85 + .../qpOASES/examples/example1b.cpp | 90 + .../third_party/qpOASES/examples/example2.cpp | 123 + .../third_party/qpOASES/examples/example3.cpp | 88 + .../qpOASES/examples/example3b.cpp | 88 + .../third_party/qpOASES/examples/example4.cpp | 172 + .../qpOASES/examples/example4CP.cpp | 112 + .../third_party/qpOASES/examples/example5.cpp | 200 + .../qpOASES/examples/exampleLP.cpp | 87 + .../examples/generate_sparse_qp/main.py | 58 + .../generate_sparse_qp/qp_data.in.hpp | 108 + .../generate_sparse_qp/simple_qp_data.hpp | 14376 ++++++++++ .../generate_sparse_qp/trivial_qp_data.hpp | 828 + .../third_party/qpOASES/examples/qrecipe.cpp | 118 + .../qpOASES/examples/qrecipeSchur.cpp | 165 + .../qpOASES/examples/qrecipe_data.hpp | 404 + .../external/ThirdParty-Mumps/.gitattributes | 18 + .../external/ThirdParty-Mumps/.gitignore | 1 + .../qpOASES/external/ThirdParty-Mumps/LICENSE | 87 + .../external/ThirdParty-Mumps/Makefile.am | 937 + .../external/ThirdParty-Mumps/Makefile.in | 2521 ++ .../external/ThirdParty-Mumps/README.md | 76 + .../external/ThirdParty-Mumps/coinmumps.pc.in | 15 + .../qpOASES/external/ThirdParty-Mumps/compile | 384 + .../external/ThirdParty-Mumps/config.guess | 1686 ++ .../external/ThirdParty-Mumps/config.h.in | 112 + .../external/ThirdParty-Mumps/config.sub | 1853 ++ .../external/ThirdParty-Mumps/configure | 21824 ++++++++++++++++ .../external/ThirdParty-Mumps/configure.ac | 242 + .../qpOASES/external/ThirdParty-Mumps/depcomp | 791 + .../external/ThirdParty-Mumps/get.Mumps | 70 + .../external/ThirdParty-Mumps/ltmain.sh | 11147 ++++++++ .../qpOASES/external/ThirdParty-Mumps/missing | 215 + .../ThirdParty-Mumps/mumps_compat.h.in | 26 + .../ThirdParty-Mumps/mumps_int_def.h.in | 10 + .../external/ThirdParty-Mumps/mumps_mpi.patch | 57 + .../third_party/qpOASES/include/qpOASES.hpp | 73 + .../qpOASES/include/qpOASES/Bounds.hpp | 256 + .../qpOASES/include/qpOASES/Bounds.ipp | 120 + .../qpOASES/include/qpOASES/Constants.hpp | 77 + .../include/qpOASES/ConstraintProduct.hpp | 91 + .../qpOASES/include/qpOASES/Constraints.hpp | 246 + .../qpOASES/include/qpOASES/Constraints.ipp | 122 + .../qpOASES/include/qpOASES/Flipper.hpp | 155 + .../qpOASES/include/qpOASES/Indexlist.hpp | 199 + .../qpOASES/include/qpOASES/Indexlist.ipp | 92 + .../include/qpOASES/LapackBlasReplacement.hpp | 128 + .../qpOASES/include/qpOASES/Matrices.hpp | 984 + .../include/qpOASES/MessageHandling.hpp | 480 + .../include/qpOASES/MessageHandling.ipp | 144 + .../qpOASES/include/qpOASES/Options.hpp | 174 + .../qpOASES/include/qpOASES/QProblem.hpp | 1082 + .../qpOASES/include/qpOASES/QProblem.ipp | 284 + .../qpOASES/include/qpOASES/QProblemB.hpp | 1021 + .../qpOASES/include/qpOASES/QProblemB.ipp | 496 + .../qpOASES/include/qpOASES/SQProblem.hpp | 359 + .../qpOASES/include/qpOASES/SQProblem.ipp | 51 + .../include/qpOASES/SQProblemSchur.hpp | 425 + .../include/qpOASES/SQProblemSchur.ipp | 57 + .../qpOASES/include/qpOASES/SparseSolver.hpp | 573 + .../qpOASES/include/qpOASES/SubjectTo.hpp | 229 + .../qpOASES/include/qpOASES/SubjectTo.ipp | 158 + .../qpOASES/include/qpOASES/Types.hpp | 348 + .../qpOASES/include/qpOASES/UnitTesting.hpp | 79 + .../qpOASES/include/qpOASES/Utils.hpp | 366 + .../qpOASES/include/qpOASES/Utils.ipp | 174 + .../include/qpOASES/extras/OQPinterface.hpp | 250 + .../qpOASES/extras/SolutionAnalysis.hpp | 166 + .../qpOASES/extras/SolutionAnalysis.ipp | 51 + .../qpOASES/interfaces/CUTEst/Makefile | 79 + .../qpOASES/interfaces/CUTEst/makeprob | 28 + .../interfaces/CUTEst/qpoasesCutest.cpp | 498 + .../qpOASES/interfaces/CUTEst/readme.txt | 39 + .../third_party/qpOASES/interfaces/c/Makefile | 129 + .../qpOASES/interfaces/c/c_example1.c | 104 + .../qpOASES/interfaces/c/c_example1a.c | 105 + .../qpOASES/interfaces/c/c_example1b.c | 102 + .../qpOASES/interfaces/c/qpOASES_wrapper.cpp | 576 + .../qpOASES/interfaces/c/qpOASES_wrapper.h | 316 + .../qpOASES/interfaces/matlab/Makefile | 85 + .../qpOASES/interfaces/matlab/example1.mat | Bin 0 -> 790 bytes .../qpOASES/interfaces/matlab/example1a.mat | Bin 0 -> 896 bytes .../qpOASES/interfaces/matlab/example1b.mat | Bin 0 -> 549 bytes .../qpOASES/interfaces/matlab/make.m | 254 + .../qpOASES/interfaces/matlab/qpOASES.cpp | 608 + .../qpOASES/interfaces/matlab/qpOASES.m | 75 + .../interfaces/matlab/qpOASES_auxInput.m | 118 + .../matlab/qpOASES_matlab_utils.cpp | 960 + .../matlab/qpOASES_matlab_utils.hpp | 102 + .../interfaces/matlab/qpOASES_options.m | 251 + .../interfaces/matlab/qpOASES_sequence.cpp | 1115 + .../interfaces/matlab/qpOASES_sequence.m | 111 + .../qpOASES/interfaces/matlab/testQPset.m | 40 + .../qpOASES/interfaces/matlab/testSchur.m | 16 + .../qpOASES/interfaces/octave/clean | 3 + .../qpOASES/interfaces/octave/clean.sh | 3 + .../qpOASES/interfaces/octave/example1.mat | Bin 0 -> 790 bytes .../qpOASES/interfaces/octave/example1a.mat | Bin 0 -> 896 bytes .../qpOASES/interfaces/octave/example1b.mat | Bin 0 -> 549 bytes .../qpOASES/interfaces/octave/make.m | 238 + .../qpOASES/interfaces/octave/qpOASES.cpp | 584 + .../qpOASES/interfaces/octave/qpOASES.m | 75 + .../interfaces/octave/qpOASES_auxInput.m | 118 + .../octave/qpOASES_octave_utils.cpp | 950 + .../octave/qpOASES_octave_utils.hpp | 93 + .../interfaces/octave/qpOASES_options.m | 251 + .../interfaces/octave/qpOASES_sequence.cpp | 1104 + .../interfaces/octave/qpOASES_sequence.m | 111 + .../qpOASES/interfaces/python/README.rst | 75 + .../python/examples/cython/example1.pyx | 73 + .../python/examples/cython/setup.py | 16 + .../interfaces/python/examples/example1.py | 74 + .../interfaces/python/examples/example1b.py | 72 + .../interfaces/python/examples/example2.py | 94 + .../qpOASES/interfaces/python/qpoases.pxd | 515 + .../qpOASES/interfaces/python/qpoases.pyx | 920 + .../qpOASES/interfaces/python/setup.py | 105 + .../interfaces/python/tests/__init__.py | 1 + .../interfaces/python/tests/test_examples.py | 360 + .../qpOASES/interfaces/scilab/Makefile | 93 + .../qpOASES/interfaces/scilab/example1.dat | Bin 0 -> 656 bytes .../qpOASES/interfaces/scilab/example1a.dat | Bin 0 -> 784 bytes .../qpOASES/interfaces/scilab/example1b.dat | Bin 0 -> 408 bytes .../interfaces/scilab/qpOASESinterface.c | 893 + .../interfaces/scilab/qpOASESinterface.sce | 41 + .../interfaces/scilab/qpOASESroutines.cpp | 369 + .../interfaces/simulink/example_QProblem.mdl | 762 + .../interfaces/simulink/example_QProblemB.mdl | 728 + .../interfaces/simulink/example_SQProblem.mdl | 797 + .../simulink/load_example_QProblem.m | 86 + .../simulink/load_example_QProblemB.m | 72 + .../simulink/load_example_SQProblem.m | 95 + .../qpOASES/interfaces/simulink/make.m | 239 + .../interfaces/simulink/qpOASES_QProblem.cpp | 507 + .../interfaces/simulink/qpOASES_QProblemB.cpp | 434 + .../interfaces/simulink/qpOASES_SQProblem.cpp | 474 + .../simulink/qpOASES_simulink_utils.cpp | 121 + locomotion/src/third_party/qpOASES/make.mk | 38 + .../src/third_party/qpOASES/make_cygwin.mk | 119 + .../src/third_party/qpOASES/make_linux.mk | 133 + .../src/third_party/qpOASES/make_osx.mk | 124 + .../src/third_party/qpOASES/make_windows.mk | 126 + .../qpOASES/qpOASESConfig.cmake.in | 29 + .../qpOASES/src/BLASReplacement.cpp | 152 + .../src/third_party/qpOASES/src/Bounds.cpp | 514 + .../third_party/qpOASES/src/Constraints.cpp | 499 + .../src/third_party/qpOASES/src/Flipper.cpp | 259 + .../src/third_party/qpOASES/src/Indexlist.cpp | 319 + .../qpOASES/src/LAPACKReplacement.cpp | 159 + .../src/third_party/qpOASES/src/Makefile | 111 + .../src/third_party/qpOASES/src/Matrices.cpp | 2200 ++ .../qpOASES/src/MessageHandling.cpp | 632 + .../third_party/qpOASES/src/OQPinterface.cpp | 683 + .../src/third_party/qpOASES/src/Options.cpp | 563 + .../src/third_party/qpOASES/src/QProblem.cpp | 6461 +++++ .../src/third_party/qpOASES/src/QProblemB.cpp | 3859 +++ .../src/third_party/qpOASES/src/SQProblem.cpp | 559 + .../qpOASES/src/SQProblemSchur.cpp | 3634 +++ .../qpOASES/src/SolutionAnalysis.cpp | 681 + .../third_party/qpOASES/src/SparseSolver.cpp | 1612 ++ .../src/third_party/qpOASES/src/SubjectTo.cpp | 289 + .../src/third_party/qpOASES/src/Utils.cpp | 1061 + .../third_party/qpOASES/testing/c/Makefile | 78 + .../qpOASES/testing/c/test_c_example1.c | 104 + .../qpOASES/testing/c/test_c_example1a.c | 105 + .../qpOASES/testing/c/test_c_example1b.c | 102 + .../qpOASES/testing/checkForMemoryLeaks | 109 + .../third_party/qpOASES/testing/cpp/Makefile | 138 + .../qpOASES/testing/cpp/data/fetch_cpp_data | 34 + .../qpOASES/testing/cpp/test_bench.cpp | 310 + .../testing/cpp/test_constraintProduct1.cpp | 200 + .../testing/cpp/test_constraintProduct2.cpp | 197 + .../qpOASES/testing/cpp/test_example1.cpp | 116 + .../qpOASES/testing/cpp/test_example1a.cpp | 111 + .../qpOASES/testing/cpp/test_example1b.cpp | 112 + .../qpOASES/testing/cpp/test_example2.cpp | 131 + .../qpOASES/testing/cpp/test_example4.cpp | 206 + .../qpOASES/testing/cpp/test_example5.cpp | 204 + .../qpOASES/testing/cpp/test_example6.cpp | 109 + .../qpOASES/testing/cpp/test_example7.cpp | 87 + .../qpOASES/testing/cpp/test_exampleLP.cpp | 115 + .../testing/cpp/test_externalChol1.cpp | 101 + .../testing/cpp/test_gradientShift.cpp | 125 + .../qpOASES/testing/cpp/test_guessedWS1.cpp | 153 + .../qpOASES/testing/cpp/test_hs268.cpp | 106 + .../testing/cpp/test_identitySqproblem.cpp | 129 + .../qpOASES/testing/cpp/test_indexlist.cpp | 96 + .../qpOASES/testing/cpp/test_infeasible1.cpp | 104 + .../qpOASES/testing/cpp/test_janick1.cpp | 190 + .../qpOASES/testing/cpp/test_janick2.cpp | 275 + .../qpOASES/testing/cpp/test_matrices.cpp | 903 + .../qpOASES/testing/cpp/test_matrices2.cpp | 113 + .../qpOASES/testing/cpp/test_matrices3.cpp | 90 + .../qpOASES/testing/cpp/test_qrecipe.cpp | 144 + .../qpOASES/testing/cpp/test_qrecipeSchur.cpp | 178 + .../qpOASES/testing/cpp/test_qrecipe_data.hpp | 401 + .../testing/cpp/test_runAllOqpExamples.cpp | 177 + .../qpOASES/testing/cpp/test_sebastien1.cpp | 74 + .../qpOASES/testing/cpp/test_smallSchur.cpp | 141 + .../testing/cpp/test_vanBarelsUnboundedQP.cpp | 69 + .../testing/matlab/auxFiles/generateExample.m | 25 + .../matlab/auxFiles/generateRandomQp.m | 110 + .../testing/matlab/auxFiles/getKktResidual.m | 134 + .../testing/matlab/auxFiles/isoctave.m | 21 + .../matlab/auxFiles/setupQpDataStruct.m | 18 + .../matlab/auxFiles/setupQpFeaturesStruct.m | 21 + .../testing/matlab/data/fetch_matlab_data | 34 + .../qpOASES/testing/matlab/runAllTests.m | 152 + .../testing/matlab/setupTestingPaths.m | 14 + .../testing/matlab/tests/runAlexInfeas1.m | 30 + .../testing/matlab/tests/runAlexInfeas2.m | 35 + .../matlab/tests/runAlternativeX0Test.m | 84 + .../testing/matlab/tests/runBenchmarkCHAIN1.m | 60 + .../matlab/tests/runBenchmarkCHAIN1A.m | 61 + .../testing/matlab/tests/runBenchmarkCRANE1.m | 55 + .../testing/matlab/tests/runBenchmarkCRANE2.m | 56 + .../testing/matlab/tests/runBenchmarkCRANE3.m | 55 + .../testing/matlab/tests/runBenchmarkDIESEL.m | 59 + .../matlab/tests/runBenchmarkEQUALITY1.m | 56 + .../matlab/tests/runBenchmarkEQUALITY2.m | 60 + .../matlab/tests/runBenchmarkEXAMPLE1.m | 56 + .../matlab/tests/runBenchmarkEXAMPLE1A.m | 56 + .../matlab/tests/runBenchmarkEXAMPLE1B.m | 56 + .../matlab/tests/runBenchmarkIDHESSIAN1.m | 59 + .../matlab/tests/runEmptyHessianTests.m | 261 + .../matlab/tests/runExternalCholeskyTests.m | 214 + .../matlab/tests/runInterfaceSeqTest.m | 436 + .../testing/matlab/tests/runInterfaceTest.m | 462 + .../qpOASES/testing/matlab/tests/runQAP8.m | 37 + .../testing/matlab/tests/runQSHARE1B.m | 44 + .../testing/matlab/tests/runRandomIdHessian.m | 435 + .../matlab/tests/runRandomZeroHessian.m | 433 + .../matlab/tests/runSimpleSpringExample.m | 34 + .../matlab/tests/runTestAPrioriKnownSeq1.m | 87 + .../qpOASES/testing/matlab/tests/runTestSeq.m | 104 + .../testing/matlab/tests/runTestSparse.m | 33 + .../testing/matlab/tests/runTestSparse2.m | 33 + .../testing/matlab/tests/runTestSparse3.m | 39 + .../testing/matlab/tests/runTestSparse4.m | 29 + .../matlab/tests/runTestWorkingSetLI.m | 50 + .../matlab/tests/runVanBarelsUnboundedQP.m | 25 + .../third_party/qpOASES/testing/runUnitTests | 111 + 281 files changed, 124633 insertions(+), 40 deletions(-) create mode 100644 locomotion/src/third_party/qpOASES/.coin-or/projDesc.xml create mode 100644 locomotion/src/third_party/qpOASES/.gitattributes create mode 100644 locomotion/src/third_party/qpOASES/.gitignore create mode 100644 locomotion/src/third_party/qpOASES/.gitmodules create mode 100644 locomotion/src/third_party/qpOASES/AUTHORS create mode 100644 locomotion/src/third_party/qpOASES/AUTHORS.txt create mode 100644 locomotion/src/third_party/qpOASES/CMakeLists.txt create mode 100644 locomotion/src/third_party/qpOASES/INSTALL create mode 100644 locomotion/src/third_party/qpOASES/INSTALL.txt create mode 100644 locomotion/src/third_party/qpOASES/LICENSE create mode 100644 locomotion/src/third_party/qpOASES/LICENSE.txt create mode 100644 locomotion/src/third_party/qpOASES/Makefile create mode 100644 locomotion/src/third_party/qpOASES/README create mode 100644 locomotion/src/third_party/qpOASES/README.txt create mode 100644 locomotion/src/third_party/qpOASES/VERSIONS create mode 100644 locomotion/src/third_party/qpOASES/VERSIONS.txt create mode 100644 locomotion/src/third_party/qpOASES/doc/DoxygenLayout.xml create mode 100644 locomotion/src/third_party/qpOASES/doc/Makefile create mode 100644 locomotion/src/third_party/qpOASES/doc/doxygen.config create mode 100644 locomotion/src/third_party/qpOASES/doc/mainpage.dox create mode 100644 locomotion/src/third_party/qpOASES/doc/manual.pdf create mode 100644 locomotion/src/third_party/qpOASES/examples/Makefile create mode 100644 locomotion/src/third_party/qpOASES/examples/example1.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/example1a.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/example1b.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/example2.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/example3.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/example3b.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/example4.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/example4CP.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/example5.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/exampleLP.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/main.py create mode 100644 locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/qp_data.in.hpp create mode 100644 locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/simple_qp_data.hpp create mode 100644 locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/trivial_qp_data.hpp create mode 100644 locomotion/src/third_party/qpOASES/examples/qrecipe.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/qrecipeSchur.cpp create mode 100644 locomotion/src/third_party/qpOASES/examples/qrecipe_data.hpp create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/.gitattributes create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/.gitignore create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/LICENSE create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/Makefile.am create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/Makefile.in create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/README.md create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/coinmumps.pc.in create mode 100755 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/compile create mode 100755 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.guess create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.h.in create mode 100755 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.sub create mode 100755 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/configure create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/configure.ac create mode 100755 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/depcomp create mode 100755 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/get.Mumps create mode 100755 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/ltmain.sh create mode 100755 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/missing create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_compat.h.in create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_int_def.h.in create mode 100644 locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_mpi.patch create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Bounds.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Bounds.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Constants.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/ConstraintProduct.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Constraints.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Constraints.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Flipper.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Indexlist.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Indexlist.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/LapackBlasReplacement.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Matrices.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/MessageHandling.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/MessageHandling.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Options.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/QProblem.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/QProblem.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/QProblemB.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/QProblemB.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/SQProblem.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/SQProblem.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/SQProblemSchur.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/SQProblemSchur.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/SparseSolver.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/SubjectTo.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/SubjectTo.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Types.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/UnitTesting.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Utils.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/Utils.ipp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/extras/OQPinterface.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/extras/SolutionAnalysis.hpp create mode 100644 locomotion/src/third_party/qpOASES/include/qpOASES/extras/SolutionAnalysis.ipp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/CUTEst/Makefile create mode 100755 locomotion/src/third_party/qpOASES/interfaces/CUTEst/makeprob create mode 100644 locomotion/src/third_party/qpOASES/interfaces/CUTEst/qpoasesCutest.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/CUTEst/readme.txt create mode 100644 locomotion/src/third_party/qpOASES/interfaces/c/Makefile create mode 100644 locomotion/src/third_party/qpOASES/interfaces/c/c_example1.c create mode 100644 locomotion/src/third_party/qpOASES/interfaces/c/c_example1a.c create mode 100644 locomotion/src/third_party/qpOASES/interfaces/c/c_example1b.c create mode 100644 locomotion/src/third_party/qpOASES/interfaces/c/qpOASES_wrapper.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/c/qpOASES_wrapper.h create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/Makefile create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/example1.mat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/example1a.mat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/example1b.mat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/make.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_auxInput.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_matlab_utils.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_matlab_utils.hpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_options.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_sequence.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_sequence.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/testQPset.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/matlab/testSchur.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/clean create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/clean.sh create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/example1.mat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/example1a.mat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/example1b.mat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/make.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_auxInput.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_octave_utils.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_octave_utils.hpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_options.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_sequence.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_sequence.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/README.rst create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/examples/cython/example1.pyx create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/examples/cython/setup.py create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/examples/example1.py create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/examples/example1b.py create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/examples/example2.py create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/qpoases.pxd create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/qpoases.pyx create mode 100755 locomotion/src/third_party/qpOASES/interfaces/python/setup.py create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/tests/__init__.py create mode 100644 locomotion/src/third_party/qpOASES/interfaces/python/tests/test_examples.py create mode 100644 locomotion/src/third_party/qpOASES/interfaces/scilab/Makefile create mode 100644 locomotion/src/third_party/qpOASES/interfaces/scilab/example1.dat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/scilab/example1a.dat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/scilab/example1b.dat create mode 100644 locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESinterface.c create mode 100644 locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESinterface.sce create mode 100644 locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESroutines.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/example_QProblem.mdl create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/example_QProblemB.mdl create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/example_SQProblem.mdl create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_QProblem.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_QProblemB.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_SQProblem.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/make.m create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_QProblem.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_QProblemB.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_SQProblem.cpp create mode 100644 locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_simulink_utils.cpp create mode 100644 locomotion/src/third_party/qpOASES/make.mk create mode 100644 locomotion/src/third_party/qpOASES/make_cygwin.mk create mode 100644 locomotion/src/third_party/qpOASES/make_linux.mk create mode 100644 locomotion/src/third_party/qpOASES/make_osx.mk create mode 100644 locomotion/src/third_party/qpOASES/make_windows.mk create mode 100644 locomotion/src/third_party/qpOASES/qpOASESConfig.cmake.in create mode 100644 locomotion/src/third_party/qpOASES/src/BLASReplacement.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/Bounds.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/Constraints.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/Flipper.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/Indexlist.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/LAPACKReplacement.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/Makefile create mode 100644 locomotion/src/third_party/qpOASES/src/Matrices.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/MessageHandling.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/OQPinterface.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/Options.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/QProblem.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/QProblemB.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/SQProblem.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/SQProblemSchur.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/SolutionAnalysis.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/SparseSolver.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/SubjectTo.cpp create mode 100644 locomotion/src/third_party/qpOASES/src/Utils.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/c/Makefile create mode 100644 locomotion/src/third_party/qpOASES/testing/c/test_c_example1.c create mode 100644 locomotion/src/third_party/qpOASES/testing/c/test_c_example1a.c create mode 100644 locomotion/src/third_party/qpOASES/testing/c/test_c_example1b.c create mode 100755 locomotion/src/third_party/qpOASES/testing/checkForMemoryLeaks create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/Makefile create mode 100755 locomotion/src/third_party/qpOASES/testing/cpp/data/fetch_cpp_data create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_bench.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_constraintProduct1.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_constraintProduct2.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_example1.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_example1a.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_example1b.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_example2.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_example4.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_example5.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_example6.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_example7.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_exampleLP.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_externalChol1.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_gradientShift.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_guessedWS1.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_hs268.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_identitySqproblem.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_indexlist.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_infeasible1.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_janick1.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_janick2.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_matrices.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_matrices2.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_matrices3.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipe.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipeSchur.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipe_data.hpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_runAllOqpExamples.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_sebastien1.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_smallSchur.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/cpp/test_vanBarelsUnboundedQP.cpp create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/generateExample.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/generateRandomQp.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/getKktResidual.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/isoctave.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/setupQpDataStruct.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/setupQpFeaturesStruct.m create mode 100755 locomotion/src/third_party/qpOASES/testing/matlab/data/fetch_matlab_data create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/runAllTests.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/setupTestingPaths.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlexInfeas1.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlexInfeas2.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlternativeX0Test.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCHAIN1.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCHAIN1A.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE1.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE2.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE3.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkDIESEL.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEQUALITY1.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEQUALITY2.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1A.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1B.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkIDHESSIAN1.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runEmptyHessianTests.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runExternalCholeskyTests.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runInterfaceSeqTest.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runInterfaceTest.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runQAP8.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runQSHARE1B.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runRandomIdHessian.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runRandomZeroHessian.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runSimpleSpringExample.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestAPrioriKnownSeq1.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSeq.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse2.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse3.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse4.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestWorkingSetLI.m create mode 100644 locomotion/src/third_party/qpOASES/testing/matlab/tests/runVanBarelsUnboundedQP.m create mode 100755 locomotion/src/third_party/qpOASES/testing/runUnitTests diff --git a/locomotion/custom/include/CommunicationManager.hpp b/locomotion/custom/include/CommunicationManager.hpp index 4edc40a..a622b85 100644 --- a/locomotion/custom/include/CommunicationManager.hpp +++ b/locomotion/custom/include/CommunicationManager.hpp @@ -32,18 +32,23 @@ public: void setJoystickDataPtr(QuadrupedJoystickData* joystick_data_ptr) { m_joystick_data_ptr = joystick_data_ptr; } + void setPlantTimePtr(double* time_ptr) { + m_plant_time_ptr = time_ptr; + } void writeSensorData(const QuadrupedSensorData& sensor_data); void writeCommandData(const QuadrupedCommandData& cmd_data); void writeMeasurementData(const QuadrupedMeasurementData& measure_data); void writeEstimationData(const QuadrupedEstimationData& est_data); void writeJoystickData(const QuadrupedJoystickData& joy_data); + void writePlantTime(const double& time); void getSensorData(QuadrupedSensorData& sensor_data); void getCommandData(QuadrupedCommandData& cmd_data); void getMeasurememtData(QuadrupedMeasurementData& measure_data); void getEstimationData(QuadrupedEstimationData& est_data); void getJoystickData(QuadrupedJoystickData& joy_data); + void getPlantTime(double& time); void setAccessMode(const DATA_ACCESS_MODE& mode) { m_mode = mode; @@ -55,6 +60,7 @@ protected: QuadrupedEstimationData* m_estimation_data_ptr = NULL; QuadrupedMeasurementData* m_measurement_data_ptr = NULL; QuadrupedJoystickData* m_joystick_data_ptr = NULL; + double* m_plant_time_ptr = NULL; int m_mode = DATA_ACCESS_MODE::PLANT; private: diff --git a/locomotion/custom/include/Controller/Controller.hpp b/locomotion/custom/include/Controller/Controller.hpp index fb68d29..4303c44 100644 --- a/locomotion/custom/include/Controller/Controller.hpp +++ b/locomotion/custom/include/Controller/Controller.hpp @@ -7,6 +7,16 @@ #include "memory_types.hpp" #include "utils.hpp" #include "timer.hpp" +// #include "Iir.h" +#include + +using namespace qpOASES; + +#define MU 0.5 +#define GRAVITY 9.8 + +static const double NEGATIVE_NUMBER = -1000000.0; +static const double POSITIVE_NUMBER = 1000000.0; class Controller { public: @@ -16,7 +26,8 @@ public: ~Controller(); - vec12 GetDesiredContactForcePGD(const vec6 &b); + vec12 GetDesiredContactForcePGD(const Eigen::MatrixXd& JabT, const vec6 &b); + vec12 getDesiredContactForceqpOASES(const vec6 &b); virtual vec12 CalculateFeedForwardTorque() { return vec12::Zero(); @@ -76,6 +87,24 @@ protected: // To read QuadrupedEstimationData* m_estimation_data_ptr; QuadrupedPlannerData* m_planner_data_ptr; + + void resize_qpOASES_vars(); + + void resize_eigen_vars(); + + void update_problem_size(); + + void print_real_t(real_t *matrix, int nRows, int nCols); + + void copy_Eigen_to_real_t(real_t *target, Eigen::MatrixXd &source, int nRows, int nCols); + + void copy_real_t_to_Eigen(Eigen::VectorXd &target, real_t *source, int len); + + void print_QPData(); + + Eigen::VectorXd clipVector(const Eigen::VectorXd &b, float F); + + void cleanFc(vec12& Fc); private: std::string m_name; @@ -89,4 +118,35 @@ private: bool m_starting_from_sleep = false; vec12 F_prev; + + // float m_loop_rate = 1000; + // Iir::Butterworth::LowPass<2> m_Fc_filter[12]; + // qpOASES related variables + real_t *H_qpOASES; + + real_t *A_qpOASES; + + real_t *g_qpOASES; + + real_t *lbA_qpOASES; + + real_t *ubA_qpOASES; + + real_t *xOpt_qpOASES; + + real_t *xOpt_initialGuess; + + Eigen::MatrixXd H_eigen, A_eigen, g_eigen, lbA_eigen, ubA_eigen; + + Eigen::VectorXd xOpt_eigen; + + uint8_t real_allocated, num_vars_qp, num_constr_qp, c_st; + + double fz_min, fz_max; + + int_t qp_exit_flag; + + int_t nWSR_qpOASES; + + real_t cpu_time; }; \ No newline at end of file diff --git a/locomotion/custom/include/Executor.hpp b/locomotion/custom/include/Executor.hpp index aace5a0..12e6f58 100644 --- a/locomotion/custom/include/Executor.hpp +++ b/locomotion/custom/include/Executor.hpp @@ -31,7 +31,7 @@ private: std::string m_name; float m_rate = 1000; float m_dt = 0.001; - float t_curr = 0; + double t_curr = 0; float t_last = 0; int delay_ms = 1; int exec_time_ms = 0; @@ -64,6 +64,7 @@ private: Gait stance; Gait trot; + Gait walk; QuadrupedSensorData m_sensor_data; QuadrupedCommandData m_cmd_data; @@ -76,4 +77,6 @@ private: std::chrono::time_point m_currentTimePoint; std::chrono::time_point m_lastTimePoint; std::thread m_comm_thread; + + bool use_plant_time = false; }; \ No newline at end of file diff --git a/locomotion/custom/include/Planner/Gait.hpp b/locomotion/custom/include/Planner/Gait.hpp index 8e7cce2..f0b79c4 100644 --- a/locomotion/custom/include/Planner/Gait.hpp +++ b/locomotion/custom/include/Planner/Gait.hpp @@ -28,6 +28,8 @@ public: void ShowParams(); + void updateInitTime(const float& t0); + Eigen::Array4i GetScheduledContact(const float& t); float GetStridePhase(const float& t, const int& leg_id); diff --git a/locomotion/custom/include/Planner/Planner.hpp b/locomotion/custom/include/Planner/Planner.hpp index 9e19762..af3c9ea 100644 --- a/locomotion/custom/include/Planner/Planner.hpp +++ b/locomotion/custom/include/Planner/Planner.hpp @@ -29,6 +29,7 @@ public: void setGait(Gait& gait) { m_gait = gait; + // m_gait.updateInitTime(m_t_curr); } void setPlannerDataPtr(QuadrupedPlannerData* pd) { @@ -71,11 +72,11 @@ protected: double m_a_max_x = 0.2; double m_a_max_y = 0.2; double m_a_max_z = 0.2; - double m_a_max_yaw = 1.0; + double m_a_max_yaw = 0.2; double max_vel_x = 1.0; double max_vel_y = 1.0; double max_vel_z = 1.0; - double max_vel_yaw = 3.0; + double max_vel_yaw = 1.0; double m_loop_rate = 1000; double m_dt = 0.001; diff --git a/locomotion/custom/include/QuadROSComm.hpp b/locomotion/custom/include/QuadROSComm.hpp index 26ef0e7..fe308fb 100644 --- a/locomotion/custom/include/QuadROSComm.hpp +++ b/locomotion/custom/include/QuadROSComm.hpp @@ -94,5 +94,13 @@ private: sensor_msgs::msg::Joy joystick_data; + double m_plant_time = 0; + + std_msgs::msg::Float32 plant_time; + rclcpp::Publisher::SharedPtr m_plant_time_pub; + rclcpp::Subscription::SharedPtr m_plant_time_sub; + + void get_plant_time_cb(const std_msgs::msg::Float32::SharedPtr msg); + std::thread m_thread; }; \ No newline at end of file diff --git a/locomotion/setup_libraries.sh b/locomotion/setup_libraries.sh index c12cfc2..b5033d2 100755 --- a/locomotion/setup_libraries.sh +++ b/locomotion/setup_libraries.sh @@ -1,8 +1,10 @@ +git submodule update --init --recursive SOURCE_DIR=$PWD INSTALL_DIR=$SOURCE_DIR/custom/install # install eigen3.4 cd $SOURCE_DIR/src/third_party/eigen +git checkout master mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release @@ -12,6 +14,7 @@ make install # install pinocchio without python and install locally cd $SOURCE_DIR/src/third_party/pinocchio +git checkout master mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_UNIT_TESTS=OFF -DBUILD_PYTHON_INTERFACE=OFF -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR @@ -20,6 +23,7 @@ make install # install mujoco locally cd $SOURCE_DIR/src/third_party/mujoco +git checkout main mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR @@ -27,6 +31,7 @@ cmake --build . -j$(($(nproc) - 2)) make install cd $SOURCE_DIR/src/third_party/iir +git checkout master mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR @@ -34,6 +39,7 @@ make -j$(($(nproc) - 2)) make install cd $SOURCE_DIR/src/third_party/cyclonedds +git checkout master mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR # -DENABLE_TYPE_DISCOVERY=ON -DENABLE_TOPIC_DISCOVERY=ON @@ -41,12 +47,21 @@ cmake --build . cmake --build . --target install cd $SOURCE_DIR/src/third_party/cyclonedds-cxx +git checkout master mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR -DCMAKE_PREFIX_PATH=$INSTALL_DIR cmake --build . cmake --build . --target install +cd $SOURCE_DIR/src/third_party/qpOASES +git checkout master +mkdir build +cd build +cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR +make -j$(($(nproc) - 2)) +make install + cd $SOURCE_DIR # chmod +x compile.sh # ./compile.sh diff --git a/locomotion/src/communication/CMakeLists.txt b/locomotion/src/communication/CMakeLists.txt index 00c056e..d037422 100644 --- a/locomotion/src/communication/CMakeLists.txt +++ b/locomotion/src/communication/CMakeLists.txt @@ -28,21 +28,21 @@ elseif($ENV{USE_COMM_TYPE} STREQUAL "ros2") # find_package(catkin REQUIRED) # find_package(genmsg REQUIRED) - find_package(rosidl_default_generators REQUIRED) + # find_package(rosidl_default_generators REQUIRED) # Specify that your package belongs to the rosidl_interface_packages group # set(ROSIDL_INTERFACE_PACKAGES_GROUP "rosidl_interface_packages" CACHE INTERNAL "") # set_property(GLOBAL APPEND PROPERTY ${ROSIDL_INTERFACE_PACKAGES_GROUP} ${PROJECT_NAME}) - rosidl_generate_interfaces(${PROJECT_NAME} - "msgs/ros/LowCmd.msg" - ) - rosidl_get_typesupport_target(cpp_typesupport_target ${PROJECT_NAME} "rosidl_typesupport_cpp") + # rosidl_generate_interfaces(${PROJECT_NAME} + # "msgs/ros/LowCmd.msg" + # ) + # rosidl_get_typesupport_target(cpp_typesupport_target ${PROJECT_NAME} "rosidl_typesupport_cpp") - add_custom_target(${PROJECT_NAME}_ros_msgs ALL - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_cpp/${PROJECT_NAME} - ) - target_link_libraries(${PROJECT_NAME}_ros_msgs "${cpp_typesupport_target}") + # add_custom_target(${PROJECT_NAME}_ros_msgs ALL + # DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_cpp/${PROJECT_NAME} + # ) + # target_link_libraries(${PROJECT_NAME}_ros_msgs "${cpp_typesupport_target}") # install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_cpp/${PROJECT_NAME} # DESTINATION ${COMMON_INCLUDE_DIR} # ) diff --git a/locomotion/src/communication/include/CommunicationManager.hpp b/locomotion/src/communication/include/CommunicationManager.hpp index 4edc40a..a622b85 100644 --- a/locomotion/src/communication/include/CommunicationManager.hpp +++ b/locomotion/src/communication/include/CommunicationManager.hpp @@ -32,18 +32,23 @@ public: void setJoystickDataPtr(QuadrupedJoystickData* joystick_data_ptr) { m_joystick_data_ptr = joystick_data_ptr; } + void setPlantTimePtr(double* time_ptr) { + m_plant_time_ptr = time_ptr; + } void writeSensorData(const QuadrupedSensorData& sensor_data); void writeCommandData(const QuadrupedCommandData& cmd_data); void writeMeasurementData(const QuadrupedMeasurementData& measure_data); void writeEstimationData(const QuadrupedEstimationData& est_data); void writeJoystickData(const QuadrupedJoystickData& joy_data); + void writePlantTime(const double& time); void getSensorData(QuadrupedSensorData& sensor_data); void getCommandData(QuadrupedCommandData& cmd_data); void getMeasurememtData(QuadrupedMeasurementData& measure_data); void getEstimationData(QuadrupedEstimationData& est_data); void getJoystickData(QuadrupedJoystickData& joy_data); + void getPlantTime(double& time); void setAccessMode(const DATA_ACCESS_MODE& mode) { m_mode = mode; @@ -55,6 +60,7 @@ protected: QuadrupedEstimationData* m_estimation_data_ptr = NULL; QuadrupedMeasurementData* m_measurement_data_ptr = NULL; QuadrupedJoystickData* m_joystick_data_ptr = NULL; + double* m_plant_time_ptr = NULL; int m_mode = DATA_ACCESS_MODE::PLANT; private: diff --git a/locomotion/src/communication/include/QuadROSComm.hpp b/locomotion/src/communication/include/QuadROSComm.hpp index 26ef0e7..fe308fb 100644 --- a/locomotion/src/communication/include/QuadROSComm.hpp +++ b/locomotion/src/communication/include/QuadROSComm.hpp @@ -94,5 +94,13 @@ private: sensor_msgs::msg::Joy joystick_data; + double m_plant_time = 0; + + std_msgs::msg::Float32 plant_time; + rclcpp::Publisher::SharedPtr m_plant_time_pub; + rclcpp::Subscription::SharedPtr m_plant_time_sub; + + void get_plant_time_cb(const std_msgs::msg::Float32::SharedPtr msg); + std::thread m_thread; }; \ No newline at end of file diff --git a/locomotion/src/communication/src/CommunicationManager.cpp b/locomotion/src/communication/src/CommunicationManager.cpp index cc1b666..a8034e0 100644 --- a/locomotion/src/communication/src/CommunicationManager.cpp +++ b/locomotion/src/communication/src/CommunicationManager.cpp @@ -119,4 +119,24 @@ void CommunicationManager::getJoystickData(QuadrupedJoystickData& joy_data) { std::cout << "Memory not initialized. Cannot read.\n"; } joy_data.copy(*m_joystick_data_ptr); +} + +void CommunicationManager::getPlantTime(double& time) { + if (m_plant_time_ptr != NULL) { + time = *m_plant_time_ptr; + } else { + std::cout << "Time pointer set to NULL.\n"; + } +} + +void CommunicationManager::writePlantTime(const double& time) { + if (m_mode == DATA_ACCESS_MODE::EXECUTOR) { + std::cout << "Access mode executor. Cannot set time.\n"; + return; + } + if (m_plant_time_ptr != NULL) { + *m_plant_time_ptr = time; + } else { + std::cout << "Time pointer set to NULL.\n"; + } } \ No newline at end of file diff --git a/locomotion/src/communication/src/QuadROSComm.cpp b/locomotion/src/communication/src/QuadROSComm.cpp index 6082d8d..80dd39c 100644 --- a/locomotion/src/communication/src/QuadROSComm.cpp +++ b/locomotion/src/communication/src/QuadROSComm.cpp @@ -78,7 +78,16 @@ void QuadROSComm::initClass() { m_estimated_fc_pub[i] = this->create_publisher("/" + m_name + "/estimation/contact_forces_" + std::to_string(i), 1); } + m_plant_time_sub = this->create_subscription( + "/" + m_name + "/plant_time", + 1, + std::bind(&QuadROSComm::get_plant_time_cb, this, std::placeholders::_1) + ); + } else if (m_mode == DATA_ACCESS_MODE::PLANT) { + + m_plant_time_pub = this->create_publisher("/" + m_name + "/plant_time", 1); + m_joint_state_pub = this->create_publisher("/" + m_name + "/joint_state", 1); m_imu_pub = this->create_publisher("/" + m_name + "/imu", 1); m_odom_pub = this->create_publisher("/" + m_name + "/odom", 1); @@ -139,6 +148,8 @@ void QuadROSComm::initClass() { // js_data.velocity.push_back(0); // js_data.effort.push_back(0); // } + + setPlantTimePtr(&m_plant_time); } void QuadROSComm::get_joint_state_cb(const sensor_msgs::msg::JointState::SharedPtr msg) const { @@ -186,8 +197,13 @@ void QuadROSComm::get_joystick_data_cb(const sensor_msgs::msg::Joy::SharedPtr ms m_joystick_data_ptr -> gait = msg -> axes[4]; } +void QuadROSComm::get_plant_time_cb(const std_msgs::msg::Float32::SharedPtr msg) { + m_plant_time = msg -> data; +} + void QuadROSComm::timer_cb() { if (m_mode == DATA_ACCESS_MODE::EXECUTOR) { + js_data.header.stamp = this -> now(); for (int i = 0; i < 12; ++i) { js_data.position[i] = m_joint_command_data_ptr -> q(i); js_data.velocity[i] = m_joint_command_data_ptr -> qd(i); @@ -213,6 +229,10 @@ void QuadROSComm::timer_cb() { m_joint_state_pub->publish(js_data); } else if (m_mode == DATA_ACCESS_MODE::PLANT) { + // double time = 0; + // getPlantTime(time); + plant_time.data = m_plant_time; + m_plant_time_pub -> publish(plant_time); for (int i = 0; i < 12; ++i) { js_data.position[i] = m_sensor_data_ptr -> q(i); js_data.velocity[i] = m_sensor_data_ptr -> qd(i); diff --git a/locomotion/src/execution/CMakeLists.txt b/locomotion/src/execution/CMakeLists.txt index 495d33d..3062367 100644 --- a/locomotion/src/execution/CMakeLists.txt +++ b/locomotion/src/execution/CMakeLists.txt @@ -38,16 +38,6 @@ target_link_libraries(didc pd_controller ) -add_library(robust_didc STATIC - src/Controller/RobustDIDC.cpp -) -target_compile_options(robust_didc PRIVATE "-fPIC") -target_link_libraries(robust_didc - quad_dynamics - pd_controller - gp_regressor -) - add_library(quad_estimator SHARED src/Estimator/Estimator.cpp src/Estimator/QuadEstimator.cpp @@ -74,7 +64,7 @@ target_link_libraries(reactive_planner install(TARGETS pd_controller didc - robust_didc + # robust_didc quad_estimator base_planner reactive_planner diff --git a/locomotion/src/execution/include/Executor.hpp b/locomotion/src/execution/include/Executor.hpp index 0add653..12e6f58 100644 --- a/locomotion/src/execution/include/Executor.hpp +++ b/locomotion/src/execution/include/Executor.hpp @@ -78,5 +78,5 @@ private: std::chrono::time_point m_lastTimePoint; std::thread m_comm_thread; - bool use_plant_time = true; + bool use_plant_time = false; }; \ No newline at end of file diff --git a/locomotion/src/robot_simulation/include/sim_passive_viewer.hpp b/locomotion/src/robot_simulation/include/sim_passive_viewer.hpp index 9b51643..0534b30 100644 --- a/locomotion/src/robot_simulation/include/sim_passive_viewer.hpp +++ b/locomotion/src/robot_simulation/include/sim_passive_viewer.hpp @@ -1,5 +1,7 @@ #pragma once +#include "simulate.h" + #include #include #include @@ -12,9 +14,13 @@ #include #include +#include "lodepng.h" +#include +#include +#include +#include #include -#include "glfw_adapter.h" -#include "simulate.h" +#include "platform_ui_adapter.h" #include "array_safety.h" #define MUJOCO_PLUGIN_DIR "mujoco_plugin" @@ -40,13 +46,6 @@ extern "C" { #include "SHM.hpp" #endif -// Signal handler to gracefully handle Ctrl+C -void signalHandler(int signum) { - // std::cout << "Interrupt signal (" << signum << ") received.\n"; - // Add cleanup or exit logic as needed - exit(signum); -} - // holders of one step history of time and position to calculate dertivatives mjtNum position_history = 0; mjtNum previous_time = 0; @@ -69,6 +68,18 @@ std::shared_ptr comm_data_ptr; std::shared_ptr comm_data_ptr; #endif +std::chrono::time_point m_startTimePoint; +double t_curr = 0; + +double updateTimer() { + auto currTimePont = std::chrono::high_resolution_clock::now(); + auto start = std::chrono::time_point_cast(m_startTimePoint).time_since_epoch().count(); + auto curr = std::chrono::time_point_cast(currTimePont).time_since_epoch().count(); + auto duration = curr - start; + + return duration * double(1e-6); +} + void UpdateSensorData(mjData*); void CustomController(const mjModel*, mjData*); @@ -398,6 +409,7 @@ void PhysicsLoop(mj::Simulate& sim) { syncSim = d->time; sim.speed_changed = false; + // run single step, let next iteration deal with timing mj_step(m, d); stepped = true; diff --git a/locomotion/src/robot_simulation/src/sim_passive_viewer.cpp b/locomotion/src/robot_simulation/src/sim_passive_viewer.cpp index 583c80d..90fd66b 100644 --- a/locomotion/src/robot_simulation/src/sim_passive_viewer.cpp +++ b/locomotion/src/robot_simulation/src/sim_passive_viewer.cpp @@ -17,6 +17,18 @@ #include #include +#include +#include "glfw_adapter.h" +#include "simulate.h" +#include "array_safety.h" + +// Signal handler to gracefully handle Ctrl+C +void signalHandler(int signum) { + // std::cout << "Interrupt signal (" << signum << ") received.\n"; + // Add cleanup or exit logic as needed + exit(signum); +} + void UpdateSensorData(mjData* data) { if (data == NULL) { return; @@ -60,6 +72,10 @@ void UpdateSensorData(mjData* data) { } void CustomController(const mjModel* model, mjData* data) { + // t_curr = updateTimer(); + t_curr = data->time; + comm_data_ptr -> writePlantTime(t_curr); + UpdateSensorData(data); // get joint command comm_data_ptr->getCommandData(joint_command_data); @@ -69,16 +85,17 @@ void CustomController(const mjModel* model, mjData* data) { // return; // } // std::cout << "cmd js: " << joint_command_data.q.transpose() << "\n"; + // std::cout << "kp: " << joint_command_data.kp.transpose() << "\n"; // float Kp = 20; // float Kd = 0.5; - // float Kp = 60; - // float Kd = 5; - float Kp = 0; - float Kd = 0; + float Kp = 60; + float Kd = 5; + // float Kp = 0; + // float Kd = 0; // if (data->time - last_update > 1.0/ctrl_update_freq) { for (int i = 0; i < 12; ++i) { - Kp = joint_command_data.kp(i); - Kd = joint_command_data.kd(i); + // Kp = joint_command_data.kp(i); + // Kd = joint_command_data.kd(i); float dtheta = joint_command_data.q(i) - sensor_data.q(i); float dtheta_d = joint_command_data.qd(i) - sensor_data.qd(i); // data->ctrl[i] = joint_command_data.tau(i) + joint_command_data.kp(i) * dtheta * joint_command_data.kd(i) * dtheta_d; @@ -168,6 +185,7 @@ int main(int argc, char** argv) { comm_data_ptr->setCommandDataPtr(&joint_command_data); comm_data_ptr->setSensorDataPtr(&sensor_data); comm_data_ptr->setMeasurementDataPtr(&measurement_data); + // comm_data_ptr->setPlantTimePtr(&t_curr); #elif defined(USE_DDS_COMM) comm_data_ptr = std::make_shared(m_name, DATA_ACCESS_MODE::PLANT); comm_data_ptr->setCommandDataPtr(&joint_command_data); @@ -184,6 +202,7 @@ int main(int argc, char** argv) { comm_data_ptr->start_thread(); #endif + m_startTimePoint = std::chrono::high_resolution_clock::now(); // start physics thread std::thread physicsthreadhandle(&PhysicsThread, sim.get(), filename); // physicsthreadhandle.detach(); diff --git a/locomotion/src/third_party/qpOASES/.coin-or/projDesc.xml b/locomotion/src/third_party/qpOASES/.coin-or/projDesc.xml new file mode 100644 index 0000000..9d3f420 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/.coin-or/projDesc.xml @@ -0,0 +1,60 @@ + + + + + qpOASES + + qpOASES is an open-source C++ implementation of the recently + proposed online active set strategy for solving quadratic + programming (QP) problems. It has several theoretical features + that make it particularly suited for model predictive control + (MPC) applications. Further numerical modifications have made + qpOASES a reliable QP solver, even when tackling semi-definite, + ill-posed or degenerated QP problems. Moreover, several + interfaces to third-party software make qpOASES easy-to-use + even for users without knowledge of C/C++. + + An open-source C++ implementation of the recently proposed online active set strategy. + Joachim Ferreau + https://github.com/coin-or/qpOASES + ​GNU Lesser General Public License (LGPL), v2.1 + http://www.gnu.org/licenses/lgpl-2.1.html + + + + BLAS + http://www.netlib.org/blas + Optional + + + LAPACK + http://www.netlib.org/lapack + Optional + + + C++ + + Active + 3 + + + + Linux + g++ + + + Microsoft Windows + CYGWIN/g++ + + + + Optimization deterministic nonlinear + + + + http://www.qpOASES.org/go/manual + https://github.com/coin-or/qpOASES + + http://list.coin-or.org/mailman/listinfo/qpOASES + + diff --git a/locomotion/src/third_party/qpOASES/.gitattributes b/locomotion/src/third_party/qpOASES/.gitattributes new file mode 100644 index 0000000..4433bcf --- /dev/null +++ b/locomotion/src/third_party/qpOASES/.gitattributes @@ -0,0 +1,238 @@ +* text=auto !eol +.coin-or/projDesc.xml -text +/AUTHORS -text +/AUTHORS.txt -text +/CMakeLists.txt -text +/INSTALL -text +/INSTALL.txt -text +/LICENSE -text +/LICENSE.txt -text +/Makefile -text +/README -text +/README.txt -text +/VERSIONS -text +/VERSIONS.txt -text +doc/DoxygenLayout.xml -text +doc/Makefile -text +doc/doxygen.config -text +doc/mainpage.dox -text +doc/manual.pdf -text svneol=unset#unset +examples/Makefile -text +examples/example1.cpp -text +examples/example1a.cpp -text +examples/example1b.cpp -text +examples/example2.cpp -text +examples/example3.cpp -text +examples/example3b.cpp -text +examples/example4.cpp -text +examples/example4CP.cpp -text +examples/example5.cpp -text +examples/exampleLP.cpp -text +examples/qrecipe.cpp -text +examples/qrecipeSchur.cpp -text +examples/qrecipe_data.hpp -text +include/qpOASES.hpp -text +include/qpOASES/Bounds.hpp -text +include/qpOASES/Bounds.ipp -text +include/qpOASES/Constants.hpp -text +include/qpOASES/ConstraintProduct.hpp -text +include/qpOASES/Constraints.hpp -text +include/qpOASES/Constraints.ipp -text +include/qpOASES/Flipper.hpp -text +include/qpOASES/Indexlist.hpp -text +include/qpOASES/Indexlist.ipp -text +include/qpOASES/LapackBlasReplacement.hpp -text +include/qpOASES/Matrices.hpp -text +include/qpOASES/MessageHandling.hpp -text +include/qpOASES/MessageHandling.ipp -text +include/qpOASES/Options.hpp -text +include/qpOASES/QProblem.hpp -text +include/qpOASES/QProblem.ipp -text +include/qpOASES/QProblemB.hpp -text +include/qpOASES/QProblemB.ipp -text +include/qpOASES/SQProblem.hpp -text +include/qpOASES/SQProblem.ipp -text +include/qpOASES/SQProblemSchur.hpp -text +include/qpOASES/SQProblemSchur.ipp -text +include/qpOASES/SparseSolver.hpp -text +include/qpOASES/SubjectTo.hpp -text +include/qpOASES/SubjectTo.ipp -text +include/qpOASES/Types.hpp -text +include/qpOASES/UnitTesting.hpp -text +include/qpOASES/Utils.hpp -text +include/qpOASES/Utils.ipp -text +include/qpOASES/extras/OQPinterface.hpp -text +include/qpOASES/extras/SolutionAnalysis.hpp -text +include/qpOASES/extras/SolutionAnalysis.ipp -text +interfaces/CUTEst/Makefile -text +interfaces/CUTEst/makeprob -text +interfaces/CUTEst/qpoasesCutest.cpp -text +interfaces/CUTEst/readme.txt -text +interfaces/c/Makefile -text +interfaces/c/c_example1.c -text +interfaces/c/c_example1a.c -text +interfaces/c/c_example1b.c -text +interfaces/c/qpOASES_wrapper.cpp -text +interfaces/c/qpOASES_wrapper.h -text +interfaces/matlab/Makefile -text +interfaces/matlab/example1.mat -text +interfaces/matlab/example1a.mat -text +interfaces/matlab/example1b.mat -text +interfaces/matlab/make.m -text +interfaces/matlab/qpOASES.cpp -text +interfaces/matlab/qpOASES.m -text +interfaces/matlab/qpOASES_auxInput.m -text +interfaces/matlab/qpOASES_matlab_utils.cpp -text +interfaces/matlab/qpOASES_matlab_utils.hpp -text +interfaces/matlab/qpOASES_options.m -text +interfaces/matlab/qpOASES_sequence.cpp -text +interfaces/matlab/qpOASES_sequence.m -text +interfaces/matlab/testQPset.m -text +interfaces/matlab/testSchur.m -text +interfaces/octave/clean -text +interfaces/octave/clean.sh -text +interfaces/octave/example1.mat -text +interfaces/octave/example1a.mat -text +interfaces/octave/example1b.mat -text +interfaces/octave/make.m -text +interfaces/octave/qpOASES.cpp -text +interfaces/octave/qpOASES.m -text +interfaces/octave/qpOASES_auxInput.m -text +interfaces/octave/qpOASES_octave_utils.cpp -text +interfaces/octave/qpOASES_octave_utils.hpp -text +interfaces/octave/qpOASES_options.m -text +interfaces/octave/qpOASES_sequence.cpp -text +interfaces/octave/qpOASES_sequence.m -text +interfaces/python/README.rst -text +interfaces/python/examples/cython/example1.pyx -text +interfaces/python/examples/cython/setup.py -text +interfaces/python/examples/example1.py -text +interfaces/python/examples/example1b.py -text +interfaces/python/examples/example2.py -text +interfaces/python/qpoases.pxd -text +interfaces/python/qpoases.pyx -text +interfaces/python/setup.py -text +interfaces/python/tests/__init__.py -text +interfaces/python/tests/test_examples.py -text +interfaces/scilab/Makefile -text +interfaces/scilab/example1.dat -text +interfaces/scilab/example1a.dat -text +interfaces/scilab/example1b.dat -text +interfaces/scilab/qpOASESinterface.c -text +interfaces/scilab/qpOASESinterface.sce -text +interfaces/scilab/qpOASESroutines.cpp -text +interfaces/simulink/example_QProblem.mdl -text +interfaces/simulink/example_QProblemB.mdl -text +interfaces/simulink/example_SQProblem.mdl -text +interfaces/simulink/load_example_QProblem.m -text +interfaces/simulink/load_example_QProblemB.m -text +interfaces/simulink/load_example_SQProblem.m -text +interfaces/simulink/make.m -text +interfaces/simulink/qpOASES_QProblem.cpp -text +interfaces/simulink/qpOASES_QProblemB.cpp -text +interfaces/simulink/qpOASES_SQProblem.cpp -text +interfaces/simulink/qpOASES_simulink_utils.cpp -text +/make.mk -text +/make_cygwin.mk -text +/make_linux.mk -text +/make_osx.mk -text +/make_windows.mk -text +src/BLASReplacement.cpp -text +src/Bounds.cpp -text +src/Constraints.cpp -text +src/Flipper.cpp -text +src/Indexlist.cpp -text +src/LAPACKReplacement.cpp -text +src/Makefile -text +src/Matrices.cpp -text +src/MessageHandling.cpp -text +src/OQPinterface.cpp -text +src/Options.cpp -text +src/QProblem.cpp -text +src/QProblemB.cpp -text +src/SQProblem.cpp -text +src/SQProblemSchur.cpp -text +src/SolutionAnalysis.cpp -text +src/SparseSolver.cpp -text +src/SubjectTo.cpp -text +src/Utils.cpp -text +testing/c/Makefile -text +testing/c/test_c_example1.c -text +testing/c/test_c_example1a.c -text +testing/c/test_c_example1b.c -text +testing/checkForMemoryLeaks -text +testing/cpp/Makefile -text +testing/cpp/data/fetch_cpp_data -text +testing/cpp/test_bench.cpp -text +testing/cpp/test_constraintProduct1.cpp -text +testing/cpp/test_constraintProduct2.cpp -text +testing/cpp/test_example1.cpp -text +testing/cpp/test_example1a.cpp -text +testing/cpp/test_example1b.cpp -text +testing/cpp/test_example2.cpp -text +testing/cpp/test_example4.cpp -text +testing/cpp/test_example5.cpp -text +testing/cpp/test_example6.cpp -text +testing/cpp/test_example7.cpp -text +testing/cpp/test_exampleLP.cpp -text +testing/cpp/test_externalChol1.cpp -text +testing/cpp/test_gradientShift.cpp -text +testing/cpp/test_guessedWS1.cpp -text +testing/cpp/test_hs268.cpp -text +testing/cpp/test_identitySqproblem.cpp -text +testing/cpp/test_indexlist.cpp -text +testing/cpp/test_infeasible1.cpp -text +testing/cpp/test_janick1.cpp -text +testing/cpp/test_janick2.cpp -text +testing/cpp/test_matrices.cpp -text +testing/cpp/test_matrices2.cpp -text +testing/cpp/test_matrices3.cpp -text +testing/cpp/test_qrecipe.cpp -text +testing/cpp/test_qrecipeSchur.cpp -text +testing/cpp/test_qrecipe_data.hpp -text +testing/cpp/test_runAllOqpExamples.cpp -text +testing/cpp/test_sebastien1.cpp -text +testing/cpp/test_smallSchur.cpp -text +testing/cpp/test_vanBarelsUnboundedQP.cpp -text +testing/matlab/auxFiles/generateExample.m -text +testing/matlab/auxFiles/generateRandomQp.m -text +testing/matlab/auxFiles/getKktResidual.m -text +testing/matlab/auxFiles/isoctave.m -text +testing/matlab/auxFiles/setupQpDataStruct.m -text +testing/matlab/auxFiles/setupQpFeaturesStruct.m -text +testing/matlab/data/fetch_matlab_data -text +testing/matlab/runAllTests.m -text +testing/matlab/setupTestingPaths.m -text +testing/matlab/tests/runAlexInfeas1.m -text +testing/matlab/tests/runAlexInfeas2.m -text +testing/matlab/tests/runAlternativeX0Test.m -text +testing/matlab/tests/runBenchmarkCHAIN1.m -text +testing/matlab/tests/runBenchmarkCHAIN1A.m -text +testing/matlab/tests/runBenchmarkCRANE1.m -text +testing/matlab/tests/runBenchmarkCRANE2.m -text +testing/matlab/tests/runBenchmarkCRANE3.m -text +testing/matlab/tests/runBenchmarkDIESEL.m -text +testing/matlab/tests/runBenchmarkEQUALITY1.m -text +testing/matlab/tests/runBenchmarkEQUALITY2.m -text +testing/matlab/tests/runBenchmarkEXAMPLE1.m -text +testing/matlab/tests/runBenchmarkEXAMPLE1A.m -text +testing/matlab/tests/runBenchmarkEXAMPLE1B.m -text +testing/matlab/tests/runBenchmarkIDHESSIAN1.m -text +testing/matlab/tests/runEmptyHessianTests.m -text +testing/matlab/tests/runExternalCholeskyTests.m -text +testing/matlab/tests/runInterfaceSeqTest.m -text +testing/matlab/tests/runInterfaceTest.m -text +testing/matlab/tests/runQAP8.m -text +testing/matlab/tests/runQSHARE1B.m -text +testing/matlab/tests/runRandomIdHessian.m -text +testing/matlab/tests/runRandomZeroHessian.m -text +testing/matlab/tests/runSimpleSpringExample.m -text +testing/matlab/tests/runTestAPrioriKnownSeq1.m -text +testing/matlab/tests/runTestSeq.m -text +testing/matlab/tests/runTestSparse.m -text +testing/matlab/tests/runTestSparse2.m -text +testing/matlab/tests/runTestSparse3.m -text +testing/matlab/tests/runTestSparse4.m -text +testing/matlab/tests/runTestWorkingSetLI.m -text +testing/matlab/tests/runVanBarelsUnboundedQP.m -text +testing/runUnitTests -text diff --git a/locomotion/src/third_party/qpOASES/.gitignore b/locomotion/src/third_party/qpOASES/.gitignore new file mode 100644 index 0000000..66b8c52 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/.gitignore @@ -0,0 +1 @@ +/*.mex diff --git a/locomotion/src/third_party/qpOASES/.gitmodules b/locomotion/src/third_party/qpOASES/.gitmodules new file mode 100644 index 0000000..e42a0ff --- /dev/null +++ b/locomotion/src/third_party/qpOASES/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/ThirdParty-Mumps"] + path = external/ThirdParty-Mumps + url = https://github.com/coin-or-tools/ThirdParty-Mumps.git diff --git a/locomotion/src/third_party/qpOASES/AUTHORS b/locomotion/src/third_party/qpOASES/AUTHORS new file mode 100644 index 0000000..e9ad01c --- /dev/null +++ b/locomotion/src/third_party/qpOASES/AUTHORS @@ -0,0 +1,94 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +MAIN AUTHORS +============ + +qpOASES's core functionality and software design have been developed by the +following main developers (in alphabetical order): + + Hans Joachim Ferreau + Christian Kirches + Andreas Potschka + + + +FURTHER AUTHORS +=============== + +Moreover, the following developers have contributed code to qpOASES's +third-party interfaces or provided additional functionality +(in alphabetical order): + + Alexander Buchner + Holger Diedam + Dennis Janka + Manuel Kudruss + Andreas Waechter + Sebastian F. Walter + + + +CONTRIBUTORS +============ + +Finally, the following people have not contributed to the source code, +but have helped making qpOASES even more useful by testing, reporting +bugs or proposing algorithmic improvements (in alphabetical order): + + Eckhard Arnold + Joris Gillis + Boris Houska + D. Kwame Minde Kufoalor + Aude Perrin + Silvio Traversaro + Milan Vukov + Thomas Wiese + Leonard Wirsching + + + +SCIENTIFIC MENTORS +================== + +We also would like to thank two persons who had a major share in making +qpOASES a success. Not by writing even a single line of code, but by +establishing the idea of using a homotopy-based approach for high-speed +QP solutions and by excellent scientific guidance during the development +process: + + Hans Georg Bock + Moritz Diehl + + + +All users are invited to further improve qpOASES by providing comments, +code enhancements, bug reports, additional documentation or whatever you +feel is missing. + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/AUTHORS.txt b/locomotion/src/third_party/qpOASES/AUTHORS.txt new file mode 100644 index 0000000..012529d --- /dev/null +++ b/locomotion/src/third_party/qpOASES/AUTHORS.txt @@ -0,0 +1,94 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +MAIN AUTHORS +============ + +qpOASES's core functionality and software design have been developed by the +following main developers (in alphabetical order): + + Hans Joachim Ferreau + Christian Kirches + Andreas Potschka + + + +FURTHER AUTHORS +=============== + +Moreover, the following developers have contributed code to qpOASES's +third-party interfaces or provided additional functionality +(in alphabetical order): + + Alexander Buchner + Holger Diedam + Dennis Janka + Manuel Kudruss + Andreas Waechter + Sebastian F. Walter + + + +CONTRIBUTORS +============ + +Finally, the following people have not contributed to the source code, +but have helped making qpOASES even more useful by testing, reporting +bugs or proposing algorithmic improvements (in alphabetical order): + + Eckhard Arnold + Joris Gillis + Boris Houska + D. Kwame Minde Kufoalor + Aude Perrin + Silvio Traversaro + Milan Vukov + Thomas Wiese + Leonard Wirsching + + + +SCIENTIFIC MENTORS +================== + +We also would like to thank two persons who had a major share in making +qpOASES a success. Not by writing even a single line of code, but by +establishing the idea of using a homotopy-based approach for high-speed +QP solutions and by excellent scientific guidance during the development +process: + + Hans Georg Bock + Moritz Diehl + + + +All users are invited to further improve qpOASES by providing comments, +code enhancements, bug reports, additional documentation or whatever you +feel is missing. + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/CMakeLists.txt b/locomotion/src/third_party/qpOASES/CMakeLists.txt new file mode 100644 index 0000000..24c1a81 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/CMakeLists.txt @@ -0,0 +1,200 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: CMakeLists.txt +## Author: Hans Joachim Ferreau (thanks to Milan Vukov) +## Version: 3.2 +## Date: 2007-2017 +## + +cmake_minimum_required(VERSION 2.6) + +PROJECT(qpOASES CXX) +SET(PACKAGE_NAME "qpOASES") +SET(PACKAGE_VERSION "3.2.2") +SET(PACKAGE_SO_VERSION "3.2") +SET(PACKAGE_DESCRIPTION "An implementation of the online active set strategy") +SET(PACKAGE_AUTHOR "Hans Joachim Ferreau, Andreas Potschka, Christian Kirches et al.") +SET(PACKAGE_MAINTAINER "Hans Joachim Ferreau, Andreas Potschka, Christian Kirches et al.") +SET(PACKAGE_URL "https://projects.coin-or.org/qpOASES") + +SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) +SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/libs) + +IF(NOT CMAKE_INSTALL_LIBDIR) + SET(CMAKE_INSTALL_LIBDIR lib) +ENDIF(NOT CMAKE_INSTALL_LIBDIR) + +IF(NOT CMAKE_INSTALL_BINDIR) + SET(CMAKE_INSTALL_BINDIR ${CMAKE_INSTALL_LIBDIR}) +ENDIF(NOT CMAKE_INSTALL_BINDIR) + +IF(NOT CMAKE_INSTALL_INCLUDEDIR) + SET(CMAKE_INSTALL_INCLUDEDIR include) +ENDIF(NOT CMAKE_INSTALL_INCLUDEDIR) + + +IF( NOT CMAKE_VERBOSE_MAKEFILE ) + SET( CMAKE_VERBOSE_MAKEFILE OFF ) +ENDIF( NOT CMAKE_VERBOSE_MAKEFILE ) + +IF( NOT CMAKE_BUILD_TYPE ) + SET(CMAKE_BUILD_TYPE Release CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." + FORCE + ) +ENDIF( NOT CMAKE_BUILD_TYPE ) + +option(BUILD_SHARED_LIBS "If ON, build shared library instead of static" OFF) +option(QPOASES_BUILD_EXAMPLES "Build examples." ON) +option(QPOASES_AVOID_LA_NAMING_CONFLICTS "If ON, avoid to re-defined symbols that conflict with Blas/Lapack provided functions." OFF) + +IF(BUILD_SHARED_LIBS AND WIN32) + MESSAGE(FATAL_ERROR "Compiling qpOASES as a shared library in Windows is not supported.") +ENDIF() + +############################################################ +#################### compiler flags ######################## +############################################################ +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__NO_COPYRIGHT__") +IF(QPOASES_AVOID_LA_NAMING_CONFLICTS) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__AVOID_LA_NAMING_CONFLICTS__") +ENDIF() + +IF ( UNIX ) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Wfloat-equal -Wshadow -DLINUX") + SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} -O3 -finline-functions") +ELSEIF( WINDOWS ) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nologo -EHsc -DWIN32") +ENDIF() + +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D__DEBUG__") + +############################################################ +######################## rpath ############################# +############################################################ +# use, i.e. don't skip the full RPATH for the build tree +set(CMAKE_SKIP_BUILD_RPATH FALSE) + +# when building, don't use the install RPATH already +# (but later on when installing) +set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) + +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:${CMAKE_INSTALL_PREFIX}/lib/casadi") + +# add the automatically determined parts of the RPATH +# which point to directories outside the build tree to the install RPATH +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# the RPATH to be used when installing, but only if it's not a system directory +list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) +if("${isSystemDir}" STREQUAL "-1") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:${CMAKE_INSTALL_PREFIX}/lib/casadi") +endif("${isSystemDir}" STREQUAL "-1") + + + +############################################################ +#################### build and install ##################### +############################################################ +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include) +# compile qpOASES libraries +FILE(GLOB SRC src/*.cpp) + +# library +ADD_LIBRARY(qpOASES ${SRC}) +INSTALL(TARGETS qpOASES + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) +SET_TARGET_PROPERTIES( + qpOASES + PROPERTIES + SOVERSION ${PACKAGE_SO_VERSION} + ) + +# headers +INSTALL(FILES include/qpOASES.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +INSTALL(DIRECTORY include/qpOASES + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.hpp" + PATTERN "*.ipp" + PATTERN ".svn" EXCLUDE) + +############################################################ +######################### Package Config ################### +############################################################ + +include(CMakePackageConfigHelpers) +set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) +set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) +configure_package_config_file(qpOASESConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/qpOASESConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qpOASES + PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR + NO_CHECK_REQUIRED_COMPONENTS_MACRO) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/qpOASESConfigVersion.cmake + VERSION ${PACKAGE_VERSION} + COMPATIBILITY SameMajorVersion) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qpOASESConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/qpOASESConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qpOASES + COMPONENT qpOASES) + +############################################################ +######################### examples ######################### +############################################################ + +if (QPOASES_BUILD_EXAMPLES) + # compile qpOASES examples + SET(EXAMPLE_NAMES + example1 + example1a + example1b + example2 + example3 + example3b + example4 + example5 + exampleLP + qrecipe + qrecipeSchur + ) + + FOREACH(ELEMENT ${EXAMPLE_NAMES}) + ADD_EXECUTABLE(${ELEMENT} examples/${ELEMENT}.cpp) + TARGET_LINK_LIBRARIES(${ELEMENT} qpOASES) + ENDFOREACH(ELEMENT ${EXAMPLE_NAMES}) +endif(QPOASES_BUILD_EXAMPLES) + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/INSTALL b/locomotion/src/third_party/qpOASES/INSTALL new file mode 100644 index 0000000..e4c3d73 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/INSTALL @@ -0,0 +1,79 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +INSTALLATION UNDER LINUX +======================== + +0. Obtain qpOASES from COIN-OR: + +Download a zipped archive containg the latest stable release and unpack it +into . Alternatively, you check out the latest stable branch, +e.g. by running + +svn co https://projects.coin-or.org/svn/qpOASES/stable/3.2 + +from your shell. + + +1. Compilation of the qpOASES library libqpOASES.a (or .so) and test examples: + +cd +make + +The library libqpOASES.a (or .so) provides the complete functionality of the +qpOASES software package. It can be used by, e.g., linking it against a main +function from the examples folder. The make also compiles a couple of test +examples; executables are stored within the directory /bin. + + +2. Running a simple test example: + +Among others, an executable called example1 should have been created; run +it in order to test your installation: + +cd /bin +./example1 + +If it terminates after successfully solving two QP problems, qpOASES has been +successfully installed! + + +3. Optional, create source code documentation (using doxygen): + +cd /doc +doxygen doxygen.config + +Afterwards, you can open the file /doc/html/index.html with +your favorite browser in order to view qpOASES's source code documentation. + + +NOTE: More detailed installation instructions, including information on how + to run unit tests can be found in the qpOASES User's Manual located + at /doc/manual.pdf! + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/INSTALL.txt b/locomotion/src/third_party/qpOASES/INSTALL.txt new file mode 100644 index 0000000..1515425 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/INSTALL.txt @@ -0,0 +1,79 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +INSTALLATION UNDER LINUX +======================== + +0. Obtain qpOASES from COIN-OR: + +Download a zipped archive containg the latest stable release and unpack it +into . Alternatively, you check out the latest stable branch, +e.g. by running + +svn co https://projects.coin-or.org/svn/qpOASES/stable/3.2 + +from your shell. + + +1. Compilation of the qpOASES library libqpOASES.a (or .so) and test examples: + +cd +make + +The library libqpOASES.a (or .so) provides the complete functionality of the +qpOASES software package. It can be used by, e.g., linking it against a main +function from the examples folder. The make also compiles a couple of test +examples; executables are stored within the directory /bin. + + +2. Running a simple test example: + +Among others, an executable called example1 should have been created; run +it in order to test your installation: + +cd /bin +./example1 + +If it terminates after successfully solving two QP problems, qpOASES has been +successfully installed! + + +3. Optional, create source code documentation (using doxygen): + +cd /doc +doxygen doxygen.config + +Afterwards, you can open the file /doc/html/index.html with +your favorite browser in order to view qpOASES's source code documentation. + + +NOTE: More detailed installation instructions, including information on how + to run unit tests can be found in the qpOASES User's Manual located + at /doc/manual.pdf! + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/LICENSE b/locomotion/src/third_party/qpOASES/LICENSE new file mode 100644 index 0000000..9ef3d70 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/LICENSE @@ -0,0 +1,503 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + diff --git a/locomotion/src/third_party/qpOASES/LICENSE.txt b/locomotion/src/third_party/qpOASES/LICENSE.txt new file mode 100644 index 0000000..2d59e84 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/LICENSE.txt @@ -0,0 +1,503 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + diff --git a/locomotion/src/third_party/qpOASES/Makefile b/locomotion/src/third_party/qpOASES/Makefile new file mode 100644 index 0000000..62097aa --- /dev/null +++ b/locomotion/src/third_party/qpOASES/Makefile @@ -0,0 +1,118 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: Makefile +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2007-2017 +## + +include make.mk + +## +## targets +## + + +ifeq ($(DEF_SOLVER), SOLVER_MUMPS) +EXTERNAL = mumps +else +EXTERNAL = +endif + +all: $(EXTERNAL) bin src examples +#src_aw testing + +ifeq ($(DEF_SOLVER), SOLVER_MUMPS) +mumps: + @echo $(QPOASESROOT) + @cd external/ThirdParty-Mumps; \ + if [ -d "MUMPS" ]; then \ + echo "Found MUMPS source code."; \ + else get.Mumps; ./configure --prefix=$(PWD)/external/mumps_installation; fi; \ + make && make install +endif + +src: $(EXTERNAL) + @cd $@; ${MAKE} -s + +bin: + mkdir bin + +#src_aw: +# @cd $@; ${MAKE} -s + +examples: src + @cd $@; ${MAKE} -s + +doc: + @cd $@; ${MAKE} -s + +testing: src + @cd testing/cpp; ${MAKE} -s + +test: testing + @cd testing/cpp; ${MAKE} -s runTests + +debugging: + @cd $@; ${MAKE} -s + +clean: +ifeq ($(DEF_SOLVER), SOLVER_MUMPS) + @echo Cleaning up \(mumps\) + @cd external/ThirdParty-Mumps && ${MAKE} -s clean + @cd external && ${RM} -rf mumps_installation +endif + @cd src && ${MAKE} -s clean + @cd examples && ${MAKE} -s clean + @cd bin && ${RM} -f *.* *{EXE} + @cd testing/cpp && ${MAKE} -s clean + +# && cd src_aw && ${MAKE} -s clean && cd .. \ +# && cd debugging && ${MAKE} -s clean && cd .. \ + + +clobber: clean + +scilab: + @echo Compiling Scilab interface... + @cd ./interfaces/scilab/; ${MAKE} -s + +python: all + cd ./interfaces/python/ && python setup.py build_ext --inplace + +pythoninstall: all + cd ./interfaces/python/ && python setup.py install + +c_wrapper: + @echo Compiling C interface... + @cd ./interfaces/c/; ${MAKE} -s + +.PHONY : all src examples doc testing debugging clean clobber scilab python phythoninstall c_wrapper + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/README b/locomotion/src/third_party/qpOASES/README new file mode 100644 index 0000000..cafbbc2 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/README @@ -0,0 +1,84 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +INTRODUCTION +============ + +qpOASES is an open-source C++ implementation of the recently proposed +online active set strategy, which was inspired by important observations +from the field of parametric quadratic programming (QP). It has several +theoretical features that make it particularly suited for model predictive +control (MPC) applications. Further numerical modifications have made +qpOASES a reliable QP solver, even when tackling semi-definite, ill-posed or +degenerated QP problems. Moreover, several interfaces to third-party software +like ​Matlab or ​Simulink are provided that make qpOASES easy-to-use even for +users without knowledge of C/C++. + + + +GETTING STARTED +=============== + +1. For installation, usage and additional information on this software package + see the qpOASES User's Manual located at doc/manual.pdf or check its + source code documentation! + + +2. The file LICENSE.txt contains a copy of the GNU Lesser General Public + License (v2.1). Please read it carefully before using qpOASES! + + +3. The whole software package can be obtained from + + http://www.qpOASES.org/ or + https://github.com/coin-or/qpOASES/ + + On this webpage you will also find further support such as a list of + questions posed by other users. + + + +CONTACT THE AUTHORS +=================== + +If you have got questions, remarks or comments on qpOASES, it is strongly +encouraged to report them by creating a new ticket at the qpOASES webpage. +In case you do not want to disclose your feedback to the public, you may +send an e-mail to + + support@qpOASES.org + +Finally, you may contact one of the main authors directly: + + Hans Joachim Ferreau, joachim.ferreau@ch.abb.com + Andreas Potschka, potschka@iwr.uni-heidelberg.de + Christian Kirches, christian.kirches@iwr.uni-heidelberg.de + +Also bug reports, source code enhancements or success stories are most welcome! + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/README.txt b/locomotion/src/third_party/qpOASES/README.txt new file mode 100644 index 0000000..6746414 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/README.txt @@ -0,0 +1,84 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +INTRODUCTION +============ + +qpOASES is an open-source C++ implementation of the recently proposed +online active set strategy, which was inspired by important observations +from the field of parametric quadratic programming (QP). It has several +theoretical features that make it particularly suited for model predictive +control (MPC) applications. Further numerical modifications have made +qpOASES a reliable QP solver, even when tackling semi-definite, ill-posed or +degenerated QP problems. Moreover, several interfaces to third-party software +like ​Matlab or ​Simulink are provided that make qpOASES easy-to-use even for +users without knowledge of C/C++. + + + +GETTING STARTED +=============== + +1. For installation, usage and additional information on this software package + see the qpOASES User's Manual located at doc/manual.pdf or check its + source code documentation! + + +2. The file LICENSE.txt contains a copy of the GNU Lesser General Public + License (v2.1). Please read it carefully before using qpOASES! + + +3. The whole software package can be obtained from + + http://www.qpOASES.org/ or + https://projects.coin-or.org/qpOASES/ + + On this webpage you will also find further support such as a list of + questions posed by other users. + + + +CONTACT THE AUTHORS +=================== + +If you have got questions, remarks or comments on qpOASES, it is strongly +encouraged to report them by creating a new ticket at the qpOASES webpage. +In case you do not want to disclose your feedback to the public, you may +send an e-mail to + + support@qpOASES.org + +Finally, you may contact one of the main authors directly: + + Hans Joachim Ferreau, joachim.ferreau@ch.abb.com + Andreas Potschka, potschka@iwr.uni-heidelberg.de + Christian Kirches, christian.kirches@iwr.uni-heidelberg.de + +Also bug reports, source code enhancements or success stories are most welcome! + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/VERSIONS b/locomotion/src/third_party/qpOASES/VERSIONS new file mode 100644 index 0000000..6702e13 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/VERSIONS @@ -0,0 +1,124 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +VERSION HISTORY +=============== + + +3.2 (released on 1st September 2015, last updated on 26th April 2017): +---------------------------------------------------------------------- + ++ Addition of SQProblemSchur class implementing Schur complement approach + for sparse QP problems ++ Introduction of data types int_t and uint_t for integer-valued numbers ++ Minor source code clean-up and bugfixes + + +3.1 (released on 11th February 2015): +------------------------------------- + ++ Addition of C interface ++ Further improved Matlab, Simulink, octave and Python interfaces ++ Possibility to provide pre-computed Cholesky factor of Hessian matrix ++ Source code clean-up and bugfixes + + +3.0 (released on 29th July 2014, last updated on 17th December 2014): +--------------------------------------------------------------------- + ++ Addition of unit testing ++ Several bugfixes + + +3.0beta (released on 16th August 2011, last updated on 4th April 2014): +----------------------------------------------------------------------- + ++ Improved ratio tests and termination check for increased reliabilty ++ Introduction of iterative refinement in step determination and + drift correction to handle ill-conditioned QPs ++ Introduction of ramping strategy to handle degenerated QPs ++ Addition of far bounds and flipping bounds strategy to handle + semi-definite and unbounded QPs more reliably ++ Limited support of sparse QP matrices (also in Matlab interface) ++ Optional linking of LAPACK/BLAS for linear algebra operations ++ Addition of a number of algorithmic options, summarised in an option struct ++ Improved Matlab interface ++ Python interface added ++ Several bugfixes + + +2.0 (released on 10th February 2009, last updated on 7th December 2009): +------------------------------------------------------------------------ + ++ Implementation of regularisation scheme for treating QPs with + semi-definite Hessians ++ Addition of convenience functionality for Bounds and Constraints + objects for specifying guessed active sets ++ Allows to specify a CPU time in addition to an iteration limit ++ Improved efficiency for QPs comprising many constraints ++ Source code cleanup and bugfixing + + +1.3 (released on 2nd June 2008, last updated on 13th August 2008): +------------------------------------------------------------------ + ++ Implementation of "initialised homotopy" concept ++ Addition of the SolutionAnalysis class ++ Utility functions for solving test problems in OQP format added ++ Flexibility of Matlab(R) interface enhanced ++ Major source code cleanup + (Attention: a few class names and calling interfaces have changed!) + + +1.2 (released on 9th October 2007): +----------------------------------- + ++ Special treatment of diagonal Hessians ++ Improved infeasibility detection ++ Further improved Matlab(R) interface ++ Extended Simulink(R) interface ++ scilab interface added ++ Code cleanup and several bugfixes + + +1.1 (released on 8th July 2007): +-------------------------------- + ++ Implementation of the QProblemB class ++ Basic implementation of the SQProblem class ++ Improved Matlab(R) interface ++ Enabling/Disabling of constraints introduced ++ Several bugfixes + + +1.0 (released on 17th April 2007): +---------------------------------- + +Initial release. + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/VERSIONS.txt b/locomotion/src/third_party/qpOASES/VERSIONS.txt new file mode 100644 index 0000000..1d44111 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/VERSIONS.txt @@ -0,0 +1,124 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +VERSION HISTORY +=============== + + +3.2 (released on 1st September 2015, last updated on 26th April 2017): +---------------------------------------------------------------------- + ++ Addition of SQProblemSchur class implementing Schur complement approach + for sparse QP problems ++ Introduction of data types int_t and uint_t for integer-valued numbers ++ Minor source code clean-up and bugfixes + + +3.1 (released on 11th February 2015): +------------------------------------- + ++ Addition of C interface ++ Further improved Matlab, Simulink, octave and Python interfaces ++ Possibility to provide pre-computed Cholesky factor of Hessian matrix ++ Source code clean-up and bugfixes + + +3.0 (released on 29th July 2014, last updated on 17th December 2014): +--------------------------------------------------------------------- + ++ Addition of unit testing ++ Several bugfixes + + +3.0beta (released on 16th August 2011, last updated on 4th April 2014): +----------------------------------------------------------------------- + ++ Improved ratio tests and termination check for increased reliabilty ++ Introduction of iterative refinement in step determination and + drift correction to handle ill-conditioned QPs ++ Introduction of ramping strategy to handle degenerated QPs ++ Addition of far bounds and flipping bounds strategy to handle + semi-definite and unbounded QPs more reliably ++ Limited support of sparse QP matrices (also in Matlab interface) ++ Optional linking of LAPACK/BLAS for linear algebra operations ++ Addition of a number of algorithmic options, summarised in an option struct ++ Improved Matlab interface ++ Python interface added ++ Several bugfixes + + +2.0 (released on 10th February 2009, last updated on 7th December 2009): +------------------------------------------------------------------------ + ++ Implementation of regularisation scheme for treating QPs with + semi-definite Hessians ++ Addition of convenience functionality for Bounds and Constraints + objects for specifying guessed active sets ++ Allows to specify a CPU time in addition to an iteration limit ++ Improved efficiency for QPs comprising many constraints ++ Source code cleanup and bugfixes + + +1.3 (released on 2nd June 2008, last updated on 13th August 2008): +------------------------------------------------------------------ + ++ Implementation of "initialised homotopy" concept ++ Addition of the SolutionAnalysis class ++ Utility functions for solving test problems in OQP format added ++ Flexibility of Matlab(R) interface enhanced ++ Major source code cleanup + (Attention: a few class names and calling interfaces have changed!) + + +1.2 (released on 9th October 2007): +----------------------------------- + ++ Special treatment of diagonal Hessians ++ Improved infeasibility detection ++ Further improved Matlab(R) interface ++ Extended Simulink(R) interface ++ scilab interface added ++ Code cleanup and several bugfixes + + +1.1 (released on 8th July 2007): +-------------------------------- + ++ Implementation of the QProblemB class ++ Basic implementation of the SQProblem class ++ Improved Matlab(R) interface ++ Enabling/Disabling of constraints introduced ++ Several bugfixes + + +1.0 (released on 17th April 2007): +---------------------------------- + +Initial release. + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/doc/DoxygenLayout.xml b/locomotion/src/third_party/qpOASES/doc/DoxygenLayout.xml new file mode 100644 index 0000000..927d94d --- /dev/null +++ b/locomotion/src/third_party/qpOASES/doc/DoxygenLayout.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/locomotion/src/third_party/qpOASES/doc/Makefile b/locomotion/src/third_party/qpOASES/doc/Makefile new file mode 100644 index 0000000..462a5aa --- /dev/null +++ b/locomotion/src/third_party/qpOASES/doc/Makefile @@ -0,0 +1,66 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: Makefile +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2007-2017 +## + + + +## +## settings +## + +MAKEPDF = pdflatex +LATEX = latex + + +## +## targets +## + +all: doc + + +.PHONY: doc +doc: + @ echo "Creating doxygen documentation " + @ doxygen doxygen.config + + +.PHONY: clean +clean: + @ ${RM} -rf ./html + + +.PHONY: clobber +clobber: clean + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/doc/doxygen.config b/locomotion/src/third_party/qpOASES/doc/doxygen.config new file mode 100644 index 0000000..a533465 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/doc/doxygen.config @@ -0,0 +1,310 @@ +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = qpOASES +PROJECT_NUMBER = 3.2.1 +PROJECT_BRIEF = "An Implementation of the Online Active Set Strategy" +PROJECT_LOGO = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = NO +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = YES +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = .. +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +SYMBOL_CACHE_SIZE = 0 +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = DoxygenLayout.xml +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ./mainpage.dox \ +../src \ +../include/qpOASES \ +../include/qpOASES/extras \ +../examples +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.cpp \ +*.ipp \ +*.hpp \ +*.c +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = ../examples +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +SEARCHENGINE = NO +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = RTF +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = MAN +MAN_EXTENSION = .3 +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = XML +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/locomotion/src/third_party/qpOASES/doc/mainpage.dox b/locomotion/src/third_party/qpOASES/doc/mainpage.dox new file mode 100644 index 0000000..50d39dd --- /dev/null +++ b/locomotion/src/third_party/qpOASES/doc/mainpage.dox @@ -0,0 +1,135 @@ +/** + * \mainpage Main Page + * + *

 

+ * + * \section sec_copyright Copyright + * + * qpOASES -- An Implementation of the Online Active Set Strategy. \n + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *

 

+ * + * + * \section sec_developers Authors and Contributors + * + * qpOASES's core functionality and software design have been developed by + * the following main developers (in alphabetical order): + *
    + *
  • Hans Joachim Ferreau + *
  • Christian Kirches + *
  • Andreas Potschka + *
+ * + * Moreover, the following developers have contributed code to qpOASES's + * third-party interfaces or provided additional functionality + * (in alphabetical order): + *
    + *
  • Alexander Buchner + *
  • Holger Diedam + *
  • Dennis Janka + *
  • Manuel Kudruss + *
  • Andreas Waechter + *
  • Sebastian F. Walter + *
+ * + * Finally, the following people have not contributed to the source code, + * but have helped making qpOASES even more useful by testing, reporting + * bugs or proposing algorithmic improvements (in alphabetical order): + *
    + *
  • Eckhard Arnold + *
  • Joris Gillis + *
  • Boris Houska + *
  • D. Kwame Minde Kufoalor + *
  • Aude Perrin + *
  • Milan Vukov + *
  • Thomas Wiese + *
  • Leonard Wirsching + *
+ * + * We also would like to thank two persons who had a major share in making + * qpOASES a success. Not by writing even a single line of code, but by + * establishing the idea of using a homotopy-based approach for high-speed + * QP solutions and by excellent scientific guidance during the development + * process: + *
    + *
  • Hans Georg Bock + *
  • Moritz Diehl + *
+ * + * All users are invited to further improve qpOASES by providing comments, code enhancements, + * bug reports, additional documentation or whatever you feel is missing. The preferred way + * of doing so is to create a new ticket + * at the qpOASES webpage. In case you do not want to disclose your feedback to the public, + * you may send an e-mail to support@qpOASES.org + * or contact one of the main developers directly. + *

 

+ * + * + * \section sec_citing Citing qpOASES + * + * If you use qpOASES within your scientific work, we strongly encourage you to cite at least + * one of the following publications: + * + *
    + *
  • Reference to the software: + * \code + * @ARTICLE{Ferreau2014, + * author = {H.J. Ferreau and C. Kirches and A. Potschka and H.G. Bock and M. Diehl}, + * title = {{qpOASES}: A parametric active-set algorithm for quadratic programming}, + * journal = {Mathematical Programming Computation}, + * year = {2014}, + * volume = {6}, + * number = {4}, + * pages = {327--363}, + * keywords = {qpOASES, parametric quadratic programming, active set method, model predictive control} + * } + * \endcode + * + *
  • Reference to the online active set strategy: + * \code + * @ARTICLE{Ferreau2008, + * author = {H.J. Ferreau and H.G. Bock and M. Diehl}, + * title = {An online active set strategy to overcome the limitations of explicit MPC}, + * journal = {International Journal of Robust and Nonlinear Control}, + * year = {2008}, + * volume = {18}, + * number = {8}, + * pages = {816--830}, + * keywords = {model predictive control, parametric quadratic programming, online active set strategy} + * } + * \endcode + * + *
  • Reference to the webpage: + * \code + * @MISC{qpOASES2017, + * author = {H.J. Ferreau and A. Potschka and C. Kirches}, + * title = {{qpOASES} webpage}, + * howpublished = {http://www.qpOASES.org/}, + * year = {2007--2017}, + * keywords = {qpOASES, model predictive control, parametric quadratic programming, online active set strategy} + * } + * \endcode + *
+ *

 

+ * + * \section sec_moreinfo More Information + * + * More information can be found on http://www.qpOASES.org/ + * and in the qpOASES User's Manual. + *

 

+ */ diff --git a/locomotion/src/third_party/qpOASES/doc/manual.pdf b/locomotion/src/third_party/qpOASES/doc/manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2bb7587230fee022579e7bc183623c1dd35ba8e9 GIT binary patch literal 823967 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 z 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 z z#XQI9A?nSH2BbT$#=j_H#9XG?57srHURyNDE}PHq)4Ns5cf_$?Pfn{z z8+1SJmmvbT`%)F36!12{S@8M zP=KGn1cKp%^+@!JRt&|phV$UoC_@Wex3qYD5sQi8a4F66G5maRY{9umD8mS3`!b#E zf&}zecd$QmgKPfY&=2Zj7_T+Rdq>V0V3FEcu?Be)L<5`SHn4`@S7GI)bE~`!=x?j` ztd{|QF6f^N`X@sFeB}Q%_Rv@Y>m<7tYyU`GzKbJ11pGe1BHb(ldPi|<(d5y7#3#C# zm6GC7N|0nx>EU{e>|WK{67K$@%DcOd`2~8Yb?2GnwYqyanVk6XjuLE62{>&ZaN5;T z)+^fsDI!Mk?i&wkv%CNF51u{*T*@s)(RVForb(yg9@$Am&Q4$G z(hdU?c}FB7-1#xypC0ZwKfb||Yn+eaQM8&31)hg^z{sZnt*ygPy$S?-dp%+eQu9lp zVimY1Jl9h*Mt; zQ4thkziW~o**nh;>xH+b6fPG5BlX5#7P~k?RW1wy_4wUeH8IHB41S+_-VEjcris#%Q1K zr(Gf9x=eHQCnUodRC5zJi3O;ISx^Xx)so|U14MsSFDGOT;up?-w+6{5n@ZwnX)%7I z*8IT&Cf8U|BpNs^Ksje<3^*-L=B;wyhmD`+{8)o5pPC;?U;)D_4o@d6lJT#N<9}0D z`#lZ!FW1Diz(oh#Eu;{fmDO2hL<5wuo~xi@ZrH_30@>w2;bW#)+&G%me=RzL8E73m z`4f(^FUNn;*8GQxD1YB1^6LxLK$Bz|6)c)5`I8)pVr=IUY{yhymeKxbR&{i3-OYq7 zmy)*qjl|%@!(XhE&e6)>5^2YFPQAaUdV<3j=u*yj#@+9uN?0t~-JqDCAgU}HGIHVR zqK@;~X^w%@1N6+5ulU72lr|Xhv+e{6T!Sz#vv@!q_Zd|>n>t1r?Z*$=-&liOV8V#C zMWv$%yEVw$1H(kDI4)>y&l{{9U=-8O8) z$}-raKVpP{29I83OLTugKKi#vK!1aeiK+Ybj`#oJ6>F896L`9ikw}mjjb|OQ zUQg%agObgdyG3ILDv;(~a8CH`Pdi4u<)rZK4Xq1-J*{sdIrqOAuRK|URH51JffbHx z5TJ8V=GfR}48sZiWOUI2Hvbv;`Bo0CM-aaM@E+iHzy6^=-}rC39NOn}%*~Q=YYry^V8R)<>)nw}EPxVsgIymjoqMjMwq&(m1AiPQb&&#@!o$ z*dAKP&q!_*wXuWNQD0<*dMY(?(;B7{`jQ-8UbPoieY+#1fkMCt7-YUBfJxQWx4MSS zjdw|=Ej|ag?)Td;e<6%qK;a{{01EOLKXauIz1ZiY%{`L>j4Wjz@N`*c`&Cr=YrfZi zA$EU{^!?%g<7(k(2JY^{JI8Dr4b-IV!`-RASwcsvBSa!khcZ>VMPgSxl-2lmw7N$! z(*o13s+R0{&HbU{o)#|~lP{*v2m#s{=T!TH z`i4~6l74qd%=*gsBycQX=B1p#1@^LU3cV8+kKSB?VuEMo)ipIv~ zLjI>vDoTI!7KUp(N(>~`3yLnQvSpCHEpKMSl-UKoW$bSs`2um*91U6fnhv~uP$x+wdvEem{V9JHe-Zv-cq3kcIHn#@G#S#@Vn48~a z6Ax^~*##8NZ)pJ<{O@=zf!gkl;Y?a^W)^>4)&*q-Dm-T8pw?c{mw@A7RMa7VudMdB z3GeTC+Sj2>aahM!vproFg@hkT~}IG zkr_KBSace?t5!`Yvo|}P9sVhDMJjH%j_`J1;M2I|3B+elp@veo#G@pGq1SnkKs@sl zSU(G`eSyvcSqvaQlQ#4Y`p%Z0ip5SIqldHG^Gf%ax*l!r3aV3pc`sy^7ZFFt5A26h zfOSnOn*?LG+ppd%FY2hw=A2^`F&_Zq(WH1551S07FLUBLa#0Kh^V=T+!tca*z9)4c zVFZ3)Q-HG=&P#I9g!ra4$jdn<(A|fAw%)X#pW}e3n1jXy5Vo}}|KJn-`-Qi4Kh-dd z-BrXM_-p$y`0RD-Kmrsv2TrU(JU!T2F5Z9F*$=+Z`bP8wT@JkuyIE8Ws8LHdC>WtD z>N@F4i}2|pwV66S0Aq3UK5@GatPZE_CI!?JC`H)ylxG4Aut!haT!VbR2&y2TKLefV zU+k?_G>E?VZJbW^D|Hf#fFO1W7!~*KaamC6)Sz3Vr_PC%A0uZxjx<{As#rQ39?T_d zzJ0^YZxc``jpu_oUI5DrDul_cyif4i!;?6^4Q7c4YeV4v*3#bVr{(NvwmY@^=;qk4 zEB6A=WB}-&rg-yMdV|Jx?j{~NvBT*hBO`nQ`Rgs<0*Bv3$O}nCDx2w#>28nQ_!hE3 zTNFxtk6*gXSy!+w1MDdS1q+l3d-T>NtWZ6`Vt;Xjg51^&3M4EcD7yhjSVxuESI|HM zyMkWk1sd3&pYZ28{Hx;uIAtl*%!6RBD`XfKf;I?2Ao(9+^3l;O_|m%oO0_q~J&_ZZ!stl_IJ%s1{)Ixxob^;niN@DOUi^Xm8AO4QO z_FKLYe1OxArdqw@X-rlwdK?d1$wsQKV$;y-mFcP>vl~Nh8cyPTrdU1Cmg({P-8eh?b*i$ z|3kmbKdy6v-+I-41z7dyW`SVKtx*0opZo2y{3bH||M?OBHAs_EXthXl^!Diwb;rv& zU7adQaun4OSE_&NIhxJycrf>Kht|qu`U%%72sYfglcbf1!hb3&36Vqj)wUpS%zq0N zkQ|k(jVV9>^Nv^ib$v1D22KxV-a1$i#1o)TXQ8bBBO>u5;6d_0Ps*=m{qr;taL0Ib zfGDE01C4a4+t2i6NnvP5I~D7i-hTLjG$(+;MnfyNSL{4qd~cgqWk|+rseS)_>;`oF zD#D?)G4g)~x&NDjJ@>pW$z$78-AR1ZIqGoANJ-AH$Gq#z)%bC;y@IHfM&&`h7xZ&6 z5){*N{#T?cPdBW>#`qXAqmAf$V0eYj7=EwIDD{aobfyE#xY#6O%>UV~C-4LFW+18u?PMQT-O{MU z+l2JV0nGo}{PjA68#oW_l{Du$T_7jL+!UkFMA`BUyp*zUm{$FLZWDC1#`NjDT7xAKTv@1IbjJ7q7z=(|Xj zDjk{Xkj?LUbP&wLC(lp$8`h?pm8ZNi9Ul5vq9;EuReN0d4z9PF7qo^s-tf#JnEuujC@Q78<&Wo zn+QiB?`BmkA$*gy<*2P~UPN7oq(b%}qBS@{cp)rocA(%P{kHCLTRomLM~$@d%*8G-Vr+UY*7JLA%Xgx z_6=0O9>o)H>=6jt!Hb7p*3w3{w!LX^m0(`Mi5Mv#Ls&~H_-f3zcrbXNyDG{7^>6 z*zN6|z0pOWk$=Gmv{5NNI$a=$3MBOdd#j>tkrX$YV+ZJBkg4kH)Y~` ze;k}iMMR_vSsRMCweNnR-5K*`Vg+ zr_*w_0~xCW$h>Ncvcn8GJ&IZs?XJu;Ix!kPQa%z95&`+w^SK?zaB+F zww23r$VM_ArLcOeBn0)SW2V;HB<>;Nq0^~m73a^HC+ihWeURtVbKozeGjh)>80ESJ z7@U`Jyop-8UWc;+^6yT)oXGnruf%&D@kBgN?z15a*$@a^=Al3u6yBNxt+Z$|dc zj?10C8H+{W#@ZrH}tCgR^@The%qC3HRNfZff~hmq_td-qhtEaXRQ;Ajx+|hNqEER>+bK} z?v&K|J+8`b4kn|UOe9a}LoXIr$1ER*Z~v0n(C~9GQOKOkCH?%UP>J`Ci1e8kCqJF3 z>Ps{1LVlL*aXG{MWY9$H`tc(9$BXB=&B>Qu%%Sqmn-H9+*$YdyokM;ejq!Ghr7>n* zHx?*PLmOmi)f(=dMmxTK&QW>SC@A^VX3%(_7x?oO{BwSyF38%nzO6IA%2CY6NV&`N z`Hkeq>4(b?w<|Pzx?FZwP|LrOQI(Ec^6opI8m(#CIpuC~%1Lf4Ms#v?r*d+Uz;uVa z=*>j_)NxCoTJb!Vxs`VVM6aT?>l|D3;_xLM`wT&iX$cPsDvMON%hJ9B2 zobkPEXE};oXn@6T{`v&&c6Owfixp7ZO6hzqvv)LZ_4Mg%;gn|s8FXYylmB?yZ#ne_T3-_kIO(^eXFY*w zcb^%X>pf;+{~F{rs7$|Fac$+;0x@ZniCp!x|0>h^hcbW-W5DI91!1VsgNxlHNc3mO zG(>C6DUx|WRCJMYEIW7pX8i2*XXN;zkVZn1NPP*_X*c`(G=x8n(AnSH)*zcES}h8wCyB#2Vw}q>H4pA*Ka`h&r}`z;J=V z`mCieEsf$z9B@c&^m|~2r>THj&qEVWyx!sOs1{bF5#U8I5U;#=G?PIp|;F>-qPV9@aJXE7(mK!&bDYQNe>F&>_k&1{20WTLOv>j#(1cZ1eu=(H-eRYG`#^X~JN6{IGpg5%yzyL5&=QE(;Y0&;w9#m zdmdAYrOU8-gCep=BNUa;Bsrh5;lo{v1=aE;oSsDANJidjHowlqC zXzZSKRDZy@v$bjQxU=h<75t^o)TxY8#@B|g1?Mx;m#U28-H)%f>DR05%MOIicJDu| zHz0onQx?~#G@Pn{yq#N1cz)v<9chdFnC#Lz(#z_w)6M-pw1|ETPxsSn8i5j6X9}jp zq0}Lccn_)eTK?3X-qIAUxwD8Z-70)okJ6`_-``JV&3>k@k|>MQdCa%7P0@V`_v!tQ zrKPh(_|8`xIvII9guXjdg>vnYkC3cQMG{tmnQHiavdJ+2$cF}^&fQnopIh5a9-orL zypzPyj_$Ic@Mge(ZABY(CGKAjiAI zFI|p5o-ls}Ai1s5>NBqF!K(>#zsKh$n7GILCe^Xi-I=GF4tEu7PhC=f{^h3>QdfmJ znJHFtL@!>}diHshjj6%(;qvqgFcPdQP>C->WAj)=WEZEyvdd>W=yZdxo<%hQf#{h@ z8gUjzokmT!wt5JjK;cx&kiN(CJaUm0C1--%G}QgI3e0Qj$4}k9{qSvXn(WJ$0b9*1 z?+WcsSF~zRIcdDjRYOMftNRs~c9ZPGpI>`5?^|@4=uVe>z4FRGBfmGIB6|)?UVLtr zgcQ%CE|9|#v?`~nIWc3=GVsp1+3&P{P8XTx(E`R-7p%bvmH~>dB)aF9RYz>Ip5}O@ zol4R?Z+WBUK}+MesrpE?dBMXxlk$`DC+M{=zK>l#?~UxaSTKp)Yv(fE>7Ynaq$o&@ zw9rEvK!gARDWOP-g(6+LQpFHLfPg?kFG>}V8j6Hw=q*4HLa4smIrq%Hb7s!DbKdvd zd(XM={73d@lkDs~`+3&0)^B}(PUozv`o-+x2G7+-ZZST`7&Dvx$i?94b}l@=$-O_) zNfit6{5+ah{&Bl@8q*P*7ndOTUa;*834JbCjrirJ(g~%dF-Otb%VjB!MX1zAKhOdw zGL4PeJp3rRn^ zS%^BKO~keEpLlL~P3l@d7sm^eP!ZS(11hVdKsQk+TH9cn!mRx?SkQV~$T0C{U%Y0d zy0)N_B+7Fermf+jVgVT}HP0WfNmzN45=YCNw+npW$Nw?KDq1o#DDVf0NT7ICghq0c zY;zqlyIJsxh4!H=hboUNsb}ev4k)h9_D^t2cT;tZoRnZstv*S059%-(U&{*eIVT$) zbzVPjs8Q9*q{wLV{xar00droc)GfO&v;GmB<%R)LRi7G@oTAa%>8|3JpI_yaXhF`& z`%0&{u;pEUN=iJ`@??OO@>)^2vp=I7+T3i3A$d4MLrxgRns(J}k?17f+&Pfm0MTIm z*ycvPmHkvO92XnFi~JrYN8rviZn8#2N2#|*c#>I)<2@2ks#xT4Z82zznB1DXTWuys zEx&5Aq_vb*KF9*$RS=f|huv~qwRcLlYSp@>L6af{hz;pdMC!PP>?n-2quwtZ?KRJq z6-`D6cc0c_OBel^WbEZtY-L_`2h*6>Y<>TBWt?-j zjqT6&hIXc7drF}i11oUX@7|N> zQVcgY8^=x4HK|@?Bp-ixUIXz|uoQ^x7fn4A=yP7LK5U@+8^*%Q_sC z& zrq#mEweckT=eCs;Pc{XXfz6oH^WgcN$Q^>!3H$I7b5Jec57E$BeB^>`_6ty;%bwKt zNxIM_4%zufUi$^Ev_SaV1w;zU_(B`vW!dE z+VK?E3C%Q=z{VD;$z`b2o`+Q~`pkQ%#5opTTx!iXScx&r^;Y8~B0 zC6cCbI;VVG23Bm1U^#G0ohsE*t~hN**e-sZE*!?_RLvJfUL4 zDr@|{MXIidPbo;yW4(L0JwtIRgK&mV+_%pqKM~Cu5|M)hJx!b479)cxv*vy7_<>c> zFp+`i;aArCrFz`bE#If?RyqguiwY&F_~A1(TG}88Kp4N2OF4yxxn)6`WxKW{+FY## z2jV`PD`33uPu@x$iK2%EKYHK{twMU-e=cS(VD)jbTW$<;~Xk~z%;Y&rkiA*z6~g8#ji zFcrR*9@99%*x?P&arjE-ux?l9lU?D88`JUSf4SD^dZwxT6sC-&;V8YwcOQ?ne*7Da z*nh%7{ms(e&*_ri(?b1sHg^14H})HHp+9N={!UJRPoHP1#dm{T*YAZ0|ChtnO!01;b@T4-QB@!0W6HeQfAgIMazJgjx#1JWQg$+$n}B+FXg9 zv22#4#*gEPWpQ1+^?sap9y({2nj~E?L1p=ZHqPqFBabw*Tz<;|*MmCfhfb$xx zhxSXIuj}erS$BQ?MJ%;_@Y3kGWi|KM1NqLfz57G*a)FmZW!@%Ock>Ib_o2A$#KY6D zM>~~_j2o+ayar#nB-pv!A4^OeO~;l(_N*poHQlOx8}l1}4$ePF)EE`>3J^L)n^3m8 z;dU9`alX?(eD_6*H}1o*FIRd5kC;20PbjX$9ad-3a;@6C@0#W{3na^%q%dCRWFZaD zFZGj~fd#du34g29{9jh~N8C^>&D>*iwOH%w6rSRX+2i$k=Dnxo`QdX}zwv>1DPLjCXFq}#Xpm4FX`VFI1zMWfIxl-=-l!8OPOU8 z4_@ZI4v)`Na|RPFcrC|@sTD(G-}Ugfyy&-Cp1cbgBz}Z}j#~o29_`lackmy1eIsgb zf5ZHo2l~Ve06CS|BRa(?K=-$ph?waHR8)3~`{1Iz%5P}dNHow_2{c+J%hT~t628)H zYSypM0qvC%nFko-1M>|!M2kL<*Z>AyM+P9PZb$5(thPPANwfaGH-ALG3|rH0wmOO{ zI*n*(NY<0vj6N%Ksj3*DCkswG?00zPGSu$#v&Ktl5a;ihOuQ z1z&Dcg;s{obOA?q@6bv$DXq;#L6C`%RZ*!Zi6ubWb7iH)rw}%?zL9$=z9WOpC-Z(T zrEc(+#rad`)p;`AboRn1R$KG{pt4W?9{X;SBG5>|mwA7PLfLx%>-79@iD>@%lg5*2 zg%@uaJ2|D+91~*6NJ%WBCWT=T4W`soS7{%)?#r5Gl@VKIeT@>Zlyei)vEDG^uu?nX zx0TECa|c{*Yy1bnnS1$8nR}&0^UO2Pet8HOX1_S)kJtah_k(FB;{QS~#!UkhE=K_J zMu;0t2kWl}gvR?>lQ8jRo(Clac9(Rf%)CZB@pSo*mu9y?4ug za#ursv`dm4{d~A}?<8eHo3c3=2DP=zHEWy%=(LCiJ@lA%*;AfUVd#=*c0Si=`I(8^ zQXu|V{}7yA!gH4ypJ|oDwjUIj0(*c@;u#*7<`|=uQvfqXJcW11Qy3~g>65ah(N{3T z;eVAi$;{2}LP{FMT=saSEmRE2jh;1q%v3u6H|CvfK#f)WP1ZgozRM~#u`e~IOWy>@ z$@Z8-KetB99VQi>SqkI^%wGz85Sn#0sk=HRF`X5aZ_87B78JD;tSAw5#=M726X=2SnTrn4sM3?;t{3c^s@p+h*FN z=2o%UW%0{wTUPdIZ^nF&kG!K_WDiEza0yed(eP_TPDbrj%l^GPK%U!pWaUb@uoGfK zUNEYB7^dHu#588flG#~P^@Zz5?6y$L#lN>0^5@OR-(X3zZ#gNR+Dxa{weS)i<9tu#n+qw}nCokD_Qa^Z zgx&YU*NMSB1BCjm#?M7(`Z63T?cKoK8)80GoJn#WMq8BNBJNUn!Vow~IOQ-c$H|XN z=p=iwkx-#6R|T+ko zJr#krKd5tADU{s$N|*5v0_B=Nyr>w-!|E?XiJwF_D4wBR*24`+w$+oaa>EOr?3Kfg zwYXlIRNyPCRL==R;VaY&FOI)4iH#Qi8|0vs@P7z7h*T7lA<|cKl9EYsDWAO6p~Z6# z574RVyQ=FlzO`_4avw*2;eQne^l)TDD?{escanZ&`YRLk$Y0u${3)IA&*@C^j~zt+ zILDNK@#|7Ng0NquiFilto%a+~5PHuZ>G^8r=*sKx@kVf&kppWa$n}D>jGppYZORDf zXbnNAK$vCcu^;aUTVrcv`g@Qp5Rq0?0DB zVrdh*#>;~f#J5mOE2;t8mc#*dcHF_t|GN5DI=L6*b+4kA>wt;Qx6;=CPi9|-KPlR| z5&`)u^?4uOZ{HQD-3RIDuXR5c_m}szrcU>Jjhd)9ekmu~l$SrBGz*D16Lxyr(&pac zX90S`uYa0vAhzF0&H^&nzj8%D0C)et(n<#S%zsLYn?J7We}`4kKkM%ZWHi_GR)?3~ zDIBF;o8)qB4CGilh`|7G{Rh4>NwS8)_$JE-#pq`KWI5>tA=j{R8DgXRt&8o&M;K$; zd4{_WPN-3Mrc^sY&A?9X_^Ib3^?sNJa&B7;j(^27eeGlFgAl2B^7_K=>vS<#;9#a8 z-Trs=`!8xZcX{_9G;1`C<5pS4fFenBHvo|6=(u@P0|eyDU*=xIMSL*B*yxlHM^?3R z5YoE$75}2b!uIk{)E7mt@IM5<5mKiBc+FE=U*FZ{fVIUFXOHC z&pKfLm9FbRx87dyli8#q`DV##LzVX@oZ6pgKeah&ZhxZv#9IdL5J6Cd_pWfNZ@cKw zi>Mm9z?g$RtF?OosOz93^BB-O!q(~GJ!!>mig>Us8`+E%CD)AEjF0P-d{P$9{el(q ze|0b-e_(k{s(cv4Lg$Q7?*F?3qu*QB`8{fve@4TAK;OV&h3_ciSyMXS(EzMT%M&0o z8?$$DV(rC#31L^W^!8jjHUpl06GVjvOHhuIFS2y0VL?^9uO3-koEyg z5dc+McRlF;)ms9b06oP;;9UUN;cf*2iXhbQr2_F46Agmks-Fk60y9%tU+E}$iv2n} z0Nt+xaj?QewAxq&fI9%ZN%?>+v(b^Y51z`p3onap(RRbALP#e@rER zISJ3niIWf!JS++#KEf@Q5^KhL7gPA3DV77K*88<6N1!%>+sG-4*fQ#5=_qqR>crhF zopW&&z5GD&^?g(JopJznh9K9LmjcT|V0UtS=I)o;?LDkZIibC2GO)a3Wqo}DyHy^y z9Ecs7=TG{N#f;yqaQyP%Ppw}k;S*6jCpIUJ(WC(%J+uD$(t}Re?0foG(~e~_-;x?8 z)>>~HFYm33k*kfx4Ato~ztS}-|Fl@C0asNBELI-?QQ5!Dp+j?2X~1J#(%)oFF|x+) zGlHfhsdEI;aEF?jNmG}^8h<<(=!^R1Gk*2kHbip!a;kTFWeqOs<&$3;jsK0dVG1Co z^H&=1zdQ+}SK2*_Y6+W+sPqJ|>H&2IHRUxi_Xgni5cWWiU5&(uq^y1N+*dlNia?To zz{_m2X}WGoc}u=k$N^t@ubeh9FqX7bdv?oEc3}2(S;vt<*^opV>d@)#BVLr|YlEVU zwcR5f8Zxh3V7l92&0{U0tvt^mMGfTROLaVNaf2((W2iT#7FHc--}MRYB%_CB-Q1bE z{6rW039{%Vc0s2H8GbtO0ND3p)8FhpCsUa&0QR1jd--;aUKK#@1lUWr#&nifhFy88 zBW9?f@2`z5xvOSQ8ZbFc_h+j*MG-~YqNwqcG$@?He2?N)|Hdb9$10qgKV5WFRI{tg zJ~*Y9%`kk@VeE~4^xd;Zg&;Dz?ge!8!~fDnszZ}JxCye%+K43$HraXo9>qSS$hF8{ zs^Gn=>#~+z) zRIai2XHFk(%ETE5`(K9Jp&UyV*>DOt1#>#+LqKVuRuF|*p$|sw@}AQVQeabLML61jOC=d@p?&2 zKqkhe3eyoz+^IR~Iy#jpbH-);1!U)qq5dQjctor<*C6`BH47^`W`HE)TysLY-kUX> z`$}&ic_YBhl#fl;Zf*oy0B3}laM)E^oE;>3OoH6tZuX)>p<4KU06Q|epL6=~J8of0 zYs8gkGcHg=2H#o>66NRtp{1&or!Ft#skqt0>>PJ|23HjbFrK}8b`=>T2Av&E&ZAH; zB%AnxKKbCI6}LZ#GUi#UJz=#LSk6QZ%*>_5X!dP%Dsk2d!af3u|ZIXT1(%J%##}57qw2rBm=hQ)Bd8pW)V1c>Rc(hda_stgucUnV4SBowl z^gPo|$NLUWf&0j3cZSI>l4GoMRplu&m(CIqww81O_5ZIb(_bzs|MrSUaft`F8YIa> zW-8Oji&_CXmMji=v&nGq3YJ(fTlT5ooG?xt{@w2Jj%)!0M@O-1gf-k^`6*?&fa;{asOlR$ulwvo=ROA&t_T}1N5L1B^+ zWX)Y8S<7Ts?jn~G9b2~8{6*BSJ?#?$om2VE&_m7jAri%vQjJqm(& zWn#xi7a)bmD+yl~dlo$uvI5`|3&zK8pkS5(s_IDDz?Ybu&K&gcL4R_@IZht+KWQos zZCmeh`JZ01YRWHqo{|}XV`R3f3!MxN`wWT#X_eNzx@d%hhuKwxsF@^A$2M6%4T=5q zed*al0CVua-GBYRHW$P6@bBqX`H6t?jkxtcZ4bWpdB4aRZWUB_mO@4Cqe;6K%#%k^ z%asF`W}ptIrnSzx)ctg8o;2&hLb!t`whS}75VsJAOIFaXh@eW*Eh~uaS>WH&;z=j= zg!5>Qle>CrgJm#LxV#?hVn1mB&U5lgCRaMSqS^;l>%*7PV6rU5+RxUq*mvCE!%*3e z+)rNnpB_5kdXHX8k?+bZ@`nBcSDY+*V#!Cj^xoCI%AZ=tPZ8n%f#QG7F(o9;+Uypmu)Orp-74H$ zr@3UEWbM99W`7r4Sdloctifb>vBY%Y-O=**-CREOxIce z@y4A~=qrgHj?|O~X!yev@>J?&Yqx?4>0mU7iE3aZVLIIIya}}}9}t&IEH_Cx*>ei< zS>_3#Q6hFXj$at?tY?4_9a4-kk&adP95li^cYJsO0{GqB83qumLsusVOn^F!BN~;D$mvMybmL!Vf zg7c1a7B5Fkr9f)yqk!a)OufF% zlQ%p~X8Q}l=Os<1`Y+YU#&TcCAW8Wi-S|rPW6JoX`bKk2(n(Xc0X$6(a;&vz&u+lq z4|XLs$6p*r7>6nAw&Y_L7v@YBs+=Ew=xd`oNO7KAN?kx*MI{(5@qTY)SCi7laqID+ zmEYWt0Leh*pNQ3J0CBD8;3fGl5Yj(?FQAd;31Sxcm2TLOqIU4?;`+(Leyo@aVOOEiAV79oYHqC#dewL#gSo8(oCq&}Yq4^KV2O{pz!f(gy8Ht27&yKR@fbCi~O z(P8I1BivLKk_g{V&sAFo9UU6Zk#-*)?)-kO{q5-chwm-`_Mi3V7VBizw(BXJ5Dg4* zv1;~}WYSd-%vGGKU7ow3*U42gBoo&-r}7}K1_oCc@;cQ1nU3kl-;h@RRJ>2YPegG5 z#e2KY6F_aI;S82`8K~Y5DGuv8*4a}F*rP-Xo z;3^(p=|r$hfY?z0Xt4_U-+Jt);{EUx@n~HCa9bU=TUiSFbL6pKDzx|Ek{m%l({|_EcU!%&ZW5;uE7cu1Aw~b zV7>=tv=y^x3;|O6*VX!QFSCNNxODxS2mNuA8eIDJ!*P5X3O#*hkG%lF7b|>n#0=DV zW-`=bZ6)hievaHs60@X}Xl*C10CP236m+kuzHhoxdI)Ay-f}QL=#*~;f6ep*MSOYR z)Bkcd&E^oA_68=b8*eZu0)IGIWgjNCdbyuR&u_ku5qwJ>HL%G>Il|Uq8vt|lvv-2I zGFI`jOF!n|IULC9SWjQDNkT6u@bn_e#agho*-&F}Guq6OQFcVj>9UXmwax-JF`QK1 zXVr{;<-f1G&Wx`AWLwq$_|wFGMveGn(NXA7m2o82Ghau>Z~%S_D%q(C3?l@!r5NJ~ zw3m%8$lAwKb;{ISFFYsg=R38xIR!^O{?xO^mOnLS-^?+c!G|MkAdU{VCslo~BG+lT zQSdM|N@>?M5{=8^@nd;NLP#q|^c?|}U~%V2!weZRea=Qt`a|#SWAx38wpMFf zP3esOmtDoM9{D~_RvOMOaOkpUu(WJUDEG;c+=lUNa8q)5Qt#+6)YzK<@^*E-0b=n> z{XtspE8SE~^FC*5-Eo4;=E+WF($3O2U#gN!Ii#{@y3d~AA_WRCU2)y0y+?cn9?~3O z*3{td_Z&&L*g$$aiB@`?rUwG7LkfJr1T_jYrH5sJKoMbqy-sk2jFDyj8o~;iu<9bY zAlC-blJ=`M%^{#-Kb8#3oz=t$%L>rH{m;eK{|s^NpMR!*=-T*iZ+3Wg-=3P@i!)ip zhY&WaV@~=6nvDb)H=X{JR9up&o#Ny--&v|&)wyg$Xs}7y1@#qed|hsL)I`wHwFINqszXSu`yd)Bh# zi&^MPO|2;6i_rE78l+erpYDf@_gsH_h+;d%2xMdd_iv8wCRKvi23AMCuc+uE!F3We zY+Lb!kL?Xv(ky>I3Kv%Z?iOKB6itIFuLNzXcLt4vBt$1GM!HPw&oj3b@$?l!cq z8uf|dY8@MXw0{a!=)Mx4Gx9Q_;JT@bUl!Y05rUROqBOhDY+ky~IAHz@VpH6bnO)D@24hEj1&E$2E zYI*i~^h0`A<9Nti^x!X|lS$|7<3ILDMLiG(assJ#!;h#%is`8;6((Yx6`aRj?HVjV z$X#LFvDrRPzvxi#qeeU2D5?OqVAV$2n|+AAexclGNIGdSX|S)OqpTKh=kBC}kP zeXhCLIijsIOLmw``N_G{hg&C(7`Mvqqa$qw@wF$xy&Jpf3az`+AeN9re)0uF@i-YH zb`4+A2GjR0*8N9kB8553M@--6wz4k&c>du0e!6GTk)=lu>R($qmU-wp@h6{?q^C4`{UNFBemJ96 zjdAW3lpOohCS@lHGv)jFP%4PiG)Spyuxo@}-{P8?dbT(}ZK2(z#L0%`x7asB_r!Jx^jG|4|*d8A2X2!Y8~hf`u_Oyx9$Ur z;~CFmk43WEC%hi>{YIoqQ#RcX!ij=(>s}#>xm(Tq#o=bvK!N|{{G;f4*3SLWp^|3X z{Bg6k2W7&NPcDZV^uqlr$V8vZ^|zgg?+*7X2>P>7jGMTOmJCZNM{{1W)@Fl9{RbUY zaTd&arZ&(`R|!#$s6g&vBFMEe=M6ILJY|{Xjj1!KMddQ$qCb@2c_(jUO1>IK{wi_-0@H= zZG>bMCWrVO;Pf8SQtq%*9xf{8e7{~x0F{WU9TkR(cs+X9A4mW!gvOo2w;tg~BDSY9 z-AYV6KRuRLzE?6t>WwPQ@ORw_CCqMJ&~J z{ieIne zQk?(qShS zLJVmMK~vofkX{^YG_5TzduBC~XK88%>4I}vPvO7t++l+VR%;%%1y&gjAN!VrA1Gc? zZdr@HK8W{^4D`G6?|kpI#ZIj4&|n`f2)9^RM+HX;UWk#J!IP>hnA@CRm`OAv&e2!= z=Rw9_iim#R1^l#O|7~#4KYq)6%Bks5yF-uUI#+nON#<<<#+Zza6E(&Zr6YqI3s_0U zOAB%x(v=~gj?|Z#$8HkO&6P$IZ|ZNw9+q5}kX=<*|KYK7W+=A^&lj#@fJ1e6Vz1&g z;HnkuG1eE-c&u?50%yj{GqlQX~{XV^O{hFQ(K;`(hISh9DcFr*3-%dd^R8Sli z3jh3?PT>Nr^x#>U@&Sn%u|E0uliu1?bNvQa$)7)ko+)G;(C54+#~d(R0TemShu)Ib z2*4@aKVJxNisiRcHlG7p_n$5eIKutYkw5%&|7XyD?fNPs7Mn4=8a?)Iz&Se#dV*)0P!EbpVj2V4inJ0 z_NOlhBy$<+e{p$-4_FZqhcAbVk5HVy_48N)!V!kK=4S`CWmf+-MvpZh{_P?B^B_H(QMoo0RZy5y zUfl0V)&!};=GJ*}8BLm{^6f09&0}j}L(ALX9@)x(0^7sBbV~|s{wfMWL9YhLg+Ior z^FO`k`=a~g%h@n$Ts1P*R0C{ST&V#*LAS$jWmH1oJ59RZjG!n0+T33WafX%;SsUvt z%twtnB&GQ0Gpb z?7qhosxTch?og$jjHNxnov@97WNMWfh2E1GF&ocW#dSMLqXkPVK=IJm%J~zQ5~4wd z6_uqS(}y!D>|{~2L;mY=Xq8cU(SpK_aJF7Nqx4C&kXgTc&RW&MUhIlE49^L*$K#-k zot=@gus0v#9N7mSw!--;=->JXH^=!@4XlXa_Lc8cJ=Oo73Q2fa(EHXPR4{7N^iR zXWZzk(YL0Y1h7p(srqY~QE&v43W9pej7fSzJG|{oU8ghWIO8eiHZ&PsH&$bgJ!3@=S=Gm3M(*00N=Oa|E+PM)NUQ~Sk%7imb-nzdJNdoB%l?nXR++EFm76#x7|qI!92$ee_v-kVo4 z=f-t8JcCcGzt|h+yp9Yj(ig8b#I!qh2??2(#BIqhSTytbtyennu@oZLP3}!GMK%qz zZ>PDjpuvKgLJW?~agLew3ijtvoq@)DzAX%Ly`fe9vb5F77*=zjyfo^yW497pw6J5? z8>Rq*c>>8q^8qLFFVnPJwH~ z8;IRH(l);QukORQiwc)vvEMb#q=15!>3AnAXY}K+A`)8drMXBaQ$JZL;m&rlLzcD? ze#FbDpO7d77jDaKiF@WhOA^Vk%Y0<+;TF-Labaa9FV|7Ls z8Jpsxtv)PlI%+Y(_O8piBJrVGXWEk?-q+;wf)42eWUqLqagA}&^;%KSZF3}4!9kIaT$*MPsS&0y7tuHPYtIYsJ9)77c%JI~uGx)u z@sjO~2K6QEWyO_?B0ewX@iEffDWGI*Tof8L)gg>$4RmTT?+u@E@7*oYgA}R=W8>Y^ zEM)u?d~#c0*`y95hU*Cf>iWbZ;KMPru&GqnkVmXr;qc?=N_-z|x-yQ_`h12;mej1V!I|58aVjwB{N2bO_F&L8z^AD4*e~aeO!^!>!s?#e14DR~3Gx-&UJd zNTYgz<6)x4E#49TVlNHH4Y>)`{j36UZ?i>+Oa2?jtBX{Kf2E-*i(4F^!r zr%n_Z&0-0Dc+}>!W7^Vwihr^N!WS$#<&vVQQH@8DyI)V_x;}2i(N{IUZsx3lao-QAW6Ff)`pfZLyOm1a^%(TcT0692pa;$YM=Y9e$&uq& z{+o^q#wmf>Wp(~GK0!U2B_?B*KnLNb*N8$`UJ1@GmLu|_h3RoT-rkWkaoI> zfTqE0icxYYMl%mTxiIhy>{D30V&59w>&7ue4tVe9q98}b&Nd)k14;e(l*N@pfv_Yvc)rq@9k{0$2#*flm#WJMs6WT3(L9<#H zz|g9YH!nt2&Yw*+8^l+}DPH>=ZdhJ*6`pI+l?H(eHh1Yl@LJj|V=BDqH=7MG$7N2m zp#`K9>`#DBXiIMMA>6YoFACp4iy2F?pU>@omT*~6Mf*(P@*A>1MM&`OZJIYEwMjQL zqfh+1QiMad8`~$yxv4}{75=_GluSw*U++^pUQq63tQ(|Y@_>}6qH|(D|3ogYM9IC@Y6MusL4mjOm z0EawJ2=W~Eb|tKnp%{%Yppm5$slv>p+CZ3}e#qjyLoXL=(GNIW zoB*mS13`{OJtt~>HhB}Fm$afI2`g7HKQPkMba$i%OVJylvZvID?b%R_s*vG>S&U(t zAqU(_^rj`jE%MD?O>rVpuw5@FRiiuZTEa9QXMM^?6`cDyAsg$t;#Z4(R~^QGyS+rH z;#5KOVY=J*A99_upEWv^Fn#sN8Ew7k_-Cb1JW>mq6J;SajJB`39#orct9K zuBsNrp68VJ2#w^=mHJQi-G^f-9AD{B3y96VuXH=Eb+1poEEM>T?H;g>XC82`)rZ=c zEtxrS23SsLW~h61Jii~R0|YRMeS$7L>iy5}aOaAwz-+~H)eDoa2p$>#F~*QRAX>}J z%zLS0w%T$R@vh8EA#^`uV_#tiNQ*!T+-J9jBt|XX!<@@>O~+ouYT2=d2TMCS&4_5R zJpQ;YJgU8}b^XJquB{>T%=o?wxQDuDQ!Fq8AZVs#yuZ>}N-ORt>b+*l^n5BR=TxM2 z`gjg?`0eXMl{oCpm!G{K@V(sRjq|O8HGz2L#99ML~%4hP6 zabKZir%~UKPJpZ^$0BD?DPeY?P~^LbvPwBCs3{z(Fnp8n(O8f{M0(Kq<7dVwCN}@8 zgRWBBH990Mh$sWhN~g3Be_c95Jcn(Nd69VpgsQd}85y>^IN(~Yg@6`7Zk?1EeI0wX2;II;*E}?sV!2t=hM-$p#UY z#q2gWr`|>}jxip-_~~P{^fk{$||xr)IAHdWVoj2mSk+{PFjlS=oFV{l(}dyL`kYik_49Ty7ns zunG=FzKx4R8)XaSB@A8)#YcUASMbX~&Vmig=P9tZ!KjerSGs}<=HQA4nM_8VmF}Yt z?4LJJ=FPEu(QFUGkmQr3B^`cT6p_AEcIJ*@R=7!;2&>~jmJ!q0+5`dJ6~!Nc)JaO~ z6MuN_VoI($JE)F;OMT99t0~sSMI0wQaDsO*7Sa{l%E=q!>LINW?h{ldW8|Hz*ne}2 ztxl+e6w<1M9vZ(AB2;UH$?eBn$Upj|a2vYbatgjynt!f=fq|99SX?x7-OiEaA+2gv zynMiSu_b&9ha#he5Ips3n!@8-xGj9;?lZ~+=_6np^}2Us-stm)nNw1^cMQ}|I#bT5 zSJ}OY*Vt%?tz7S|cO(L-$#?NNUCz#)kilrN38ZV0CF5dS&OqgwPx!;(oc_G7Gf)eN z&MS8h&YSKe3QLxYZ-Hz$RC3#`0)kiI?Q=tEXA^qStRJ?wbzarU`d_4Ih5KZxuW85n zPTq25rzvzR;VM!M9^(tBItAwyCOq;jQ@4o@cwXtg+-eE!kXw~78(a5G<)=;SMvc~# zGgQyqSrc<7ELu3H4$bjm`so}sVepuQYhqq_m815<6i=k~sdP&yRGD3))l@?hExDj^ zQ$tKcyWq``1XVAz`n*bu&d{R}u3(n^G5?3r%?vH#(|_Ywj9eyQk2h8B_f1efwTX&~+(@Q9N|;U|^@fZf~Q%m_Ack;+aN*h>>f=PO%JKFTvjFOGq=^w&tDe&%u%}v!2j=s2A309@woUX?$csOITI5op)g)3ea_T9 z;6ak?jYnPjW#?@!@`s@L?IC9xy9{g+&lyB2V9yikMR}<;hHGXH0 z&;{ z#ql;JO+U)$0BfX+hSXp(*!EL+DU1gh8T>ugWo!PBXuL0sG?G-BG@*&F#1TmN(u_gk zq|^C0rw`&%NAcw{US4tC+wj%1n=?Ftz&?n%#9dEe_jgnVbSPUxei1pTJqg~8{DAONeeYYJ%?ba zle^WFTt^)bPN5Ms*!RSAa+90c%PIAX>#t1{_&bCA7dP@}uY;q*gD7Cr{~3<;B|F;`5vO+k~G&`v=cr}p&e{d576EvM4P0Fr0WyNR``Y} zrw+}RR8KR6bVe7mj-x!aqy5(;VcJCBsKLbC4qrE*JbE;?pLZSZ5I97o*_>_qn9l5` z?~!$|hx9&LX=odFEJmcMsoB2&#jPz(68J`*a#0c8U>G;?h1X0dQ^(b zH=;_RJ}w$k-C>0?Q#{N2zE_?*W05tKrm8yh(XMJYZzob}t)+t~Haoo2SrqRFQvALF zHoa~bndDS9yfPieTbI^t?jB?-a0l!kZkRWIA$ey&({n)xZ>OK4mou+VmGFU+4YER> zh8Dx8Ygwif7F9vS8(`$BU;T1VzU+9X-;E+DA0#_Zd87^1t@mX&L9j@UrnW2V6LF8Q zF+%oM#|L;f9-N8m(1-wXhATvZA^T7tL`~N8`fdLRsOS_s+gqXchdYj@-Y()bM5%YD zvfgTe3tLN6N#wqnUewHBKLg@v&)4d#Y{#O=dBl48JOd0nSk=dl+gbjCmEr(0rc=1n zFE$0K&lQ4w;)U)!E~OohIj#?mIzhk5^;^vpl5nB3_nkJ{z6UTnFRZI8S$dox=?{J4jtqb^0DS7aK04~75K-GB zu%S@*?S_2GjIKYe&_OdwN(dY=mwyV9sLimLoh8^4Y3NH@P;%j(G`t*zGTO+VT@<$k z5e<;C@o>RTh=lvhEEUF2HLh5ToZM=ta(CD&vlOXGy_a$GMNaA)i{a6HROB%a*7SsA zZ*fT?tl(im$#Nn&LWLRK-f1hOi(-IV$Z2WbOk~(h1!tDlSzjoW;w#7_WbrI-_n>`M zgW{7#gk;G(XP`#SgGI-?QZPw1k~eMMAVIq_OL6Fv0tBp{8W+PrN|fW;{wNxpiejJQ zX4;P_nrKLwjnA8}s-zsHK88Ke(xpjg2^;jkiMxrc0!0aN259f>c1KN@_SY!Ij=mZF zxOFyry?t{da4-$2iE|JDM_)e_wu3_+1t-cHUdZo7GHCsn^$2jwDZuRBFpepCia%G; z7&>g2JI;+YGfcl=C=(Wuf+PzytFj95cZbcuZ(cjC$!f1W+>uzho>yC#wR^*A@!)#- zkjsXapH3fAmbdDM-l2CC@zBpWlbSK<2i0HTx6Zw;4A)p;Z%if-$416F7%pqfo+xSL zQ$^+rN*Rx6y0|B#34y5wQw*^8LU{~ACQuSFk&_=R;aIC}Sw+ncMTbU$gB-d}r6-^+ zDCZl2o0M2ta)nC4C~(q6NR6X@sN&@;RglXT)jeKyEr6&&awShNF9u#7gdcm}id|uGOYJJHsLHCRR}7uh zMW-W{ubJWWl0j0H*PbcLMAtg93Ve2K)2J~nfwR}s1E0+hA6GA#C!N>cxn4F|#?7^> zm{((9v!BjzCJkC>q8z91o^^b|r-9sJJYb+#Jzcro!QQyNcNF2|gzpUG#J>bRGDxVPk+7m%r!Fe=;O#NA*vcU_~w$GOkM!HBTZmR8Acq)f~3qR--YB zutJ-K6atRCy5fkn(AWPiIP(||^>NwatlF!IJAydS- z^cjY%U+TH`GTKlZj?t{?OPFHt%#@lRQ$k_{hXpm$L_z72C~(iT|KT7l&BguFjPmRG=K4o#Ui^mM@FvL)*?vcY%M;)B~-tnf~`-j_VPeWc;ch8 zq0-zwk0j%1*;CIPqq*aPH5BaRM4h$vvG>zRnyh?K*%z}p=^A=XT6xSSDT#RkUpiuK z`MSfYni9b`HPan>(tMHU{e-|#vM*o_Xr4));0(b*|Ld4}S+OStQ10{5tBr((I_^wE zLJOL6c#&eUSU>EYMEqE`1AkExeT0CmFB9#=t+kgu{G@d8i%?o6pJt(uN8Z9vvanWO zF>=%XC|Rgd)zGX+Q1eTo=4jy?j1h`oHIZxHy$@c=UYckweNlTgC8EekOmaZTzi2q$ z3UEP)+{Uy^TI(5O%=-K-NT8AZ!`d8H!T#W?vSeyYU*Y|sjcut;p%o>s4j_lNv=sqI zo3j}u4XaKI(u{;QQSH7k3R0V zXr4<3gT(VvQsvJrYAfu53y(O>NnWh8J`?X2Df5y2{A{&Tl{Qu_2pq+J(@#n~OldU{ z)Tuf&ur!e2#bsy!EwC3a(~ZH+(0rFGD?N>kYtxYd%VlPU?Owm^sQA^ZLmz#T#?6W2 zcR013#r$WZuGPlA&KN5T5jvrFGv3Ahy=I}w>?c%3%wqZ8W0qvB$xn!1nEbR zlEi?N(2E6Bx`YIz3n7F60fB@_KXd^BfdGflq}R|1AmvQ%dgu3>dDngKZ|>ZgcdePV zF8^gO*z7#}dG`K3-%qpH^~5?|ApX1J9K@V#qF}TbHroMN#3Ni9^6QQCDJkM(B&z14PcWsTqGAXs(8;hK>om&SoAhApFE6vOrA7#K9crz$_N(m{5kxu zWJkJv8B&##*A#cYxruPcx-$1qdj<1r`9@Nwmbd@D!}p(gS^vT(QRSoF%njMa%ch?2KipS7Hk-Ld)Y9P?WEOG6 z|BmF)4O=cSYR&6@S&Hn(i3%laqpLluwRQ22;sI?Uyx5ue^2!3P_Kpuq=eYvje`Vc2 zH7j-g?Xx&5E~VgkuC|>|$0f&JihNy2;dEk7fd0&rH&%?GEHgaRrs43Lw0_S@rh?Yyq>+(Rrtu_7xkv~ zH>IY++{e*2PBJf2aFV=?DUR40X@XYcmR#3g(6+#Mrx&4x6Nv6EoOoFevWO}LdIod_ z&h#)#iB78F(-7-TsHN0Y`*;*yl4<4zUB1i(gPDfIOkd`I;^O@Lrd|{Q?5yadOAMo{ z%Eu_>+vu91PQjKm7yzMv2PlRGiWOpw9$|aLvmXuR$=$vGt1DM0m(YLu693$xW6fNT zEUroYaw`LOj9Zs8aE`pkHqh@5;)Hh&L##pM&&^gk4}{bT2^ zp!)SXc0k=O`S5d!LK%nCzTwx{IMv835aF%C4G(h`b4{uxHR)0_y3*Ee<(?t<{P5_| z$H~vBhE)$j?+YAQu4OheSL%p&lDVl`}6bsP1fxFQ$wU z6iC|n8_n{$NhdoCH1H3zj!u4TNWvaw3^dzAzc7l0Z@E8$|9Bo4{vV5s6GHGu-KHt0 z4U)f0;3#HYkFWmsC_Dd03;yr#oi^f-s55QRud~#`5hgvV;qndTziAXB`W64MSv!lU zck8#4b{Z5{%`-F!2Ub*@*iCD-&HJ{9I2rF##!V2GaPaBPv4SH=i`zi%$a9?V4Gg5xg4K? zYiL@FD*SfAQ1c;-Qt&->SntT7Gn95RHYSkpqF)T4T(*0YEqC6|zF+=Z(HU3K<1p*Ia#^{q7NUfh@hqz3oa15qH1wzdN4qypl zM0L!A?jd-XMpn0AEAxQ{08ZxK1WDJo^Gthlm>wP}dF0A?FW_!nvPzapt$3_Pd`Il;bk*sngr`i=3K; zJ=6Ija*Cw_#YQV~$z33&pz)4xKXUhcJ@AtWb;l6vzRhEbeFqOG(Rb}r2D%$nuPnk% zA2{VwEkf*yCr>-X&dil2njyqJqZ13!g!gdYpaP`AIbVT!ApRk#f0!xp$978hRtA( zUnisr+5_w_9XKk+QZEW325Ti#`kMIJ0ES}&ywPA2O_4W}uW27Pda7Nb#-#AbCVf%6 zh`u#eLXZ9J=Em;Amwdk)gwm14x$GN>LXcpC&f)2M__GrYwyJAuT9gFN+lz) z=ef$WFz$qTs3o(*_b~l1K`bFEs^Ud?_Qrx-?^v&E@91}yhIzQQtL}D|E_MECh0F8D zM>P>|kkXr7>oNQbPiG()@kmTUsmAA?=))AF6rMz3J_#lyOdN!6t_n;{VIwiPEQ6ta z4HC4_YBflDU7!`vU%6Xm$#ChNDIW~Fm)reGKK(t-ykA~fhpy)#R^FZGUt*kRqxGxo zS78Adu(?5@eJdCz?I3Ly#l|f%zWq*vn>1E8{`uw0a7woK4Wi~g;6pSIQ790E_tO}e zhnUY$0K76SB>8j;>4zzvVYR2>q*WO>Od6C^tmfLF6SAC85_O#=5qecuKO`*9%Ld>Z z>U(gd%&udVqtX!(+kSVnpTJ2(?IHQ@gx2%dByqe{xm1Bm7Y}zNISy?E$STLu;I%N@ zKJgY6Th(lypJN_)=^Iu%!o}ue0$}2~!yEluSb~xSy=dl4C z!b)%($EMY_uWG;U$J>9O`riZc?-}ynykt(?oD|7?YWmXWE|1!!Pak?nC*NP?@iY)@ zJDJ4s5>#X;3@jPj@1Cw-`-AgZPlf))_1O;3p|1g&fiBUO>r?50%#A)ysuloqtYo|B zU#)j^4!jN%54iV%hwqN~wUZBNhf(afl2GEf)t)_agX00PyHP>HB;P_2RxXVHI{903WXtleeDArI|NF8>e}?`b{b9^~)WtOaTVKoZ zFfP~Dwr1<|VfNx2rYZj6*|u3bV-Kls@U^1m7jK+(-#W`3TmEP3zW;}1(7~AQqlf^mEz!u(jWhqJ>d~*VZHv=lM)iB!6>r@x*s{-C#Qwe94$mSs^3QkM^lG7Bj)gmQKw4 ziRg1Zz64e~H2G^@|_+085p(u$kB)?8bs5O?9tk3$igo-xC%PvrpIrr+BU ztA;^U1%+Gv3d#k7=LB+Bd{P#l6pGXR(F2z*G)~D00OFd)&mdHVyAN&+3MaigusCC* zcP))xw&xqdSAjyS+Y_5VRmi%z;E5%5oLEEf%y;bSCr`tw@(?f1FO)g?5@-`UE?iUlmSKX4#|fTF1W zqcBWJ)V54*mixH{hm97xnHaW}8^fdJAvj?1sB6}c>6)l-0y|go_D1DQUX@19o*A&p zHMJ%oP-2-i)?H#@TI$xx+M8E1X0T{a4)%o{D&A|wCq?u#fV?rhQwd}6!Zb66fU|Cw8!LG z%-2aKDhW$e!*CKMH?N({H@lKyN0wpze$k(sY?*a9RN+ChK*ocY^qJlL@O>+OE zOkXdLCvbJG(j%d?$~39~3_?q_Cficb^VDMzYVVgRG(oCBf*YsORv9rxho+qMzY*y& zCeR^reU^{;?HYXs_PWACG&D2m$acfaKhPf0w$!5 z_d*{0(__N_Ip)cM(%ek&o(u%HHEQ(&hp}QVF66eZ0Q*9DO!3t@#R9{y9n5*NCLb&L zW@5~A2CRj0cbKU#sQrw5Vo#7&F7N0S?jXJkIZ z$Hyw+;H>@lxd4NdJDk@CF$A_*wqdI~+~i|n754M0lJilEpn_x+Dkk2Bx^UcG<~Evz z{*77qtx9R);Y|naEnCBbJE^$`xmjmoLVxhxSf$sXMwQ>Ks5j5g2#6o?DZr1m(U?8q zjrPyC4d>3hEYW^>E}`|_Jz3#|7(o!t!1aL!aB&%1b-Upo$P|Z4TjZn16zN@8E zY~`2TFl@=`{FX3o#LkX^i&7_(PsG=@!Z0Jz7Y1QZ)0E!C+hU~K!)EmJsh>uy`t;LN zDl7M+9mT~v&(jXBWlkCwAO|W>7FNcRl;LoAJhiV|D~k8GmY09?=7rsUWMY~A9>#^e zUxWZD4=OVwD=pmGSviR{)(8bw4qC9CV3M2a{tQ1p5_^_Y=L&0yPY%$HFQSBfN)?Mz z+WGs69BSfN(rEc%-3=>hNz)`#NW7`=W&TTU=ljD_?e=Fv&&>r|dN!C7H1DNG7eFD> zn}G|=L6m^F$RhOx*xr26OUl*_mnQCl3M{t02+osh>eVuEqICMA93@i~@Gs;Ql2FA- z8gE5nlASmJYQ>lE9eqpf;3~ST46X1sT<2WHo_z=?fp||1o+f?`US3&=DA~t)k2m3* z+@)ok+5N$z;L7`)=hCm@^!Lj}H0~|+XPt-9zu6e`4~pEXK=l4PX0AWXWIm-?Ci^%w zyw&acXYZ$o_e-f?Vvb1Yoa~N3Ie1TXd;>+c5ZU`}>8k1LrsHCzO0B{dlSlEq{5MQ! z$g`8arHd>94NDBwQCbr%SiS{*+t!h7;ht?l8=f!f-FA`+0_S$m_^bJJv&qErH_v-A zRsFQawFTG4wLb4%@h>T|(~+=U)S@?94JTRGo5PpD8_evZskw0CTCLyGs%+e7&DKnk z>;mFm_CAmukm~)CNJhecs#GTpZnPp$&tt^O9xq+>$c`@ix}uvcb)xJJ*9BnnHFG$t zMH=IoU>a@VE3G0(EI^AF2!rPEC z3)d!Pb%(~It{t*ygl=j+9b48RVnj>lT|WQ1{i2-G!<~dD0e0I49j*qJft`8#1@`{A zgj|X;?Xkom?pi=COQqAl=2ivNvpORRuRK!}k-MXrR29$LNh1Qc)Y z`>aScEF$uB)`Ln56MYBmL&K+82S93eB}&Q+Vm$F0BV(3Jl;mABC!N?M@v;i^I_DFN zI?Ge3@Qoxn7uD=k^9d*c#5*Uo(_a7bcGffuO}MEdM!c3%x#iF+)l|NI4L^{j{q9_H zUCGD(yVKxjWHXg4;@W$MQ!yhjxP#mr%Jm z;<}y$m}l4d7T`*X4{Ev#gt={Xxd1rE10s$7Va3ojA!^gu$O7k2!yvd%C6Jmi2+SQ=P#I}WmTdDTI``I= z!@g0 z1=hEHHrVR)>T{>q*?|fEC(aQAhSM>BJo6jnwlIJSSpwlFE*Yv&vlr;xBq2%Xlrpee zN_x$vfqc?Ft9o;TntCq%)+ottYnrpIE2cLIi0M>te)N{~k%Xu_%UvIQx z$ejOz_STfX4)0!tMF_~NKvCS)ER9BEIr;QD?l{WC8Pcn^>gH#bSggrf~d#37eh~I2^6-- zZ=XN@s484}*Bc*;R_)TWRb{%a$ZxF`bN|wE_I-AS$bGH%xv?5h6>m7#wUcv=qsL7K zeqYCoC38G=L{3NZSLP&sxVK#`Cw`t+4K4H~QsPS2Im9jU70~IXxDUr0Lpc}rtF7H) zz^}=q1quwMm-_{8IdpS)q~Qg7<#@>`gt zk-M~))6igu5(KE;VqXoGR{4gb_!LS*y=Ex<6mDb@jv@v25@UT!04aesARa+QGSIlM ziB|3r-Z2(NiBi>%#-CRORs~B)ZI1$&V;tDy(xO^tFedc(G6WAu?%6B%EuG8Oe@x1q z4IBnC4J9@|ksz7<6Yhm(ji!WeBR0~Y*k4j`=FVf+tFO7J?<37%xG4oaTRD~T0x4KH zh>d$H^CiLnuL3Pr&N|}@>dymu=Hp0ErB73)`ZV?7OA8ZzqPpvyTesxRo~+9(?szSD zp!iJ}u1lA0uYZ=?u1Ue#*`^DB?i)?R40W&5Xi~{`SBPE4kXq^mseJYfS3paJqGniI;4wEt!h~cDGbfm|u`Q!^lo@ zrw2#C_50@gjb#bOC|!ltVMhhq#DXvcEvG|Ver~^1B~ljuMY;v+={;ksXU>*Mh>^Z$ z{!~&Xayq(};sjMLP+?i6;Pza^+qxKz;+SQE8S?>yQ;@dF8cfxgH8Qt&Aj;fYW?6pP z`%h{!SpveLF)H#P%h=>BBCf2Jv{>mLsr7ban>S{~Ii*YO!O77|!}1W*>rQ9P7u$3_ zh_K$7NQ8!C2{cJfQbiFVW0nP%y$rGGncE>~`Vi7ZPVtZ^1uZy{n)VdJL%q!x zEf3|rX<8xUZ7+*x09M=B%N4Iy076AI-Etg=%DwOisv@7C=)=Ahj+IteDy(AQK<16r zzU|z5g%svtk@x$U-r=Ed^zuRY2OImY0f5Hms#-&_xEJ`K-Jf^Pq{&Qv{_c~-S}Wq? z!7+DAumw^wXpm`v`uFIC2Gd4U*iFeZey-{l(wT2>7LOS$A^NJH3K=A7w_i+Ge~8!1 z$JjW*_6IOBZT6i(I=RT#D>}Q6hg*^YoN}yY%98_g5l2d8)gNpWUU?x))tH!To~Ivk z?7cSL7UX@joN%2Tx+?8{QF(7vIO;-$2bKUfvtcl<89I1L_2CU%pRSONFS-s^n$HQr zXH)QcCR7ZF@_ClcsC0uk0)M=tg$HrhNeW%)~(Go$vz=OHF+&o zYFSuFfbEuy`+^?iX;psw9;C_Z=^w(!pi;oBZzV{Nh>650qkUav-#bEjgw`HdeV56n zy&JWq^HxeTHbb#W(4H~wO0O&^&Vx6HXq?>KIu;Hj`t?;taX=6kV;ix#9 z5)|JAxN8Q}@V6mX#sn*_yMVE1(fU5W*S3M?^s*`g#ws;f$EuuR?-LPvk$Jrj7z?(C zY_5n!gW^BVyvo^diq~HQ6^YswC|E!)#Q3%RmVo0OyM0!@kqM>RK*NaF%q81gI{7Cz zb8^i`BUjbH*#THTd3p zMpx<2N4_CaXjKiTQqf^W51tOfHPh!qv`3Z~hkuLl{TP#-bR7yU+7mC20>_&NL%u z(90{{d)F;h>hHGYJvXS98_;=1rT#p#5fjiaT~CyJpPz4@U{jhTw%9_^Kt0!*-~(NH zeK;CA+RskFdH7|V6u6EopCO%riG#TJJN0e)Z>kq~If!e7tUy70QX7E+LI#&1nROxG z128R=AGRSa4H`uXMaofsPDCG8T(7-)8*ohwq@7-i|CI1RTq{vefh9% zwWjzpn?v&&2{TBS?K=Ww84r8yYeQV@Kq1Ycr-lP16;T`|oDVrrjpNbo3M?E3D_Zvy zsZ_DFcJn(p7Kt{0aXEm|E|hL^eF*bpn8!FW(KiPfkn_MHMN_ZZZzA$YGIHIiDzPO{ zAs8m?7cdZGAe>ejS)*?1w}>Tkw?su}*?E(M^Qrc9@0#rF`ANs4;eG*8G0;FrkV?P+|9&SQeEEh_yQMj2YvzH~kH2aKIzvzSo=??Qe;mZFO~O0cgmzus>y zW}L+YXW)O-PobnF{bwr}7zbr?AR(5UjsO3+*a3+-2Vt-8D`R}yQo zKKI@;DsOE7bUA-*{k1z2{AE-FUP%&^>SenN2vzI@H}t z5u9rQWMeLRB5VfesU|C@W&hxZ`^DWxv(N9EnImIj#+M#a{5<%Fid0U^Cw2wiJFkNN zX;nGY!R?Rv^@~4imcLA{`%1kS#Gp(Zlqi!*bb(;J#5HSO_3@h*3-lycTBP@dOvz4A z8wP798tq&cQePnE)wIv z<+Lsb*dB-=8cZxuKW=~Anqy>D^q&?E?~Had`mL#VIQ2a(IVOMjD{Cfb**H0@H>g0r zWNS|4p7fz*U%ku*D6}e51%M%}kl~Q4R5TQ5)L;06aLQ5*Xi_Y&T(}gdKex<~+shK0 zP7|5VnNdJ?HVA}`pIr`mq7^FN8bJfY$D9}{Dhb8_#Rz-wm(PbBdQL!V{xwMGnfp=h zY#`P;ShddtaSLUgs0JMsDn8TuX#_t#Uxd-|G%3t~05M{EwOf%rTf+LKq2#VC!A5MR z_U&YKy&>iKjrQ~ze!SHFBL=V4Yy!EPH8~<9TmMDIVkzWiU9__3<#9XLDOh!%GU3;n zs~#c|H^1;0ph!kJ^;eN0-{GfKWY?Xm!hF4$HhdSw^!x~{Yk;(Jv*`Q@atr)$vbi3T zaSIxHim@)Q$LPJ&IF{;TrYVu7ZD^0ZOA<~<45VQY*ZlbO^Pl$CZM zd6RkSb&y$hy@zk0@1)2mq|a`R741~Cef&6LF+&u9>lv2IcvNB}Ge+z0D5oV4qn3;WHzA|yT-m^t%4p%(~-bG!AOmWFXO*SPwTF)pEU+IYB{dzlg4JA6X zqk5#*c$nSpD4)c1={uO`HCAK4GFIKuhN%I(*H+IGVXyp!aMfKAV z;6BpXYAs@51qeqFB~Ol*rKI|$GV&H0JlUPS1*ZWjx8WuQ(oG3yI<3LimYvFWD+CzffgF09&#u%Ji*i{t31EUg`Zoun4E-sM^2 zQahVAmF=$rr8b3%bKe$jxH|rR%lvVcg6r=#%Q+>NVcteNMt4&VCxL-=@R=&?PTo-4 zmnyno9=yQ)Rc|!bZ5^gv>`Vw8s%SRC-;+^$R_u8D4?Et$tr{bP^^=UF8!3zX_Jfpd z!J?IIZuu*Z&llc%iQ={yvTmaA#SOVNacdSd^NeUg^Y1*6L0(F%9tzd~cUWwv{s>$+ z6CX!=6UKWLO9sTJTflQFkaiw8{FIb~^oG>JKApP-L0qqIw_$Z8w*=)Y{1*K?U1H$V zE@IN2$7nKG(wxy6VK-nTOVKf`>UXRxjcky0Uv5ij8Sp@&S2!*)il(mew(j40zSS3n zUDof-`HZkCE-#QKtu&Bm2(to~I1vlvK|3+rnZ0;N{%>xeuc+}*~K~Q+Hv<%V2 z7^Hb&R(oD&>nI4D>ZUyB;@YWuCvS>gS^)BJyKB&3C%Aj8*tJsom9M&Q@3PBU&349z z&k%(|jC2vTe_*a6n$&UC)VlgBFG>v>^r|UgWoTt>qaKzKFvLxj= ztHWI7Jw=Q(>k-eW&7$4;!R0MtjIi!b`0~sbdc+m+BDWi{YB7A4)3HqS$IG=rg)034 z>B1D8Imb^`*@G5RqPZ2W0c!-rIdy_No(%?#%e`P#JxmqimSt||KTT+~we`|*F&6&R z8&utA6{y$who5mHCk9R+%6++7uW%{Fe9%|;Zx+13bzLi37^n908b;k&EcLVNnRv;x zdFX+7>O%Jao{EY%&!FqO<`A{y`ZcVovI?-k-e&zAMYF_W9U90Z!JKULCyZb=Mq2J8 zo%S+EnkL<1zwo~5P%|Tg#0BR_d`gl{U(|P_T9Yisa!2?irq{o(@4Qzw+)hnaLEkXS zvqV&;aj<}z4k9s}$h5JyUSP@}r4|aVsyqee`udaOeYC(Z^gZ3im8(H35}QL;B8Ey~MJGa(6lwZ%oQfTla`pU0P? z2Ubao!uX=RK5Ofa6B0%>AnPPEzW&C?F6R!F>dHLg{Jd!>%ss zRfzvekYW(qb5i4!=vwyGz2SPI5rL{p73y?t1VnZAMSoyvoUBI-k%=_3bhW>-wZ9Z4 z5=RG5EOp#_2rut(ALyJ$#b~3RePLjks3%kA^lHD}$-M!_6_Lv7w%H9`?}fsEqiaHd zD^#XwNQ)o|4gu?4!66{gS9@((G9D0<7qPUP8V09{`|bJA$muAwOj?O)v{_n~5NtL{ zd|W1IW5-^zZ0%HwPo+ia`(tHuGx|zXe zLPHAzbrY|9yvPta{t{+ReUZ1eMGh2FjDXLQtW)G=1BI)*lt7AV;+ z+53u$*Jnj`gXCRHDBspeWd#jK86M5S>)!h8ur(r$7UG+Vz-5 zJn*CB9b-UiP?XF>1WD$j+#~V!b<7QNo8$$U+N=7?u{K=>&Lt8iprr^>ig_|Ia|R|W zQ>E+iRwA=>_K6>itUR50*R+X#-Dg!n53w((sWCwWTSQMMDV|?bYZNYiyOq33p;TLF z`k@*s1DNwa!`XE%=a>x-$<2B7mnuD7gf1Ce9BS^2zA`KVQ7j_K9>}K!D^Z2mdxdi_No7+OU`K*%>(>sI<-WgW&bB8J29x06{@YIC9tJv?<7MGbT8HlwP~e!%m4h4)5kI9bSBa z9Gv&SKhPmYcCi(q)K)I4hW6@4_=GikMK+QH?6&Y!9 zzHbaM#xxF^OH?`G=i89^>n@>r2Tkyc-D#G5P!?y2vJMO7nFo7RcuPNzjtkBkS-PK7 zy7&uIvl9gTD7MafNgthk=Zw8M#ZK+Xdy}}bNDp_W%pNwHfyiqyW1qc{uECjpy?EEI zY6K(Jn;GNRXaK_em>qeBefOCtRIi~X)yQmtdfLP==Gahk7sQ;^pQxjo!E(DTqWreI zF^UJ`9>}QcpHm+D+=-E})kS@!JhIZLirv}QTNyO7VBB&7-j0zcyy_dW>rx+t#>tf5 z{tY8i8ir_pDL5m95k-LA ziD$sze9s*67ZTjlj6EK8#5=gXdc_#?)MN6jwGqc8|LH65rGk0+$G%p?Y2glkpXJY> zDP!-=8H{h4vBaV(J^5C8P@&eX=^7eKPG3R^0*z$r43*&IozooUKvbk2S%%z#o00|_ zRZ`Os%t(-F_G}8U4t@2JjY0|%%(+fa2;WVK{00w`nT@jIU3$Hhehpz%Z?d4Opi^eH zyK%z+U0@HApfR@R3BFYk5~_4j2lSnRjh|1PYTrK;^BOhGiOK6=8gN61czbk`d4YG9 z=(G9X`9cs@%7d%Ylj%q`DAdc7wEyQOx!HuQ(P$;@FvXjiVCLzSgY``?X6o}IHCtp< z@rHS-r9lrT>Mr>e`qk+@TUVtHR@!}mTiQ1PY)ro@Tv--I*Ti&O6JC2iDT^Y{t9=MA z8lhUf%}h?23_%7(hRe|WaR^vFoGjk8Xq;GCU}gGlzgY(NgA|~Ak0JyNnQ1pL2J^x zUK}hZgAT1>6zwI}Ie`wUYv<%^GAr6K8-H=-hZctZ1jsc1jSL5HqIZV4Hm#8kqJJhG zzTPT6lpc^V(y|&nGN6S1AA0V9e^Jl<-@)(tSI&8=Q-?}Ai2O-9^c(q$Yd-1I#Rt2& zcZj6JaOKcL%|E~YT5bF6=fl6aXp5DK7C$fd|5Rkm1UXK1UYr=sU$m29JXe;L{Gdx0 z4rlOxpcWQ(2)Ajrywx}NIW6J=bNH2aN>ZvhPZgKGTwFjacB-QFvuHh~(K%_^siqbQ zK&CXcXkV6E^pi?=hH^xk1$H(FqrwGFWC5gn-)Z!7Ep3y<@*y1N`c;oB391@h+3S^Q zEq{dm6C>#)q`5&_VVDyMJID%k8F!k2@{do4b7GVD{^%9Tsoos_tV0fq*2`dz(4JOQ zRACk<;a}Wj&kSv_JF|A!8bM{58T5zKwrdmfQz$t;lSi}W5jQF;9|D+ipiVEJ7HOx~ zy+U)B3~w|2aW$k8wt|AnG(%zr8B`LA+^$ zPD`M!799-0^AJUb$3h-29o$(bHC9%KI#>5^o!*YJ=3^*QKd%0Mc!V1? zt^fN+?Q_QTgbZnEi3yf_qEOi(^9xsVe@1xrzBs&DH z_huA*?u^#(R5&*4@Oz7Lb0U%_Ptaf3y7DK!U9+|7JP{A(*ETNu=42?QRKhK=s{3_0 zUqlSny~7hG8<^4S{VA=6Q9~sN0>=izb92XPXQmSt&Fsb&V~9?wtl~9B+CWmjXPZh- zfhJPZXt!}f-g&XxsBgRG*6jY1H!M~D@8eA1y%E6=$&_rMQTL_GpvUpDq?Me#TK$%M zp6UtS;aprUHe~r3L8{$oxy3Y1oPRkb&8io)D_vwb7@!Mok)N-?RoJ-Gm0ecUNf<@U z;xoV2N#?G-8Q?-D5jl3Vnof)TxrT^%rk7sW3+7d7S5$mH<|S)wv;4YVQNi%l=4r*# ziPDNF1=vcxdAKChO80K2Y#D9NRo^rnn5VAKG3wqi@-KFTsQ7xa(>~bq)?nYH7rV+M zA1EO7SFBuf`a;x$9Quwof`WZD>0MML9;jSF>=0~`ZufNSWZnUbCCrkg%z8Ri3U77_(=anc2u4(< zYR96Aw}?ho6ZROK#Hs{otUm-YsG7!?k-~3d&IznnaW8MH7j3cqpg>7$>z&wsHz@C0 z7k{mfkvY)2Ew5EupG~x>=*!sjMvG-nbx3wEPo~5Sdw3O`*0p!f$cX5CG!<4cIYT5! z>uuCNOYtmqYww-0z=d=`EfBVaqC#3XJxHTVpO;cJ7Xlt5b-B0?nYGS ziODTyi9d7rMiBb_;w_y2OM$zo3Hn1i2+W!Cugk_1$6(`5a- zXwNPsob6Un0$xK;&FLGFdsG!`f*Ek6T~Rp=NI=@3o#wdJSnhv@xb;}5df;4^ zg^|SKHur$eX3374R2+;|olSQgUYm>cHWpa;i))y9A&v|g_qH2oD5pScF2f7_R6}uAjG7R3Hog!OOa{4}b{vJ8qIbB_Mdsf-UgH~E6 zU0BdL@oBDoWK@GeI!`p!UD$9Pw&}osAt4a8;m}CVPOQ#HDcVImpVW!++KR=3CHnhp zzj6Fs4*b>zBX9I(RWiIg)ocg1meBh0*Nyfa19)afY@Xh9j`fc>(b$BaJXccogUe&V zBKLDYYGO)U{4K8EfPU*WxE;9~FGZ95wiN}gQtmP|X6o{xT^T;_5Myp>{`SmS>8k@G_9VME8q`mydw7sbjdi? zj$@Vy)T_wrfAO|AEw8O1$Dwf8gDe2?0XO(Y*|fJhsRsf*pC{c;I5K2}EEAbZ{moU< z*81=@(U#SVyIt25Mpvo(@}YKpXqwcPW3by!wrrG#$Hx7~ULC>`t7C;{3iG8 z2+IW)4ShkY7uAGg6yJ8qYyxYIHXjVt(XTHa+{sJ335Q1`?c?b=hYR{^0n+w~*7nYo zcmI@)m@mQ~)J-hMzM0Xv64K|JA#%hBKaecWIT9^7`d)#Gin~axygxZzf4j|{V%uHn zOieaOKzL~Ro%|t!6DDvFF*ff~Z)2@{36wzaqg_X}-zomJa8F#agLSKdcui8&MbWut z)yFF;wl`V?Vw8%{8D->`Zrx)@O>4B!ocI$gObRGyfmYpu>TTu33}WRPQ}2vLG2EisT-* zl%GuCJmQd<&KM8BI$%o6d8F*HexG9WFHDx(E!E9bk|8VX?x~F#H6FtVE`4{EQT}`1 z{l3A-|f8 zi_+#>Q!3kyv+VW8M0y}+**^#Vl&=q0IC0Jy|I4@Eu^LSV7oNt84VU0!fn@atKzqgp{bQ1d^#_e*+>&;Txk?)-M!NDQxb` zRs+OiPpF!X4av6`Zd&V>Qq63dhWUzEe}<3BMr0e_PC;Zvf^Q2*2TGAb{qJdu$gGZm zHU^#qe1}8&NM67>-kv#sVSR4 z#unxG1v*>RDw4x1rLd3r2VP6<^l?Olbln&gi!M9e=&umocdi2`&T;KZ0)-nR_J@m| zD}LMd;NA>UOoo>3Bw}a#W$!r&Ttq;+nGN#!K0DKliBo){5h~I-TRuMUD&-ryOB4G` z9ihuhquQIg6}{Wnz}p|)DP!$oeMNFVJ}Q5;I{$L?u90;5BME-E*%w@ur%Wkjp9X%) z^y~pTh}+$vvCytV?p8=ZR`kNarlk+Wnkw9j9d$%*Hd%dn6p2FE* ztJY;3WU77Hu=7oXCmPa)&WLF;3|Bo=s-K0dUFQ9Z%ir{OX@m-Q*QM2f@6hO5G_Q2f zN)S1)n+dE%jke{PB?9b!d101WC>%|cuW*Fmi^i)?=hXbUumH#)p|gjL@{l~u2n0f; zQ)?5@%4@1moW=sL=8L(0DyzDb|0(gtFGz8zKAS$IEZDlVe+ao>j$Ijzxh-UlC4to> zdVvzd?i>~|z2|mDV({^nE6pylh@ZsH_w@c75zzuX_pg4HS0p^FAzXl)x_f8&@_l$T zci!3)l$N$U1%To;G_B0%q*T<^s>NkIk)}RwJcuH=qhHtMegFoF3uwuCstyL-lgQF> z5$k8Tw8@Lgs?GFM&?IXi=SWTREi5KH{ZS0B9=|1wd&Ds&C+67;)vWmAmu$Tfu&;5$ zAmv^!-_qAfDrp%###kS>!5Mt509x*lkyz>zmpV!uU8Gtq0!fSfKdG0;{_MEcNokP# z+t)22vciO&Qp=r31k=Loz*?Qqqx~nqzc}{ZopMHF|YH?3AKn5fbTaey8 zlxG`EG8-`+?H)Bs)y=6%HOZ`!C`#y|b#!}YEX8Y#24@DMAA`*%Ltj=KXOE980?J?I z?fUe`B$CB;%I`jT)O+bIb2~$yuJ5_{R_LqT6NSDn$CH%B&v0D2G}-`WeTil<`Feec zy|`dz6uz8_o$rWKN+X+9rrjEuEbbIEN>NOfH@AXD)yDQ3lUs%leAZ@?UKeXC+KA@> zoRj#ou6org^PG)Bi3~@fyvr+_Oe@EM=g{a&?s6SkuF-QB2CdApguSq|=jOkadZbR* zfWFU#A%O+V1d3UTn|#9s3IyhV>oX%Og0c;O$fOG~UZ+7l!fs_Rc1a_631AJqd%v!K87OaQcH_m{PDQ?)^FC;1#%4* zCmrt)PW=w^e83m&FsH#uPDoSiab0W|KhgcGoize*RFJ!1@iX;AS$TCeot`lhRrnM=nfM6ntkC{aztE_( z7<%%tj=#=Rqp>_}Q2YQqXdtM-THDfc*v`_&$!N!f-G7f6u-|RCPu4(g?U;d=vJo}y zYMBBD;<i)fo|{Lt%kl?wN9NF{86Vp-qF5SWjQwB6l3W+pakn@7D%~vlwwlUvtmGKLnH)Bmo)Aj)Gm_d4iCaXB#~`x-h^SN+Yby7L%$`B;M zXs%@}WHwgNLEuWesY5I`Yi9Ed=(M$dVP@5`3;=eervXlM5obF}!#PnbmX-AIV$?7g zgjdfUb&`ZIH$5vzd}DV18*%Ry)@0s=d(S)XI0|;8qgWt7sDkw7D-2+Q36KVaHj0!4 z>Ak#g2?dnB{y zcvzNv3P0bt+Zkp4MWjO|J!^cbf3v{6-;QkLjPYC>>g+Di(qHbwVP}35G^YIXOD?KO z7!@@-s#_`25}iGTIl78}qZJz@m;^H3X=P8PIH+T9=!luDMb!*3>e*{d;J!VDldY2Hxs<{O7bhpfZ=NGdgOsH1XVn{0!=uiT^`3R zhH~z&OV4Q1xHVaBEnf^OEls~EL5wmZ=PsR@{9Jt^@?R>9`)LEHs3+cyr;QKHv(-6w zRX%o(JUjh&Mh{q9y&N4PveMw)E1-I~jCjL&u^s>`OL;G|wnC4gPbz*$RGdW6;KXrE6G)EU~+KNHs zt4ak-F|B>rGuof`?LFeU_QHJvLw_67_$}I2k|=*GST`~)ETc0;j}xXDHt+pnQbU5B zHm_!43t~Xs@ens$RGV^JE^3T8KH(-o4o$tynb)6`7l6Wcjaz6WbM2A!L4}{-A0x+3 zlMdmB-XdxE5K`;NVduVmF!|@ulUaxFa$oTBDVu0Uj7$;W_jW5SW8&UqOm1&#Jj{>vp%N^)1 zVPQ6y@T4asd$g~9Ysw?6U%g;$%z(On zweMiS|0i#*ZJgSvs996Lwb1slR`4KN@d`h%QmMYt$l2L+z2%GTz>mp~Cx)kg=lkqd z3@^^vS7ER-_x{_Yd;@%)zNUl>w@o!QPVz+dz_QJQ6wa&XXmP~`3gk?N4i{7(vrKcU zGdQ(GkP)y0gvd9oj@~a7t+8NER0{?7bt?n;M>*#Q(v<@5>?KPj$h3}d1G4QM0?gtu z6YUe{NVdoiU+ps|Qq`Xk|MiL}@$vU7_3B69U%Ij3A*C#2U>o~hKwT5I)$5{q%YGrp zeYox8h>=djY{W2K{yNBb7Ii5CRMuN;&yiTHC4*WF9&B&Q9lbvSY$Lg2X>W#Rhwn9R zi^!aDHSU>x4PQU%6iYXzR(>R_{h6|&C$~XuZi+9$JV@#}v**(A*;ao(-Q_W34d~QS zubgj6V9sB!f5NY+(`1}75Q2HxcWhkwk@rZNE#mn7B~v5MVVZh_g(?`a#VaNPReug# z&pI4CrICM3&afn|Ej#JA!8r&z5q#{m^zh}ACvg9H^ITsGHFq>?_*f314=Waw)t-8l zzJoY!Az89Kf?S*+jaJE~ZN}cj{PzdjD4IpVHh^lsWKjr|yeEIp9;BwAKzBV(Cg$~) ztE{y>?>g@QalgmDPZq`Urrt_OIL`Ve=Tn=u?|d}51Mpb?Em;svsxv(Lb3)-~X1MGN z^{qGUGXHXIa3cU`EpX5nmp@xZC%sKRjmY%9Cs6L1z=ZGxe3q9{O<>riFOy21Y%FOn zvJ8nA)){Fb`1u7naShmY)n@L4UFudqXJadEv(%<|{Nt+p^z*rs2YCS#4Z&>HVQP)T zYe72iiv4F*(*$r`Sl^#px1z&kJ}&Nzl&lobTOl@+&=)!psW{JJmqvrT04J}hh^g4l z5oi!sUjNVK;lTP3upUvy-VPQ4yeo{~Y1e1%mT`VCjgR&y^4yDVk%@GhqS1t)Zypsf zKfYK#@uAx3j7y*NI%n{8BfkP8VUCL(MuYsk%{<<4I#oZC4;&r}bKT+x4aIug)sj{k zD{qFX6Dai49%%gq#+o`Wp^6gQLUrGvTwuzTfg=cI5rer1KHxIO$B@}mUpfGu++rPH z2ZBR6s_I}V#I@nF5vWUKtHC$Z#=gWl`-0VV-bx%~{qJTz7s&oCNQ&ss+2$g*x@@&Yta@`8g%$u)@sl(v6l|d6gb2daH#%ZW z0)Qq~+Pdy57ie=+vwiDS6a`-$olu>9+j!i=cmRdn;z$SAthW~5cp;DxXCbtk)U zi%u{MuY@_(4zb0!YTGF@j=h^ivEF~Vnc`{4yIRFpAwdhBhQE%srVY;>1w5B}w5+#m z_4{aAc3^C>MLlUS&BLlap6Mh#x^e{1YIDp$x5FS5H^#yR>qqw`KoLhsSOOj`E6)EzD8+s_Eo*X3PBJ zhs1^p3{ON`^jcAjl{tYbw+cgAjHpar6lu09-#nG@pH^+!W~6%$ZI-k)@TIP_);H9i zn^=)H1vGgmzy3H?$h9%V&90|lN!OvY>A&AOHIG4>4ep3n@A0w2gdZJwG8u1e)RqUu zx+U^&H^2|qW%UEv8j*_8McY6q?nLU#Ll(mxl`rwM>wiPn&VO%7-t1 z23%W4Cw?7akJP3`NT=Pc2$0@#>n^doug&)Uz+U4)oAvrn^FOQ@?SjIe%s=jw=s2I* zBym*Zd>*YnJv86oqmu;BQ9bLKExM$l&#tv_?yB174_v2Agt65+vPBt|#p}f-0{iD8 zNs3j)iieSD^W?M8ETQZ$Nh5<)6I97W|CHT6{z%hYFTvmrR9Qe939kI9bI3T%6S-8yWX6-ZM}smGNu7&{q;<37`Fp`;`_pzW zn|gPXV`~(S9*iPQOoU&Pg8icV`hx-@S~zX-{;<|Mu4pqBys(%+I@$*`uo(vH^rw>F zvbQosOtqU^1g$1P%C**U6I~{|j8Kno#kU_4v7!g-`;E zRCwL6w>|pgh~n2+N6hDiQN?0m(kd)l$PzBYLzqyG0#p(UZyaLw_jj@)+>J?IOK!6A$2g(1dMD z$$>BAyBev&YOjUu3uXE|bIzy-vUVZJ_Ja=;cOR%TEZaur;#Ju$!u20^xv8ekPFcj| zF(mb*SwWb&KCA5gMj}RKQN+h+%=uhx&78p=+4R5Nnam{cxw5ZX z>Iv@kjk_vOMxp(v7uuQ-X#AX--aA zjIS^1prTf(6AIxoP}=!6{Tub*h&%^k1?oFhJ2+-1_`=Wg+fj^?@d?`AzKl#|a&*PS z#HwjUs$|_hTZR~VX@i9Qkt%F0{I$pDbk?TdY5uRr^NF+B-b-&qUrbY5@u>TwX~g8z zA!P~3XTuOO8!LzR*dTrg<-7kl?;(x_v_{{E2u4G{ws2HcC10)Z=nyAb!`BF3=5X0w)E4$;*RUSG17MUsQi$?kvFhP z>HVzczbw#S6WO;%UQL-H-(&0U&sgeuBTaUe<)G><$6$MnC36&lcak{bkN~g+8LX*& z$QS|0!yHIa^Jg=Osw$L1)c9gp()%N`rlxc^z5qTuCBVpW$EcHt0kPf--M%(KA534NVLj*ltl`=n|}Rzt9fXlouqkufj+UL+!>U@LVOrmanL$CQQtNS@P4 ziOfa^o`ru%&F>sb=U(RYpPsB1*y!thoch==>^misE&2Sg6e2I{p}g}m7pHX;cIST4 zP#2w%6GAMMW))s*w7X0x$?W& zLU~74kDM}P9r_{v_Cc>Gj-`wC*+6aADT2~)e<9{($7Z^s+F>Cl_DkUT2izxIEjvg6 zrq}&-t<2d|rdc?yB zVR|&msSK__EyN^6_lr4vG;2CA7=*hzcXgtXS53+=Q}9X{hYHTuQtD4lVcBvMuNpk? z@bCI6d3EKcM6=SI1{>S=w&223XcKP6p^c~d$f=>e24TPafG*=?AMBUl69XyWVTb-! zk+|>C4nHeIh<3@_#z>!w5Vc!qxYYruZmltsJOpu(Dii1Xhp7~dYXX9j#)2WvzQ|1^1pL6s~^JeXXuGLcwa+cB|; zzkM&`SFx1a_g|#>e1x?$j(BG?aqP&x|fnIQG2 zTsj8M9CgPtVW4Y-=!4R0DT1GwSM9&CxcRuS#we@xs+UJ!Vt7CZ&a%47 z!+kZbxvDR))WvID;3o2RXBrIaZ&uSgn_>OIdoMR&KwlhOvs$w?N?w=V^Yuju0V5*4 zt8y2*W_1nJO`y~Lh%`m7wJpzHJqmEwco+$oK_&2D)Q!>s1K`BuUZ5k>o~YKA^m>**~N#d(FVsdrlV}i8Q7a=zefb0i4zT{CkbnlEChhV-n?x_HmjN^m} zz`0|}&1X;Ah&R4(Y!9QG5)0eZiJ^LdJxr0)Qr6gn>00O1cTx>%3Up%WB&~Pul-hml zIJ>puM2EO)7}=j=sTt6hU3;C-VWW;Bg-ffjvON&%l};{vxJj$_@N@C--*~cU_(X*f z8yhaWD}Ubb-KY>b(W6BSEbEXkN5y} zjeD5$ta1>_ktEs@ji62s$!uUZIBf5Xl+w2K%03rQrh_^=5jDiii9p+sOhRLQX}v>t z#M6JrkY=aWpLXQME00=EmBx4;{qqa_w!w?ex;>j#lGOWvD1ib-2DPl1JN!3q6-BZh zG;ANXPqitW&i0=Rg)#laBLWts8uE)5wbw!&wwRsLrG){rcgw#Le!ff^#U}==ztBK10ZctjGaV&;y7|qfS-8_XUql6hsU27 zt0d%Kj$4#-=3pSf6$4-_tR z+6(*9Wmq1I=>|XPmgg@lL7@@f$s}&j8N*a$M$KX>I#Mz=5AIYXueX@zxlmY5f5!*N zcI+oq;`E3j8i?OhNr8(SCYMc}Do3lPv4sbB#_TWerKeR)Z(rNV9q=;kcJ$jJN5%M7 z3sj{^>HA7UEVn!-s_5v=^I71 zflO2545^E#3Tfg66x#AARaMGV4~K*YnvzLteU;y6t8o>t^Mj6YmYxG>*V>x+gZ%1PD*;-{(7f3 z%Q|-l<>iuvIT&Rco8l1-1n(va11{Ru;Ba8A)uVT>x0x1|$U0*ax2cXY#F&v%*!Xtk z-(Hf_(=&$IT21~x*rMa_VpG1-DE6KlMDjWIz77qcPE9I=V`9$aEm>ni@SVyvvCpq{ zzd=c`ZDtw1Q|5ONv`H!ySrwD)r0eT}lf+!` z#uj=LgQ$%;C>JuOd|EX-y8NNly|1AcT*_^)Q5RFyiQC9|Krp61VJ9i8hL2P>Sfli^(i0>BV>b%gA-riw`ngz9&KShpq=s5dWy7gk! zmPdJFlj);suNOD(zn^^whlc36=$*!f&<9!!At$gdR zMm8Za+JIev?qqY8i)vn(;~uO7>AszN`J;X&1pg_=!dqm@^xh6>*g z6xf{-%HwJ{KJu?=yzCa50aFf$Ou6!Dl8{e^O&*Oa zO7OS`UMH}>#-FxbUVBww#>!R~E3c@W&v4Pw)>P(`5V?2U|AXtldpFka!aM7!e;w;d zH?AMd=ix#gmh;DMzz|9%`~;>6ubN?|{(&};joUBk7p0AgJU%v^-1qbJ`OE&xyPih_ z*lhx-hBCpxJ~8e+gD&{}+j#7@OlOqgsG(^NX}0fB;^;^au<-g1eoA!QgQ&5np3@_p zKhHn*d!7>g`ePH|?Sl_DDmQ8wP_S{jM;PK^y8+be(oJj?G~s7m>Ws3I+OCO}qX^d0 zGUCf@459JyOtb_g@=*leS<|g1igW{>6|2I{63R%gS|8YWe#ADmJ}nhRUGl~Q0%(|% z_w?s}Jj%B`xtJx#MYzy%E`-MHPGu?}Ip^&b6^2Kb$oNPMjGT#7{hBsk49*w-$}}al zX?iPy5eszf*iohwSR$)Ml+*=d8ixa*lArtXymHDOBG!X2U|60|n3?4*j%TX1n-7+5 zdv(>wbR7Ki%i{t$Ztmh-`@jaWs@^5nrGl+^TU%>`wC>c|I6MdRZaD98ZW?|_2Gz*L zllQ_p%95K?<6azUextC2f`3PLeooKpyL5d*FvYDc zQpR)YqBZY~+Lv~pEqE9^XY)2lTRh*$D4^Ue@)H04)@~=CAW>(qJo~w{VMiTa+He;} z8-aSFgbIA{GQ3Fj#Hwfz#Rc^q2MI2g=sldP=hPF9vMenh<7+r@bkAHXIr0a9W zE3bG*mN@KXB5=m!yQg!CVx#X{L&UCQYXym;fQg0RjEGDZ9)a20!hZLO#vy5xmdtN< zkO{3~sy#4>s}ZeudL%H7^)=QamT{6TV{tRXFbaPF)pJ_FWrpHWL5$QRtpJ%LVEr(6 zwMEsM^Kj)z?MvpW!Yafz-b`1!AKVRZXtLLW9e0^)thd)P@AN+QE@N)Z;f(4MU9C~? zEh=D&4&>L>Z|xwJWY)dS`aYI6yt#KX8qB`Uuq%+^j<^$x(u?9jJf}bt^__evm?Lcj z$AkuUAwtmqTl3KG)$CWVUHY?RCL`Dp!Z; zVR|wK79B6-KK9bZ4LuOPYY?kdJcC?!HGX4%Qe5PrU$K`$(~WzBj95MWV3D4=oZrIA zZ@|aUvO9f${8sp=9;fRxVE0mx*Sl1LxUx-`~WxpAcbZQJ|Py64T4B1#vz zl^wbleC?#{y2Fbx#}#;2v3*{XKUF~X=zg)=>~z(?Mn$gITcN*Kzjz|0Ooijs?&1n{ z4zvMWM942<`ny6N5}m249=KAy2+MtHXb+o0wjO)%}&XZdixC;E;Pb6-aw7MfFFEgx%|E$zts( zBM`*RWUv8MLBC{4JS?lM>w3~)fjD~LB2RUV-+)IdnZ8DFmPpkkO}cbpjbmUp4n{#j z1KL-l5({6(c<+_gtMOv;z^%NGmTW052elUtDg|NK6U&C7XwdIfp~8XT$&NrhkB(D% z?)s!(R|Er>cKS6&7+|N&NG$vf2#$i-U$AAnLe~#&`e2bNlrk#>hKFaqUucLFoo_Zc z8cZ}9g;LvewA8{4?i0T6Rc9%$n6#gJYB4naR1h`l+E&fh*NR*9czEibRT7M>y;ESCb=h+OEB!DM}jJ(WaqHIU81`@4QM2jdEA6Jz{a*Nv)~XX)qMb?WTws2^(^6Gzr>9uK-tZvDQVfTsuDyiK!Ypz?%H@RDd z3_;46F>Gu0(Ly-maeId#9MnDKm~XEoe2+_E^yb8XP#uZbn@#)6I*B5}>3hmW7^!)I z;DL7<6+P?{2(|zG!s$xY`fEgS!tv1&V4u_%tn4T@?P2)^GuDVzpR6`43QpLXkUYDG zQH;qlf))9>;}$V+EI9aACbyXU-kq9Gh;2Z-_l}r|CU0sbd2ym(qo@UzCz+vXRVoOC z{oqKsHtYbs1WsXW8~73t8?gdDpHLh2GvHfx`8U9qZ=7+h2#u5chTH>JK4*0b+S~E& zTx`fRAax4oN}F@N9|+#~p`qZziFnrJprC4As0HFJJ#=~$64rcIq=pmjRdX;m({uHp z>{vvWe>*H?hz8rUoX8CdikN>_E1=q<(r57)5vOxw&IUI;KA zI4LOeYDN(}?)a*T+1|()aVSVv=Evp*3wGKsZc`t&U8DHO)j@AORYH{>rq|&gg$bPq zI%>Nh8_Zb@5Pb0{|I=p9kLXOUnEnl)(&ac}nP>Cf{_~07AG@CX{m=g3$WR5jVm{mN zQD3xz+^F}dcSFv~3(UJK-t;Y4y7^rBLR)MGUCsZyJJlS35a1s{B~lh>f_ec`$?9@Y zXcoYi3Q!MW$+74FIoo0s0eQOzd?N*IuF;XqO-X*x(A;dlI%W7H=JK8DhrPcyxm2wG z)XN=`lipE2r5#yRFDsv>gaaaU-lOty|vnBJ*B_2{* z2tbYqR&XO93|GNNURa>LqHRV8SZN0;Qz~OU0E57U>*)rBI=@54kU1!z1cG6@ydM?h zv%bZ-tX+mRjQmNm!wEE^>Y55h9lmHR)nk>0cr|ztThY8N-pYVh(A8qJ2l%Y~okvF68qzyhmJJx;{M?8U~%ZBZSgM*;wGQdIf zxebUfj~=SD&y#jz#hzDAF~yCMg3VBbcmIBHoAI>exhvI z#0Gea2jvlCy;im}Yd9Lc?3zSdaoC)DZy#+zR61gMlO z7M&b{Y!%FXdq()Qp^0hUyH8G-?SjN-RDs3Ir(6t40OwIh*Ho zUFN*KdFBgZTPGvJ0&ZPP{&eeNT&hTMP`;4R?&~T!`7KB7j8LQuUrMYCs|~dJbp#2x zXiijT1CzEng=QkoPc$}Rpg3WZ^s$Vz5M5`W zRAgs@Bg3^_Hw>-O**Ehrh$iWys^~0d&)D|sHoJT>2B-5|r*|o~F%NB%9HM#DndxRy zfgTB>Wi0LqR_1;qx(y~;3ij8^q$>Wfx?Q&wUfSLgMW&~F{;UIg_VXR9oACsgkU*7( z^iK08S!)OM<0po5H_92ZfTjq(``T3T0-=Fupo#)n-Uih(W6RrWjncp5{WjWsi?K3& zxvG_ihx2^+wt1)GQqCIC>s{_cz%J|eFL;fMf{U@Og%>e53wE@c;r%jq=9a;9v2i5B z_!ciL>;8yCAcmn*)Jv3WP&I&wB;1O_p^uz0iS*N$qpzkl0Y(Sza@6VX6twm| z9YGx5fL)c#HA_jY2b)&_>wEJ`g?_S~@vcr__Z1zoXnib+Xb|D$vX?u1?or?bU%tCL z0v;V6mPr;mE>=6i7Q+{uLWOvEzVYB7cP6_)W!tcZh9OH;)HcSK)Ws)iiKi^zx`kdINd=WGC42XsaAKL_km!`V{i>K-eI>;%ac$1! zd{`=$GO(hqkGNQ<)xusZvm3V?-$g`cUBHFvaxM!r5C^s_#?)uQ$Y{+WJuKH$-`eKD zgGelSNr&i<8C@1&=-=(b_|2Zs_O-?ntSEcXI z1Zp&>4U6*XAU#e@LmD1GeBN^=7yChUvw6eqhrvshjLx9e6;vh}YPMQkMp=ww+5vAw z{Y-0rA>zL4(&p)2fk)V6SFqQy`mFO;ZqOj*nQbliRf~KuUx%P6OntQ@%nB)pRtaKl@{x##UbTOn!jk)UAqQjC9xXEAon9 zdi0i}<%f!1Mw(uW5qh$1ZN@F@{=6KNqy;oH(!SlJ&g8-z_q|O@mgz?0YNlZk`;IIT z#Z*$jP|vnK1JcIW^g3n|jR$ihuZp3gGv*Ss4t!(cyZ-C;IZ8f_&g8DR&{MMqQj?WH zTJ))f2SMcqEViDpz)XV}Yw;ny)_U{1F zwA9FKL&gD!+t8#THJTl&*%#m+eE;@ZAQ!_m_E_&|h9r7pPNhaYi3Xh@i91X%P0{rO z*Q=esRq1arr_G1Fnpwwtfa=ZJZGQb?U8Z2|Ji1(kS3r=bFV*+6sP}w7`UFn7IN$Fe z2&;$(>xEaYdlY{J>8%Q)YF@d0G?bKj>S}u<^r{Rjgbwl;h~Gap(%VHY4RRnNdcK^pk@;K@4ff0w>|ONMW5p3B0a1+5JPJl5AHR8sJy)P zgZ`<`6&8OwD$wFSLGwe$#kwASXGM1sY8g9?nX+={U)G3N;a5UYLtTiFno253^FHTM z*dvO2tO(Bt(xenqQNy4v68BLwScG-W+Yek<>U*D;HGkai($rAW=ALlNBdsWw`d<53 z7wOV=M9%zea&#di&9yR6y8SfF1ETWSZL+vO)aO{%`kBBDVNSfOYDQFf!{=82I!I?H z7%Lhe=bu2hKgWZ5xhC-@rDMXtc*U6B^V5z*pl!ZQj|%lYZT_+!khhni7g$;saH}_u zqGY1hE4mwgK^_*d2e_D7U21@mb8~IRUV!&uE}*))V0*2or9S-tK9D<=Z{Cw!GvAUs zpyE*18K6;aJA2&7_%l)aHlN6+ir1u@QdJ>?(`Y+^jk!5(riN|YPAeJ|wQM18l_#h6xlyY4gS4D`sJ0w6?FH%kLiS}zfT%WHCzGOQrrlBP8ff>xMMpwIt**MIZ7Z< zsDpmsbCE~`uUI<7HVms9>c9%@4NG}|Yh}CA=mEREP7m>!3GnTT+ew#KE}#2p;bS(1 z8Li8yl?f0Rx$X$n6N9J!cH{h&+Pw7+aNSey-Sev2T#unmX8hCBJ)7O<%`Y`X1Qn>C;Q_4{4wb9|4}E9U(mVK zU=bzJg;VVj#)E=$pP9MBwzI|=ZNah$cFONH_ z)tIxQ7ZW?T0v2;4f7ue<7r#pZ`R=coFf2nyBP@Fb5W)O_Pl?1KFJcZLU$d69Baf+~ zL`gr)H^wui-^>nB-{A8}EbYH$drrFBJs5kY+sIQruqgvwgj`SSc5H5{zFLy=cZx?Lhu$E@G4jFQ4J0P3-9+uG;?!ABe{PT;b?6~~%%a;hGeKP*%ONoiaHvM}s@FUwq`=d8; z&PRk*DL{diNMWZmDhfgK`k(o27XP>TZT~-eM*h86D1aZ?B*KrHgOb14e>h&8Ao?Mm z!ID41?L>Q-mh4}!Hlq%-n+Kk(;;+d?m%NG(9VEX!-)e(zchxblWZ%m8*?Rre)6mh_ zh}nB%u)Ohz?(ARq`s-HbPe_NoRMb7Sa^#RJyz^puizxpB+tX_RIO88E)(K<+!P*A* z)-_b2p;3fxqrhsE3aEAZ0g z9knkknB&sY0s)s@1SMRd1S_H@@F{m;fxFPMY&)cBj=P|t6|+;yYz>Okj-z~a-gD+S zCEf^VoLE5*-#T`9(D_P)@Xy`bm+tY4Kk4t=?U>RTHcM}-X>2z0c8XB?50QYQT#_a! z(@h3|05ND#UYKJYzyt_~K(jDC(_pBR&}n%I8_K?P$pC9esJvye+X~u^2dND2V+UyP z<~gD(n7VAPdSEU{uq0od^>B6``tojgNIRlFC*Od$G_EzrLA~(Aj2T^*3;Z)pEVq5J zSFcKxCIrMNxVAkggTK`g0ouwADHQV4T8Dhwgz1qA-<9~Uss}yLz}DE^a5th2FM+7k za=Ww(mNbmio+DK|ki+b8l)&S%wjUVK>up>6pKKT%P2UXE3@n^s5WTLz8xGtS+|aA) zs$6?f1c;>#v3cilYoCOj!Q{S?%Jn~Z;HYW=QvvNPofCYX9G6mYS-;otcAhLYRHt0nxT3bc!7HC! z8RoLp5aow0i*%Tjw+xtWZ1W!hY%gawqlR$;gsoT}EFeNe(2$#d8P_v;K~mmMh7o&( z$2lx7afeU82fU0}U5zi*W?-a(mT=$cxSeHTw$iO|^WDCX{)_h4Ux$i%%9p&okO08}G+JR~X^}VrG?fB)dNmUmCWD1Y%c$>E<%Yxo z=e2p+2^=}=s*mi%W#~6K@4&l;dC7^T*r)Mj;{h@<&MN)Bxr-fZmX1E$>e^Ztii;KC zk2{85ImgjL}Ys8im3UcOl{<5kWNAd288K0baa-fMiS+|9UijQCYq z9;SU@f-YI9QA?Z%Ycfbu_^FYc_NVLksyz4TY4F+cwJ&`$Ys*?|#VAFXwK+P$l<-it z8!y+~))=gDco+Adi4s*(g;@y1J(kPQD?0`+xKq|HBVYYBwJUTqBUZa!2e_GK5(-ps za`#@RJ3X^GJ@WRPU37A|q!Snk*KPM6!0(AwW_S*chxg4Pz89&qOuN(`5+p?`c$&x) zL}8eK8Jh=H`&Wc=U|j)J=cQNP%hCgTglOM{m{)WuwbeyW8-0V*fBuKKIFcpw8?NL; z=Kz1h26BI|#Y}`%zNi6mpY}#Rw|e*;1pqJN)6GgIeN65y(%3N$r%j1!13-pCSEM_c z;wKl@X9J!RH2gd5o|N zq+KiX92{+0YN-JdvgHv6YRKQ>^50mx`wy&MsF6_KHNAV&XYd^^e6M-X!^5j=*J7>w zHGzPDWk3TNK#x$oyo8_@%(x5b9-Um zyhfJQb@RA%IX*+SiEKb39Epiy+JZv}W$-8_uy-fgL>*69lAJftj=>hGnqmn; zDlCgem7A7$s`W=1d?AIxV)OOpmi?Llxf{OP~$c&tjdw5mH?{S)nu4A^Q)*TCg^kFB!ig0z)!~~u# zA07n5v(}4jgJ40lC%7;wEE7*yMWurA#EN-r!BB-Kf(`(rFMwb!U}9-$>CPWtk}t)a z5$Wtt38J{HZ&>??Ttm~lym3F!o%>IU`J6-BOYgiD5mk1QpA~H+9z?<4FEe*-=|X6z z6XA0E@Zt*F*pLnoL7&1^C>67ij!11pIY}=XHoDr#{eC|mzfVL&eY{RB zzxHr-1tkUtCNtbIzRJ1Rs@&WKnA||2%wKtN*0c#(fh~S1_GL%ft;@+=l9458kIzb; z;D<(TKlhs5d-0@`eMo)?0h!oq1u;}6*&02YKxiJrq_3GCZ8$$Ea+8`2FTNFeZ}cAH=lD_@}MzF~snfVdW~2IG6sGNiXwot@M5}C-9;(6GkJvda4Imk0ZU`8?s5Acr~vv67WDt&3>kgR!Q z@C^n`mkD*G+?!vSmfz}#3EZIL_6}f)RuTEF`m6Q;xc7WU29%0wN^WMVQ`kMVe3O=Zv)U2kF0I;%-I_*x&4MV*~Ij%#8Ywci79dq2QhwlRx+mfxxo5V`SwecXQ~Mc0y+rb zg|VqjCpZIzgG1tt`k^h6ChFMmNFNiBXy(IH#Wbi&GC`=r;l>iW7pWi=v}@}W+M)rn z%?Qgj?vfyQ6~#n<>QBq2uQVz$A`>fBpDg5h*aqy^iPUfCTRvC3s@%pq#9#agVV%-_ zJc(Bv;yQ~zN2+z4RNx`LQvkEd+O8_(!P_X?2r(JDIOKHW=;6X&^j5htkYgmx+ zPP=)THW1J|yV2t|;~dsZ2U?m2kI%U^XjN)AJIu*_J$a%+>t0L5holdh6{&3k%|7iE zrtsZpl}WwJ=+EnB!N1lD)NN2mZwppudv*4!vaa<`OSdrfAfyRW$G0u!JHJ8g0C0Sb zaMj)h>XZ-IjtAQ6J=I%UTnf?yiH1hES#IP?&iK~Y+J5mj=i6Rq1dzBrW+Hv%Uo@OF zsekw$Z>|>BehjWqk@qjkgX#CXk}(}uo;F6(O`pBhCol&u=;NwefpeGaS!=B|@aG!n z4{Zj8hT`NbKZxhZRr#Qe&D_)ayto;NTgxFRN#*Bh?zf`&;KVYonZ(?7`+yf;{;oZJ zKWJ?M=NA8Z_oG8{KnPo9jO5V5!CZ4vNP}NVz7`?uaUR!S5m{j`avUT552OiH%z=>) z5RNArX$Sd(prND)zx&L#s53*%z7}voFH|C{@=VUKQ}!PMTq#`~##n4UcSx8|x31zf zd$CsHYFYH<+*(w$_@1uzbLF#`kU_dapyB&g?ef4&%KZ73=kwegptX$_Km0(d42UXF zJtLAJvE&OzCIle6!rTivoLJ?u5#&{Qtbvp*<9(3>9;e=+WUeRnbyie7vm1> zjBjzl?mzhyhI)`5{`u#+!eiQ-D8ZtG#A*kcCz!oEGHM|fbR??pyX6Jvi%%Qc`{GXc z9$S+a0{#R01XPPTk_+eU2cH4a%b1wmb~vmN&WN>@NLO;C%vW*>4cHXbO>G}zFFPn$ z`z*0*fCo$1E;J3aMM2Mn&TOT>IlTFXg!+-q*^icyc3OGPf_|74(Mc=k`9b7clIKtN zng411`u}0?y`q|2|MyM5ds|UdkPc#@hAK+vWs6c0On`)%P&Q2n2uSbn+ftMgloZeq zU;_yufq<0I%U2MPARwWKCS7`yCdJABVCH1jnzd%FS#vUTmZKcKdGkD<&wXFleUdvK zKYkquo9Ao}Qyp}GlK9h6XJ;56J!Epi%QU-sgT-Jp0((5v#;s&vzoZv5IvzG*tgGN4 zsp4n_yjfiA)mt-#>4B8qk5{v;f9?GGffT+b=j-mw$D>+{WiqOektVfhNK{-Q$`yBzuN6xBA6xQ8?pfPt8^G~ z8W_RUoBM1<*C>mwS>oIlLo!k4)!r7b26h(ODW>6st43QYW|LQ#J7e?<)gS(7tR4}G zt~8d~nG&`_Xtz{#EO?WlsQOZ$k$?h#m6uN6Xh#+AyoIHu$2CJws0x{HPTSBpL#(cf z#9jbraTp#ABN>PBLm-D5i!N;_FK$5=D(CM7^+lw|^au=BR2N)qC^IaXF!NXJEi5aH zE?m@Zh?I}aLP==ZRhmdS=nWgH?Y}cSpN{p`xxDuJiov78t!joaJX`aVx>s^AZFmuv z6_{F}wTE-iH0YNO=l&lS#V0XS_X>^%$}V3;K$vBU+-9z2*P$$4`WnA zGS#XvJ>Gm6cHP4yuCi6}5q4~M=Nnw?^4D^6qP&)akCb(Bs+ZQg_?2FggfJUCQjc>j z0P|oGTJI8^UgYVeDNgaCjNk>wADEV`st6&03k+O8Zt@T;}T5{H2& zN|#7Zaxeo_Cjb4yXE3yWF(VAYsqZ*gqe;2)P-YjYB%7}1StCgQuK!Pl zXB9BJQqwPWx!us%78gEGgH#XHkNI4H$V+0tJf=^xLUBaW{Pc(A*orDdPj+wa92$IJ zU7oXvtgRlnIi{HKVTjW5N0^AN*3>UkTtzeCVNH!q$ac3*yM)ij`oLDbUbGyl#mDT1 zL2|KY9XzPOu*E~53H!FH;F2H=N0xnT5Q+x(Q-@ddeYC1hN5K_E--(za%z>3ru9p4O zajFa-jnfk&U)DI#6FJRUS5J5pUFO4(aDCJUz>&fT^j+^73UfqhH;LGSL5Oay%UM#z6Db3%(tOIXHwvEu|$cs!($ z1rqCNpdlQkMhCZ;$tDyo1JpK^6Iz0S&~?NW11{a%H?bb;m)f}lPYXxjPl_D-qIK?D z8G6+9_a-Sg7ogou&c2vZK>}{Ir?X%AE`LV!n{!Z)3ARQSAvgznd;i95Z&Yj5{pAKb zLxcr(&^)GxBB~vETLc2+H27g=#=?dS3n0oT|67{Vt3WT2r}Y=hXK#mEaRam4>68EM zXRUO23$qrdkRc3~V*ZE59|fojC+gI@kW#YaU&l~r0NR$#@2m-d$^nkIUlKJ%f^bq- zEE5VKsx%O1*;+V5yicXVl1~Sz^^QH&v-!hlP>XlZZ85hM^{~Q?qcR*Ph+k#IJ~kHF zsI3>T$b7YA`ukjxDe{Q$>WlAEnhlHaO9nG*r}WukO0guc&X&#^7x*4$*+c+o^y2|A zDCccw>21W2m5D*MiqUYgWG+z$h42Tc@8$N*>)0-p<% z-lbQ`m!x6$#ZGc}cG-@ny0lg*Vt9Ndh#q+YZ`u?`P>L5oz=iW8GoG@+t$kq*z#DvFsILp+6t?1@6R-W7#j?1D9lzhdUHx< zjJ2OhZW&jxvGe1i;d^Q-9s4ygQ5GdWl1k4g{bd*8sNF!ov%jUIDv zZ-qTE+m0@z7c5(NvrGSx!aYEZlDQocD${!M~{$fJyyf8Ni7-hbs-bHWD3lEN6s`I5`S6EW?C} z_cVa}$iq=a6kTo5K)^z~s>DXB;nUgGny~Lo6b#>vNoCI|2 zXe$vu9mS^@RY<7aa8MZiZ$^FE{*AT8LH5-TO7l$^;cH2h7lfe~uI!!gq#%PMD^-cF z`NhB<9X=IrtVsuC=2pVw#GKR{+#ntDX=i`|HMTC~mvWcG!Bd?b`G_1!Ysbqh-){3(E07E%`f9SW8ZPZR-6QQlqou;2cP-~-D%KDs|NZ)lJz3(unaH6i*k~4W4AjCKeuItXJHz8$xUgV58BIUC$?(CW! zpAQ(D^wx^WUD9pTyFaAtZd@}63(Hv>Blq4u z*hASvSYzr|t33Qy+kR3nj$%l**4*`7lZ%|f!QHYM=-y*ZHott zi{!yP=9D?Zw$0*zikij(TPJC!tisITxQsrvW*GYIls?- z;$fo5ZPk6y%)0b$Tc%dw2ikpv%$S&*)?XEzDEhCJJ@zFWdDreo;uJD^XDlOgtzR89 z5QGAwtbPsu0jQkwvDlyQWmIDXg;ZNr2K&cwdCyA?b#DxJ}7Jt$G{j(X-7 ztJuERmC}V78cM4D;Nw2s%?_M#aTsWJ3v#{PL(56F`IdVv75SwuI{ z`k^}8_Ki%7kv|>x1l-mEOr>V@PJMbo7${JFhjO{uIwK`>(%N*fkNa?-UH@_+b|&+G zs_4=_hQU{l{=*6y{a&Gh81)Q%5N9$Ng)B5ak7+IxnKgB=8dQa74$NaV!e@U3OT9^T zzg$g)7t356Vsy?fBOV@7;c!aqjCJa5&rcds&|5QPs8ARHGTFD%5ADmEYSXN<3|XMs zWMpSlkzp#tEY6i;D9pQaO0ISY=y0)1b^7Ycucr3lVyYTdbVY?7{r2$|+urU8fA(oI zUOF#{Erol#*yV z9(x1z$n+1BM9XAvD_e3{oS?~qr#p`}cd5%efD8I9sk3aq@mYS;kR!nFvO0CA@AKQM90}p;q@R<@=I@pA<{WN8 z2#StArZ$zw+@JavGML%`hKb9o;mDNbn4$CBVxa;)QYmsz|Bm$Ijn|yZWMNYCm(p-` zbG-`++8xI-n(95k%QJc1!fH(9ws-UNOCLLEQLD{%Xffsw8G%(H~dm z?%e@hrNw;OHiHaD3FX|}I*8x+*>mwuwLQZA@%3!gkVldcN_i^DS4E@2qfahvxP|#l zd8c1%emYJ%exxw*zAn;(O;BJQnNXZ(JIJLdJbt(QBqRx=qO4$2d z^SJn_B*!a`B*aqa!UA?ND&61P8$_hE={j!C%nbf?TFd3}LhR>W&(`hD0WJ*B;FSm) zstp4`?pTY;bP3nY&00inqsQCxw z>Z~{x;7wqQ{;$REY3T2NP)5mlfi3(n6oqvq1j-ObSb~O9xF8fL9?Zm#WFAWGIXs&6 z8F>TrFPP9{%wAD7VMnWE+I(b~aktZ+c=%A!uvy7}M0D)g?Y`e89CU|fwXRreO!3NP z%NQ*)gUaz_SoX}iyYYiW;XtYq>QlSnKx&d;c(s~6&`B)Vf__>G%1cJUf4XqA~nBcS`}Y7kV0Xu3)dk;f1kVA7|H<~@`h=* z>&dbh-0DvUs#c?2*u#@AHl|_KnNW;rNG<1ywysW7$9~E1oK5RctFimnRc8trUI&MH zU$LmIajfPkmg(Y$3q!9H_fD4-ludcgFO!jM*3jd+Rq&9UmN~~LDJWw=(>)QpEaNc}SfT3ij^1G&be=()(slY@ixB(ub-`EJyuveErDKhoV>I zI7!CBZb%pwg$wi>?26hg)?&<|G_pZhv(w~E(QvU=RCi8+?S$2B8RluWYLOnQ7uZCk z^^=8mBs2K#7XBE(1_Uo8QiKgr{IFEo6nH<|m=EWYt!|S+H>4FaCAgWjZZ)nSBwMc>SI3c zi5p`t7So@Q0zn+@MWgrri$5DuxGN}dMDQb7i>jdPRaWR@=D97)7ZPQL-;Y$ zzPY+7IlK%gw4no{ckY|s;vcH8)1u?j>4W7?#S;@x?u=O)bs*cw8qQV_)VSOy@(r{p zPhy*tHDpqDsw5h(ha3(nHfF;syaACLB?ZScyk3nRxOjnVHaZYr=Y0IHhIJ13^Uuo)iom0*|U*XZB?~R0it%{oP*F!#Q4d z$?Iu8sR@_Z?Z;Adq@__%t9x&V(b-4$dg43eK}CbvX71tX; zkE;J<%4IBU@Nb67yB+di1;S7z4RqTF;r-@APH$fz(y(#nctr@z3$cVZApr&;XKx#; zWusgEc+DLnGUq^o2K(V%cnNf|dqBD1ZCGl75P-=?-WYtVFn0l5={-ryp0oaTI=Cqg zss-xZzmd{%)At0a{93g~i5qG9O<6(p)N%2$!gm|*6jNkY){m*B&t2ipVx~cEiJixH ztWgDVE?(S{^W*MUTFrAFTHrjL`0`7M`9Ar$PQ4$hr zF=1;QSn^~4jz?{y57eY|gO?jJL^73^Le{?CuzSR_QeZ~NZ?*E`@Rns@S*H_2_Tt(+ z5uu9#uk{4Pd&wO62H4j=J;1(DD)Is%C`RPbXOf_xZ}F!I4DGcyNxrzr^RV z0GY)$BilFahDG&sigX>$O4Ea9G1a$p_M_!Qp76kaAK@1D!rGGIh<{$>O!z+tN z?seM_r%+p;Ym7`duY~fwK!uk+$o=rXvBF2G)WHs5m(d~lI*QyS$K|DxZ9?Vb5+5us zQl4P=UDb#j5lFDhvaChnQL%-%opu75ME z)pXoRG{sc(7-@>!{D>U0Zyo+P!RTcvx9^h+SJgJsC7whV_6h2_aH1D|$MNhkX@S(0 zL2OJr!y2lTm0}LVxxdZ?f_)XiJIE>a(3tFjfZm0D0U54_+4;i{| z%B3$+VA+7yZ44~Iq$@0;W!-T0%Z6JGX1JdY9QTgQy*@oTTAF<&ant(az}@<~nzx@t z=xh7qKv`dZf4@9?6PF#GB0`9_F&GbG#L>ONiU!*{@*{RS$O;a2XB�?AQu0-@oO& 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

}JF9*YL?^;#|qFfwiOqJicUj@N0Smrs^?hi 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 a>Nq8luYJ=u6OkQ5eVtR~%6=gYoc<3ImW=iQ literal 0 HcmV?d00001 diff --git a/locomotion/src/third_party/qpOASES/examples/Makefile b/locomotion/src/third_party/qpOASES/examples/Makefile new file mode 100644 index 0000000..cfcbba8 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/Makefile @@ -0,0 +1,107 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: examples/Makefile +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2007-2017 +## + +include ../make.mk + +## +## flags +## + +IFLAGS = -I. \ + -I${IDIR} + +QPOASES_EXES = \ + ${BINDIR}/example1${EXE} \ + ${BINDIR}/example1a${EXE} \ + ${BINDIR}/example1b${EXE} \ + ${BINDIR}/example2${EXE} \ + ${BINDIR}/example3${EXE} \ + ${BINDIR}/example3b${EXE} \ + ${BINDIR}/example4${EXE} \ + ${BINDIR}/example5${EXE} \ + ${BINDIR}/exampleLP${EXE} \ + ${BINDIR}/qrecipe${EXE} \ + ${BINDIR}/qrecipeSchur${EXE} + + +## +## targets +## + +all: ${QPOASES_EXES} + +${BINDIR}/%${EXE}: %.${OBJEXT} ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + +${BINDIR}/example4${EXE}: example4.${OBJEXT} example4CP.cpp ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + +${BINDIR}/qrecipe${EXE}: qrecipe.${OBJEXT} qrecipe_data.hpp ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + +${BINDIR}/qrecipeSchur${EXE}: qrecipeSchur.${OBJEXT} qrecipe_data.hpp ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + + +clean: + @${ECHO} "Cleaning up (examples)" + @${RM} -f *.${OBJEXT} ${QPOASES_EXES} + +clobber: clean + + +${LINK_DEPENDS}: + @cd ..; ${MAKE} -s src + +example4.${OBJEXT}: example4.cpp example4CP.cpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} -c ${IFLAGS} ${CPPFLAGS} $< + +qrecipe.${OBJEXT}: qrecipe.cpp qrecipe_data.hpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${IFLAGS} ${CPPFLAGS} -c $< + +qrecipeSchur.${OBJEXT}: qrecipeSchur.cpp qrecipe_data.hpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${IFLAGS} ${CPPFLAGS} -c $< + +%.${OBJEXT}: %.cpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} -c ${IFLAGS} ${CPPFLAGS} $< + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/examples/example1.cpp b/locomotion/src/third_party/qpOASES/examples/example1.cpp new file mode 100644 index 0000000..05182c8 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example1.cpp @@ -0,0 +1,100 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example1.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Very simple example for testing qpOASES using the QProblem class. + */ + + + +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + + /* Setting up QProblem object. */ + QProblem example( 2,1 ); + + Options options; + example.setOptions( options ); + + /* Solve first QP. */ + int_t nWSR = 10; + example.init( H,g,A,lb,ub,lbA,ubA, nWSR ); + + /* Get and print solution of first QP. */ + real_t xOpt[2]; + real_t yOpt[2+1]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2],example.getObjVal() ); + + /* Solve second QP. */ + nWSR = 10; + example.hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2],example.getObjVal() ); + + example.printOptions(); + /*example.printProperties();*/ + + /*getGlobalMessageHandler()->listAllMessages();*/ + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/example1a.cpp b/locomotion/src/third_party/qpOASES/examples/example1a.cpp new file mode 100644 index 0000000..cfbe6a9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example1a.cpp @@ -0,0 +1,85 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example1a.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Very simple example for testing qpOASES using the SQProblem class. + */ + + + +#include + + +/** Example for qpOASES main function using the SQProblem class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t H_new[2*2] = { 1.0, 0.5, 0.5, 0.5 }; + real_t A_new[1*2] = { 1.0, 5.0 }; + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + + /* Setting up SQProblem object. */ + SQProblem example( 2,1 ); + + /* Solve first QP. */ + int_t nWSR = 10; + example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + + /* Solve second QP. */ + nWSR = 10; + example.hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,0 ); + + /* Get and print solution of second QP. */ + real_t xOpt[2]; + example.getPrimalSolution( xOpt ); + printf( "\nxOpt = [ %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() ); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/example1b.cpp b/locomotion/src/third_party/qpOASES/examples/example1b.cpp new file mode 100644 index 0000000..09d2b5c --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example1b.cpp @@ -0,0 +1,90 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example1b.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Very simple example for testing qpOASES using the QProblemB class. + */ + + +#include + + +/** Example for qpOASES main function using the QProblemB class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + + + /* Setting up QProblemB object. */ + QProblemB example( 2 ); + + Options options; + //options.enableFlippingBounds = BT_FALSE; + options.initialStatusBounds = ST_INACTIVE; + options.numRefinementSteps = 1; + options.enableCholeskyRefactorisation = 1; + example.setOptions( options ); + + + /* Solve first QP. */ + int_t nWSR = 10; + example.init( H,g,lb,ub, nWSR,0 ); + + /* Get and print solution of first QP. */ + real_t xOpt[2]; + example.getPrimalSolution( xOpt ); + printf( "\nxOpt = [ %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() ); + + /* Solve second QP. */ + nWSR = 10; + example.hotstart( g_new,lb_new,ub_new, nWSR,0 ); +// printf( "\nnWSR = %d\n\n", nWSR ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + printf( "\nxOpt = [ %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() ); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/example2.cpp b/locomotion/src/third_party/qpOASES/examples/example2.cpp new file mode 100644 index 0000000..8fa7ca4 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example2.cpp @@ -0,0 +1,123 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example2.cpp + * \author Hans Joachim Ferreau (thanks to Boris Houska) + * \version 3.2 + * \date 2008-2017 + * + * Very simple example for testing qpOASES in combination + * with the SolutionAnalysis class. + */ + + + +#include + + +/** Example for qpOASES main function using the SolutionAnalysis class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t H_new[2*2] = { 1.0, 0.5, 0.5, 0.5 }; + real_t A_new[1*2] = { 1.0, 5.0 }; + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + + /* Setting up SQProblem object and solution analyser. */ + SQProblem example( 2,1 ); + SolutionAnalysis analyser; + + /* Solve first QP ... */ + int_t nWSR = 10; + example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + + /* ... and analyse it. */ + real_t maxKktViolation = analyser.getKktViolation( &example ); + printf( "maxKktViolation: %e\n", maxKktViolation ); + + /* Solve second QP ... */ + nWSR = 10; + example.hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,0 ); + + /* ... and analyse it. */ + maxKktViolation = analyser.getKktViolation( &example ); + printf( "maxKktViolation: %e\n", maxKktViolation ); + + +// ------------ VARIANCE-COVARIANCE EVALUATION -------------------- + + real_t *Var = new real_t[5*5]; + real_t *Primal_Dual_Var = new real_t[5*5]; + + int_t run1, run2; + for( run1 = 0; run1 < 5*5; run1++ ) + Var[run1] = 0.0; + + Var[0] = 1.0; + Var[6] = 1.0; + +// ( 1 0 0 0 0 ) +// ( 0 1 0 0 0 ) +// Var = ( 0 0 0 0 0 ) +// ( 0 0 0 0 0 ) +// ( 0 0 0 0 0 ) + + + analyser.getVarianceCovariance( &example, Var,Primal_Dual_Var ); + + printf("\nPrimal_Dual_VAR = \n"); + for( run1 = 0; run1 < 5; run1++ ){ + for( run2 = 0; run2 < 5; run2++ ){ + printf(" %10f", Primal_Dual_Var[run1*5+run2]); + } + printf("\n"); + } + + delete[] Primal_Dual_Var; + delete[] Var; + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/example3.cpp b/locomotion/src/third_party/qpOASES/examples/example3.cpp new file mode 100644 index 0000000..b9a7d62 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example3.cpp @@ -0,0 +1,88 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example3.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2008-2017 + * + * Example demonstrating usage of qpOASES for solving a QP sequence of the + * Online QP Benchmark Collection. In order to run it, you have to download + * "Example 02" from from http://www.qpOASES.org/onlineQP/ and store it into + * the directory bin/chain80w/. + */ + + + +#include + + +/** Example for qpOASES main function using the OQP interface. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* 1) Define benchmark arguments. */ + BooleanType isSparse = BT_FALSE; + Options options; + options.setToMPC(); + options.printLevel = PL_NONE; + + int_t nWSR = 600; + real_t maxCPUtime = 10.0; /* seconds */ + real_t maxStationarity, maxFeasibility, maxComplementarity; + + /* 2) Run benchmark. */ + if ( runOqpBenchmark( "./chain80w/", + isSparse, + options, + nWSR, + maxCPUtime, + maxStationarity, + maxFeasibility, + maxComplementarity + ) != SUCCESSFUL_RETURN ) + { + myPrintf( "In order to run this example, you need to download example no. 02\nfrom the Online QP Benchmark Collection website first!\n" ); + return -1; + } + + /* 3) Print results. */ + printf( "\n\n" ); + printf( "OQP Benchmark Results:\n" ); + printf( "======================\n\n" ); + printf( "maximum violation stationarity: %.3e\n",maxStationarity ); + printf( "maximum violation feasibility: %.3e\n",maxFeasibility ); + printf( "maximum violation complementarity: %.3e\n",maxComplementarity ); + printf( "\n" ); + printf( "maximum CPU time: %.3f milliseconds\n\n",1000.0*maxCPUtime ); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/example3b.cpp b/locomotion/src/third_party/qpOASES/examples/example3b.cpp new file mode 100644 index 0000000..54fe001 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example3b.cpp @@ -0,0 +1,88 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example3b.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2008-2017 + * + * Example demonstrating usage of qpOASES for solving a QP sequence of the + * Online QP Benchmark Collection. In order to run it, you have to download + * "Example 02" from http://www.qpOASES.org/onlineQP/ and store it into + * the directory bin/chain80/. + */ + + + +#include + + +/** Example for qpOASES main function using the OQP interface. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* 1) Define benchmark arguments. */ + BooleanType isSparse = BT_FALSE; + Options options; + options.setToMPC(); + options.printLevel = PL_NONE; + + int_t nWSR = 300; + real_t maxCPUtime = 10.0; /* seconds */ + real_t maxStationarity, maxFeasibility, maxComplementarity; + + /* 2) Run benchmark. */ + if ( runOqpBenchmark( "./chain80/", + isSparse, + options, + nWSR, + maxCPUtime, + maxStationarity, + maxFeasibility, + maxComplementarity + ) != SUCCESSFUL_RETURN ) + { + myPrintf( "In order to run this example, you need to download example no. 02\nfrom the Online QP Benchmark Collection website first!\n" ); + return -1; + } + + /* 3) Print results. */ + printf( "\n\n" ); + printf( "OQP Benchmark Results:\n" ); + printf( "======================\n\n" ); + printf( "maximum violation stationarity: %.3e\n",maxStationarity ); + printf( "maximum violation feasibility: %.3e\n",maxFeasibility ); + printf( "maximum violation complementarity: %.3e\n",maxComplementarity ); + printf( "\n" ); + printf( "maximum CPU time: %.3f milliseconds\n\n",1000.0*maxCPUtime ); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/example4.cpp b/locomotion/src/third_party/qpOASES/examples/example4.cpp new file mode 100644 index 0000000..9abd1a0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example4.cpp @@ -0,0 +1,172 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example4.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2009-2017 + * + * Very simple example for testing qpOASES (using the possibility to specify + * user-defined constraint product function). + */ + + + +#include + +#include +#include "example4CP.cpp" + + +/** Example for qpOASES main function using the possibility to specify + * user-defined constraint product function. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t i,j; + + /* Setup data of first QP... */ + real_t H[7*7]; + real_t A[50*7]; + real_t g[7]; + real_t lbA[50]; + + /* ( 1.0 0.5 | ) + * ( 0.5 2.0 | ) + * ( --------+------------------- ) + * H = ( | 1e-6 ) + * ( | 1e-6 ) + * ( | ... ) + * ( | 1e-6 ) */ + for( i=0; i<7*7; ++i ) + H[i] = 0.0; + for( i=2; i<7; ++i ) + H[i*7+i] = 1.0e-6; + H[0] = 1.0; + H[1] = 0.5; + H[7] = 0.5; + H[8] = 2.0; + + /* ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | 1.0 ) + * A = ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) */ + for( i=0; i<50*7; ++i ) + A[i] = 0.0; + for( i=0; i<50; ++i ) + { + for( j=0; j<2; ++j ) + A[i*7+j] = (real_t)rand() / (real_t)RAND_MAX; + + A[i*7 + (i/10)+2] = 1.0; + } + + /* ( -1.0 ) + * ( -0.5 ) + * ( ---- ) + * g = ( ) + * ( ) + * ( ) + * ( ) */ + for( i=0; i<7; ++i ) + g[i] = 0.0; + g[0] = -1.0; + g[1] = -0.5; + + for( i=0; i<50; ++i ) + lbA[i] = 1.0; + + /* ... and setting up user-defined constraint product function. */ + MyConstraintProduct myCP( 7,50,A ); + + + /* Setting up QProblem object and set construct product function. */ + QProblem exampleCP( 7,50 ); + exampleCP.setPrintLevel( PL_NONE ); + + exampleCP.setConstraintProduct( &myCP ); + + + /* Solve first QP. */ + real_t cputime = 1.0; + int_t nWSR = 100; + exampleCP.init( H,g,A,0,0,lbA,0, nWSR,&cputime ); + + + /* Solve second QP using a modified gradient. */ + g[0] = -2.0; + g[1] = 0.5; + + cputime = 1.0; + nWSR = 100; + exampleCP.hotstart( g,0,0,lbA,0, nWSR,&cputime ); + + /* Get and print solution of second QP. */ + real_t xOpt[7]; + exampleCP.getPrimalSolution( xOpt ); + printf( "\nxOpt = [ %e, %e, %e ... ]; objVal = %e\n", xOpt[0],xOpt[1],xOpt[2],exampleCP.getObjVal() ); + printf( "CPU time: %.3f microseconds\n\n", cputime*1.0e6 ); + + + + /* Do the same without specifying constraint product. */ + QProblem example( 7,50 ); + example.setPrintLevel( PL_NONE ); + + /* Solve first QP. */ + g[0] = -1.0; + g[1] = -0.5; + + cputime = 1.0; + nWSR = 100; + example.init( H,g,A,0,0,lbA,0, nWSR,&cputime ); + + /* Solve second QP using a modified gradient. */ + g[0] = -2.0; + g[1] = 0.5; + + cputime = 1.0; + nWSR = 100; + example.hotstart( g,0,0,lbA,0, nWSR,&cputime ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + printf( "\nxOpt = [ %e, %e, %e ... ]; objVal = %e\n", xOpt[0],xOpt[1],xOpt[2],example.getObjVal() ); + printf( "CPU time: %.3f microseconds\n\n", cputime*1.0e6 ); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/example4CP.cpp b/locomotion/src/third_party/qpOASES/examples/example4CP.cpp new file mode 100644 index 0000000..7d013a7 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example4CP.cpp @@ -0,0 +1,112 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example4CP.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2009-2017 + * + * Sample implementation of the ConstraintProduct class tailored for Example4. + */ + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Example illustrating the use of the \a ConstraintProduct class. + * + * Example illustrating the use of the \a ConstraintProduct class. + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + */ +class MyConstraintProduct : public ConstraintProduct +{ + public: + /** Default constructor. */ + MyConstraintProduct( ) {}; + + /** Constructor. */ + MyConstraintProduct( int_t _nV, + int_t _nC, + real_t* _A + ) + { + nV = _nV; + nC = _nC; + A = _A; + }; + + /** Copy constructor (flat copy). */ + MyConstraintProduct( const MyConstraintProduct& rhs + ) + { + nV = rhs.nV; + nC = rhs.nC; + A = rhs.A; + }; + + /** Destructor. */ + virtual ~MyConstraintProduct( ) {}; + + /** Assignment operator (flat copy). */ + MyConstraintProduct& operator=( const MyConstraintProduct& rhs + ) + { + if ( this != &rhs ) + { + nV = rhs.nV; + nC = rhs.nC; + A = rhs.A; + } + return *this; + }; + + virtual int_t operator() ( int_t constrIndex, + const real_t* const x, + real_t* const constrValue + ) const + { + int_t i; + + constrValue[0] = 1.0 * x[(constrIndex/10)+2]; + + for( i=0; i<2; ++i ) + constrValue[0] += A[constrIndex*nV + i] * x[i]; + + return 0; + }; + + protected: + int_t nV; /**< Number of variables. */ + int_t nC; /**< Number of constraints. */ + real_t* A; /**< Pointer to full constraint matrix (typically not needed!). */ +}; + + +END_NAMESPACE_QPOASES + diff --git a/locomotion/src/third_party/qpOASES/examples/example5.cpp b/locomotion/src/third_party/qpOASES/examples/example5.cpp new file mode 100644 index 0000000..339cd48 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/example5.cpp @@ -0,0 +1,200 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/example5.cpp + * \author Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2011-2017 + * + * Very simple example for testing qpOASES (using the possibility to + * compute the local linear feedback law) + */ + + + +#include + +#include +#include "example4CP.cpp" + + +/** Example for qpOASES main function using the possibility to specify + * user-defined constraint product function. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t i,j,jj; + real_t d = 0.0; + + /* Setup data of first QP... */ + real_t H[7*7]; + real_t A[50*7]; + real_t g[7]; + real_t lbA[50]; + + /* ( 1.0 0.5 | ) + * ( 0.5 2.0 | ) + * ( --------+------------------- ) + * H = ( | 1e-6 ) + * ( | 1e-6 ) + * ( | ... ) + * ( | 1e-6 ) */ + for( i=0; i<7*7; ++i ) + H[i] = 0.0; + for( i=2; i<7; ++i ) + H[i*7+i] = 1.0e-6; + H[0] = 1.0; + H[1] = 0.5; + H[7] = 0.5; + H[8] = 2.0; + + /* ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | 1.0 ) + * A = ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) */ + for( i=0; i<50*7; ++i ) + A[i] = 0.0; + for( i=0; i<50; ++i ) + { + for( j=0; j<2; ++j ) + A[i*7+j] = (real_t)rand() / (real_t)RAND_MAX; + + A[i*7 + (i/10)+2] = 1.0; + } + + /* ( -1.0 ) + * ( -0.5 ) + * ( ---- ) + * g = ( ) + * ( ) + * ( ) + * ( ) */ + for( i=0; i<7; ++i ) + g[i] = 0.0; + g[0] = -1.0; + g[1] = -0.5; + + for( i=0; i<50; ++i ) + lbA[i] = 1.0; + + /* ... and setting up user-defined constraint product function. */ + MyConstraintProduct myCP( 7,50,A ); + + + /* Setting up QProblem object and set construct product function. */ + QProblem example( 7,50 ); + example.setConstraintProduct( &myCP ); + + + /* Solve first QP. */ + real_t cputime = 1.0; + int_t nWSR = 100; + example.init( H,g,A,0,0,lbA,0, nWSR,&cputime ); + + /* Get and print solution of QP. */ + real_t xOpt[7], yOpt[7+50]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + + + /* Compute local linear feedback law */ + const int_t n_rhs = 7+7+50; + real_t g_in[7*n_rhs]; + real_t b_in[7*n_rhs]; + real_t bA_in[50*n_rhs]; + real_t x_out[7*n_rhs]; + real_t y_out[(7+50)*n_rhs]; + + int_t ii; + memset (g_in, 0, sizeof (g_in)); + memset (b_in, 0, sizeof (b_in)); + memset (bA_in, 0, sizeof (bA_in)); + + for ( ii = 0; ii < 7; ++ii ) + g_in[ii*7 + ii] = 1.0; + for ( ii = 0; ii < 7; ++ii ) + b_in[(ii+7)*7 + ii] = 1.0; + for ( ii = 0; ii < 50; ++ii ) + bA_in[(ii+14)*50 + ii] = 1.0; + + example.solveCurrentEQP ( n_rhs, g_in, b_in, b_in, bA_in, bA_in, x_out, y_out ); + + /* Verify validity of local feedback law by perturbation and hot starts */ + real_t perturb = 1.0e-6; + real_t nrm = 0.0; + for ( ii = 0; ii < n_rhs; ++ii ) + { + for ( jj = 0; jj < 7; ++jj ) + g_in[ii*7 + jj] = g[jj] + g_in[ii*7+jj]*perturb; + for ( jj = 0; jj < 50; ++jj ) + bA_in[ii*50 + jj] = lbA[jj] + bA_in[ii*50+jj]*perturb; + + nWSR = 100; + example.hotstart( &g_in[ii*7],0,0,&bA_in[ii*50],0, nWSR, 0 ); + + real_t xPer[7], yPer[7+50]; + example.getPrimalSolution( xPer ); + example.getDualSolution( yPer ); + + for ( jj = 0; jj < 7; ++jj ) + { + d = getAbs (x_out[ii*7+jj]*perturb - (xPer[jj]-xOpt[jj]) ); + if (nrm < d) nrm=d; + } + for ( jj = 0; jj < 7+50; ++jj ) + { + d = getAbs (y_out[ii*(7+50)+jj]*perturb - (yPer[jj]-yOpt[jj]) ); + if (nrm < d) nrm=d; + } + } + printf ("Maximum perturbation over all directions: %e\n", nrm); + + /* // print feedback matrix + for (ii = 0; ii < n_rhs; ++ii) + { + printf ("x: "); + for (jj = 0; jj < 7; ++jj ) + printf ("%8.2e ", x_out[ii*7+jj]); + printf (" y: "); + for (jj = 0; jj < 7+50; ++jj ) + printf ("%8.2e ", y_out[ii*(7+50)+jj]); + printf("\n"); + } +*/ + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/exampleLP.cpp b/locomotion/src/third_party/qpOASES/examples/exampleLP.cpp new file mode 100644 index 0000000..d7ee168 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/exampleLP.cpp @@ -0,0 +1,87 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/exampleLP.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2008-2017 + * + * Very simple example for solving a LP sequence using qpOASES. + */ + + + +#include + + +/** Example for qpOASES main function solving LPs. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first LP. */ + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second LP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + + /* Setting up QProblem object with zero Hessian matrix. */ + QProblem example( 2,1,HST_ZERO ); + + Options options; + //options.setToMPC(); + example.setOptions( options ); + + /* Solve first LP. */ + int_t nWSR = 10; + example.init( 0,g,A,lb,ub,lbA,ubA, nWSR,0 ); + + /* Solve second LP. */ + nWSR = 10; + example.hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,0 ); + + + /* Get and print solution of second LP. */ + real_t xOpt[2]; + example.getPrimalSolution( xOpt ); + printf( "\nxOpt = [ %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() ); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/main.py b/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/main.py new file mode 100644 index 0000000..729eb83 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/main.py @@ -0,0 +1,58 @@ +import numpy as np +import scipy as sp +from scipy.sparse import csc_matrix, coo_matrix, csr_matrix, lil_matrix, random +from jinja2 import Environment +from jinja2.loaders import FileSystemLoader +import os + +seed = 42 +density = 0.1 +gamma = 0.01 + +out_file_name = 'qp_data.hpp' +in_file_name = 'qp_data.in.hpp' + +NV = 100 +NC = 10 + +H = csc_matrix((NV, NV)) +A = csc_matrix((NV, NV)) + +myinf = 1e10 + +for i in range(NV): + H[i,i] = 1.0 + +# H = H + gamma*random(NV, NV, density=density, format='csc', random_state=seed) +# H = H.T*H + +for i in range(NC): + A[i,i] = 1.0 + +H_ri = H.indices +H_cp = H.indptr +H_val = H.data +H_nnz = H.nnz + +A_ri = A.indices +A_cp = A.indptr +A_val = A.data +A_nnz = A.nnz + +g = np.ones((NV,1)) + +lb = -myinf*np.ones((NV, 1)) +ub = myinf*np.ones((NV, 1)) + +lbA = -np.ones((NC, 1)) +ubA = np.ones((NC, 1)) + +print('rendering templated C++ code...') +env = Environment(loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__)))) +tmpl = env.get_template(in_file_name) + +code = tmpl.render(NV = NV, NC = NC, H_cp = H_cp, H_ri = H_ri, H_val = H_val, H_nnz = H_nnz, \ + A_cp = A_cp, A_ri = A_ri, A_val = A_val, A_nnz = A_nnz, g = g, lb = lb, ub = ub, lbA = lbA, ubA = ubA) + +with open(out_file_name, "w+") as f: + f.write(code.replace('inf', 'Inf')) diff --git a/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/qp_data.in.hpp b/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/qp_data.in.hpp new file mode 100644 index 0000000..c78b071 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/qp_data.in.hpp @@ -0,0 +1,108 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \author Andrea Zanelli + * \version 3.2 + * \date 2022 + * + * QP data generated by a Python script for testing purposes. + */ + + +USING_NAMESPACE_QPOASES + +#define NV {{NV}} +#define NC {{NC}} + +const real_t Inf = INFTY; + +sparse_int_t H_ri[] = { + {% for d in H_ri %} + {{ d }}, + {%- endfor %} +}; + +sparse_int_t H_cp[] = { + {% for d in H_cp %} + {{ d }}, + {%- endfor %} +}; + +real_t H_val[] = { + {% for d in H_val %} + {{ d }}, + {%- endfor %} +}; + +sparse_int_t A_ri[] = { + {% for d in A_ri %} + {{ d }}, + {%- endfor %} +}; + +sparse_int_t A_cp[] = { + {% for d in A_cp %} + {{ d }}, + {%- endfor %} +}; + +real_t A_val[] = { + {% for d in A_val %} + {{ d }}, + {%- endfor %} +}; + +real_t g[] = { + {% for d in g %} + {{ d[0] }}, + {%- endfor %} +}; + +real_t lb[] = { + {% for d in lb %} + {{ d[0] }}, + {%- endfor %} +}; + +real_t ub[] = { + {% for d in ub %} + {{ d[0] }}, + {%- endfor %} +}; + +real_t lbA[] = { + {% for d in lbA %} + {{ d[0] }}, + {%- endfor %} +}; + +real_t ubA[] = { + {% for d in ubA %} + {{ d[0] }}, + {%- endfor %} + }; + +long H_nnz = {{ H_nnz }}; +long A_nnz = {{ A_nnz }}; diff --git a/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/simple_qp_data.hpp b/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/simple_qp_data.hpp new file mode 100644 index 0000000..944a234 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/simple_qp_data.hpp @@ -0,0 +1,14376 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \author Andrea Zanelli + * \version 3.2 + * \date 2022 + * + * QP data generated by a Python script for testing purposes. + */ + + +USING_NAMESPACE_QPOASES + +#define NV 100 +#define NC 10 + +const real_t Inf = INFTY; + +sparse_int_t H_ri[] = { + + 96, + 24, + 78, + 71, + 52, + 50, + 27, + 95, + 88, + 70, + 65, + 21, + 90, + 69, + 39, + 13, + 4, + 83, + 76, + 36, + 56, + 89, + 60, + 22, + 7, + 97, + 79, + 47, + 46, + 32, + 17, + 86, + 35, + 20, + 73, + 53, + 41, + 30, + 28, + 25, + 23, + 11, + 6, + 92, + 82, + 74, + 58, + 45, + 44, + 33, + 26, + 98, + 93, + 77, + 68, + 64, + 29, + 16, + 14, + 12, + 8, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 40, + 37, + 18, + 3, + 1, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 42, + 38, + 27, + 96, + 89, + 74, + 71, + 51, + 44, + 23, + 82, + 62, + 47, + 46, + 32, + 17, + 99, + 88, + 50, + 19, + 98, + 93, + 77, + 68, + 64, + 14, + 12, + 8, + 79, + 75, + 21, + 11, + 7, + 94, + 69, + 56, + 53, + 52, + 30, + 29, + 16, + 6, + 87, + 84, + 81, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 0, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 87, + 77, + 16, + 66, + 50, + 10, + 36, + 95, + 85, + 80, + 74, + 84, + 82, + 40, + 37, + 3, + 99, + 97, + 89, + 83, + 67, + 34, + 7, + 90, + 86, + 63, + 61, + 49, + 19, + 5, + 81, + 59, + 55, + 54, + 53, + 79, + 65, + 9, + 70, + 69, + 51, + 47, + 32, + 22, + 18, + 75, + 56, + 48, + 94, + 60, + 31, + 30, + 25, + 21, + 20, + 11, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 53, + 67, + 2, + 9, + 77, + 63, + 61, + 50, + 88, + 71, + 36, + 93, + 82, + 56, + 35, + 98, + 97, + 92, + 58, + 33, + 7, + 99, + 90, + 68, + 48, + 46, + 41, + 31, + 17, + 89, + 52, + 43, + 39, + 21, + 6, + 86, + 85, + 76, + 69, + 28, + 20, + 14, + 5, + 75, + 70, + 65, + 62, + 42, + 25, + 16, + 96, + 95, + 91, + 80, + 74, + 73, + 30, + 26, + 22, + 15, + 13, + 94, + 79, + 78, + 11, + 83, + 60, + 47, + 45, + 34, + 32, + 23, + 4, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 81, + 31, + 97, + 86, + 73, + 51, + 91, + 89, + 61, + 58, + 7, + 98, + 87, + 74, + 57, + 38, + 78, + 68, + 66, + 52, + 50, + 35, + 33, + 27, + 8, + 95, + 88, + 55, + 49, + 12, + 11, + 6, + 90, + 84, + 82, + 69, + 41, + 39, + 30, + 22, + 13, + 0, + 75, + 70, + 65, + 62, + 25, + 16, + 15, + 71, + 64, + 59, + 42, + 29, + 21, + 10, + 5, + 83, + 72, + 60, + 47, + 45, + 37, + 34, + 32, + 23, + 4, + 3, + 92, + 74, + 39, + 24, + 66, + 65, + 48, + 41, + 11, + 36, + 25, + 78, + 50, + 7, + 77, + 44, + 73, + 88, + 47, + 15, + 6, + 84, + 54, + 40, + 37, + 90, + 19, + 2, + 96, + 87, + 68, + 67, + 43, + 79, + 70, + 32, + 30, + 22, + 17, + 9, + 86, + 76, + 69, + 57, + 28, + 20, + 18, + 16, + 14, + 3, + 83, + 71, + 64, + 59, + 42, + 29, + 23, + 21, + 10, + 4, + 82, + 72, + 60, + 58, + 56, + 55, + 52, + 33, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 97, + 86, + 82, + 98, + 34, + 26, + 79, + 68, + 59, + 17, + 15, + 10, + 5, + 96, + 83, + 71, + 95, + 88, + 84, + 70, + 65, + 49, + 13, + 4, + 85, + 81, + 38, + 33, + 27, + 58, + 24, + 12, + 91, + 80, + 73, + 51, + 44, + 41, + 31, + 28, + 25, + 23, + 0, + 89, + 78, + 66, + 60, + 55, + 54, + 47, + 45, + 43, + 39, + 21, + 11, + 3, + 94, + 87, + 69, + 56, + 53, + 52, + 37, + 30, + 29, + 16, + 6, + 1, + 39, + 95, + 94, + 86, + 31, + 28, + 55, + 54, + 50, + 5, + 67, + 19, + 9, + 2, + 99, + 88, + 87, + 74, + 34, + 26, + 91, + 65, + 61, + 12, + 4, + 76, + 64, + 49, + 47, + 44, + 42, + 38, + 93, + 82, + 72, + 57, + 56, + 35, + 97, + 92, + 89, + 73, + 60, + 58, + 33, + 18, + 3, + 0, + 98, + 84, + 83, + 77, + 62, + 48, + 46, + 45, + 43, + 41, + 29, + 22, + 17, + 15, + 14, + 13, + 81, + 79, + 78, + 75, + 30, + 21, + 11, + 7, + 1, + 99, + 89, + 86, + 72, + 70, + 58, + 46, + 38, + 13, + 56, + 51, + 48, + 11, + 10, + 78, + 71, + 65, + 55, + 52, + 50, + 35, + 33, + 27, + 4, + 98, + 93, + 87, + 77, + 68, + 66, + 64, + 59, + 49, + 29, + 16, + 14, + 12, + 8, + 1, + 0, + 93, + 80, + 49, + 74, + 71, + 47, + 37, + 27, + 10, + 77, + 68, + 59, + 51, + 41, + 35, + 89, + 67, + 34, + 21, + 19, + 7, + 98, + 86, + 82, + 60, + 31, + 13, + 3, + 83, + 58, + 40, + 24, + 23, + 16, + 65, + 62, + 52, + 2, + 85, + 79, + 70, + 32, + 30, + 22, + 17, + 5, + 99, + 97, + 87, + 81, + 64, + 56, + 53, + 33, + 26, + 15, + 9, + 90, + 67, + 65, + 41, + 2, + 95, + 91, + 66, + 38, + 33, + 31, + 22, + 84, + 76, + 60, + 52, + 46, + 24, + 16, + 82, + 81, + 78, + 75, + 98, + 87, + 74, + 40, + 37, + 27, + 9, + 88, + 79, + 69, + 47, + 28, + 15, + 6, + 56, + 51, + 48, + 11, + 8, + 68, + 58, + 50, + 35, + 26, + 17, + 83, + 71, + 64, + 59, + 42, + 34, + 29, + 23, + 21, + 10, + 5, + 4, + 67, + 5, + 74, + 26, + 97, + 82, + 59, + 99, + 92, + 85, + 17, + 56, + 10, + 8, + 96, + 83, + 71, + 90, + 77, + 63, + 61, + 50, + 40, + 22, + 95, + 88, + 84, + 70, + 65, + 49, + 13, + 4, + 20, + 2, + 91, + 80, + 73, + 53, + 51, + 44, + 37, + 31, + 28, + 25, + 23, + 16, + 0, + 89, + 66, + 60, + 55, + 54, + 52, + 43, + 6, + 93, + 86, + 48, + 47, + 41, + 39, + 34, + 33, + 24, + 15, + 12, + 94, + 45, + 3, + 81, + 79, + 78, + 75, + 30, + 21, + 11, + 7, + 1, + 91, + 89, + 83, + 72, + 62, + 61, + 7, + 90, + 54, + 31, + 22, + 97, + 76, + 67, + 56, + 53, + 50, + 27, + 95, + 88, + 84, + 55, + 30, + 13, + 4, + 58, + 21, + 6, + 92, + 85, + 74, + 70, + 65, + 42, + 38, + 17, + 94, + 86, + 48, + 47, + 41, + 39, + 34, + 33, + 24, + 15, + 11, + 98, + 93, + 87, + 77, + 68, + 66, + 64, + 59, + 49, + 29, + 16, + 14, + 12, + 8, + 1, + 0, + 93, + 97, + 59, + 51, + 87, + 34, + 24, + 89, + 78, + 72, + 64, + 58, + 52, + 38, + 8, + 86, + 23, + 9, + 71, + 33, + 28, + 16, + 88, + 70, + 65, + 55, + 49, + 47, + 21, + 12, + 11, + 6, + 82, + 75, + 69, + 60, + 39, + 4, + 0, + 99, + 90, + 79, + 68, + 66, + 31, + 96, + 95, + 91, + 80, + 74, + 73, + 30, + 26, + 3, + 98, + 84, + 83, + 77, + 62, + 48, + 46, + 45, + 43, + 41, + 29, + 22, + 17, + 15, + 14, + 13, + 7, + 51, + 40, + 24, + 88, + 31, + 99, + 89, + 78, + 72, + 70, + 55, + 52, + 38, + 97, + 67, + 56, + 53, + 50, + 27, + 86, + 85, + 76, + 69, + 57, + 28, + 20, + 18, + 5, + 3, + 94, + 92, + 82, + 75, + 74, + 58, + 54, + 44, + 33, + 26, + 84, + 83, + 62, + 48, + 46, + 45, + 43, + 41, + 22, + 17, + 15, + 13, + 7, + 98, + 93, + 87, + 77, + 68, + 66, + 64, + 59, + 49, + 29, + 16, + 14, + 12, + 8, + 1, + 0, + 49, + 82, + 92, + 44, + 20, + 71, + 52, + 38, + 27, + 88, + 79, + 69, + 68, + 59, + 28, + 21, + 10, + 6, + 5, + 50, + 36, + 18, + 58, + 40, + 75, + 70, + 42, + 25, + 23, + 16, + 4, + 96, + 95, + 91, + 74, + 30, + 3, + 98, + 84, + 83, + 77, + 62, + 46, + 45, + 43, + 29, + 22, + 17, + 14, + 13, + 7, + 94, + 93, + 86, + 47, + 41, + 39, + 34, + 24, + 12, + 11, + 99, + 87, + 81, + 64, + 56, + 53, + 33, + 26, + 9, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 39, + 2, + 84, + 21, + 10, + 99, + 89, + 48, + 82, + 60, + 22, + 81, + 58, + 40, + 9, + 96, + 83, + 13, + 78, + 71, + 55, + 50, + 35, + 27, + 97, + 79, + 46, + 32, + 91, + 80, + 73, + 51, + 44, + 41, + 31, + 11, + 86, + 76, + 57, + 28, + 20, + 18, + 5, + 92, + 85, + 74, + 38, + 33, + 24, + 17, + 75, + 72, + 70, + 65, + 62, + 47, + 45, + 42, + 25, + 23, + 15, + 4, + 3, + 98, + 93, + 77, + 68, + 66, + 64, + 59, + 49, + 14, + 12, + 8, + 0, + 94, + 87, + 69, + 56, + 53, + 52, + 37, + 30, + 29, + 16, + 6, + 1, + 95, + 76, + 78, + 75, + 44, + 20, + 11, + 88, + 69, + 59, + 21, + 6, + 86, + 82, + 60, + 81, + 40, + 23, + 9, + 5, + 97, + 87, + 72, + 53, + 47, + 32, + 1, + 0, + 99, + 90, + 79, + 66, + 31, + 30, + 3, + 50, + 35, + 10, + 94, + 93, + 85, + 74, + 70, + 65, + 38, + 33, + 24, + 16, + 12, + 98, + 84, + 83, + 77, + 48, + 46, + 29, + 22, + 15, + 14, + 13, + 7, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 91, + 77, + 99, + 88, + 74, + 64, + 34, + 26, + 83, + 62, + 50, + 43, + 36, + 15, + 70, + 51, + 48, + 47, + 41, + 32, + 31, + 2, + 93, + 82, + 75, + 56, + 35, + 98, + 97, + 92, + 89, + 73, + 60, + 58, + 33, + 30, + 22, + 7, + 86, + 85, + 76, + 69, + 28, + 20, + 16, + 14, + 5, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 97, + 89, + 67, + 65, + 56, + 34, + 21, + 9, + 7, + 90, + 86, + 63, + 61, + 5, + 2, + 83, + 78, + 57, + 41, + 99, + 88, + 81, + 50, + 49, + 48, + 35, + 30, + 19, + 1, + 98, + 59, + 51, + 50, + 48, + 38, + 92, + 47, + 44, + 17, + 15, + 84, + 82, + 67, + 54, + 43, + 40, + 37, + 60, + 45, + 31, + 30, + 21, + 11, + 2, + 75, + 63, + 49, + 35, + 29, + 0, + 78, + 66, + 46, + 25, + 99, + 94, + 87, + 80, + 74, + 72, + 61, + 26, + 24, + 86, + 85, + 76, + 69, + 57, + 28, + 20, + 18, + 16, + 14, + 5, + 3, + 62, + 82, + 76, + 46, + 16, + 69, + 68, + 28, + 17, + 15, + 99, + 97, + 67, + 56, + 19, + 9, + 91, + 90, + 77, + 63, + 61, + 50, + 40, + 22, + 95, + 88, + 84, + 70, + 65, + 49, + 13, + 0, + 94, + 31, + 25, + 20, + 2, + 58, + 24, + 12, + 89, + 66, + 60, + 55, + 54, + 52, + 47, + 45, + 43, + 39, + 6, + 3, + 83, + 71, + 64, + 59, + 42, + 34, + 29, + 23, + 10, + 5, + 4, + 81, + 79, + 78, + 75, + 30, + 21, + 11, + 7, + 1, + 87, + 81, + 78, + 66, + 38, + 37, + 10, + 57, + 86, + 23, + 16, + 67, + 54, + 12, + 65, + 52, + 51, + 47, + 2, + 88, + 63, + 61, + 50, + 49, + 40, + 21, + 11, + 90, + 82, + 69, + 39, + 4, + 76, + 36, + 97, + 92, + 89, + 60, + 33, + 18, + 0, + 85, + 79, + 70, + 32, + 9, + 5, + 75, + 58, + 31, + 25, + 96, + 95, + 91, + 80, + 74, + 73, + 30, + 26, + 3, + 98, + 84, + 83, + 77, + 62, + 48, + 46, + 45, + 43, + 41, + 29, + 22, + 17, + 15, + 14, + 13, + 7, + 92, + 39, + 98, + 86, + 82, + 22, + 13, + 81, + 58, + 24, + 17, + 9, + 96, + 89, + 77, + 74, + 55, + 1, + 93, + 76, + 69, + 63, + 54, + 46, + 40, + 91, + 80, + 73, + 66, + 53, + 51, + 44, + 41, + 31, + 30, + 28, + 11, + 6, + 0, + 75, + 70, + 65, + 62, + 25, + 16, + 15, + 71, + 64, + 59, + 42, + 29, + 21, + 10, + 5, + 83, + 72, + 60, + 47, + 45, + 37, + 34, + 32, + 23, + 4, + 3, + 59, + 57, + 51, + 50, + 43, + 14, + 62, + 25, + 5, + 0, + 84, + 82, + 60, + 52, + 46, + 10, + 98, + 73, + 29, + 13, + 83, + 81, + 40, + 23, + 9, + 58, + 21, + 6, + 99, + 87, + 80, + 76, + 72, + 61, + 28, + 26, + 20, + 92, + 85, + 74, + 70, + 65, + 42, + 38, + 17, + 16, + 94, + 93, + 86, + 48, + 47, + 41, + 39, + 34, + 33, + 24, + 15, + 12, + 11, + 92, + 74, + 39, + 24, + 86, + 57, + 43, + 36, + 5, + 94, + 60, + 21, + 2, + 88, + 81, + 68, + 52, + 38, + 34, + 33, + 78, + 46, + 20, + 91, + 80, + 73, + 66, + 53, + 51, + 44, + 37, + 30, + 28, + 11, + 6, + 0, + 58, + 48, + 41, + 31, + 29, + 22, + 75, + 72, + 70, + 65, + 62, + 47, + 45, + 42, + 25, + 23, + 16, + 15, + 4, + 3, + 90, + 11, + 78, + 98, + 47, + 39, + 6, + 34, + 18, + 7, + 88, + 77, + 67, + 60, + 55, + 48, + 27, + 50, + 35, + 29, + 10, + 85, + 76, + 72, + 61, + 24, + 20, + 96, + 95, + 80, + 73, + 30, + 22, + 13, + 3, + 94, + 82, + 75, + 74, + 54, + 44, + 14, + 0, + 99, + 97, + 87, + 81, + 64, + 56, + 53, + 33, + 15, + 9, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 98, + 87, + 74, + 47, + 40, + 10, + 9, + 80, + 69, + 42, + 15, + 1, + 97, + 76, + 58, + 53, + 14, + 12, + 78, + 71, + 68, + 66, + 65, + 52, + 50, + 35, + 16, + 8, + 4, + 0, + 85, + 43, + 39, + 38, + 37, + 33, + 6, + 88, + 81, + 77, + 67, + 60, + 56, + 55, + 48, + 29, + 27, + 26, + 50, + 7, + 84, + 60, + 46, + 40, + 82, + 88, + 79, + 47, + 21, + 15, + 10, + 96, + 71, + 55, + 49, + 33, + 13, + 98, + 83, + 78, + 77, + 67, + 64, + 63, + 59, + 73, + 66, + 53, + 51, + 44, + 37, + 31, + 30, + 25, + 23, + 11, + 6, + 0, + 99, + 94, + 87, + 80, + 74, + 72, + 61, + 24, + 86, + 85, + 76, + 69, + 20, + 18, + 16, + 14, + 5, + 3, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 73, + 47, + 39, + 24, + 86, + 63, + 20, + 88, + 81, + 67, + 60, + 55, + 27, + 50, + 35, + 26, + 75, + 58, + 31, + 25, + 84, + 62, + 48, + 46, + 45, + 43, + 41, + 22, + 17, + 15, + 13, + 7, + 83, + 71, + 42, + 34, + 23, + 21, + 10, + 5, + 4, + 98, + 93, + 77, + 68, + 66, + 64, + 59, + 49, + 14, + 12, + 8, + 0, + 94, + 87, + 69, + 56, + 53, + 52, + 37, + 30, + 29, + 16, + 6, + 1, + 76, + 57, + 43, + 86, + 77, + 59, + 83, + 72, + 62, + 61, + 65, + 55, + 47, + 12, + 45, + 20, + 2, + 84, + 82, + 39, + 4, + 98, + 97, + 92, + 89, + 60, + 58, + 33, + 18, + 85, + 70, + 32, + 9, + 5, + 90, + 68, + 46, + 17, + 66, + 51, + 44, + 41, + 31, + 28, + 25, + 23, + 0, + 99, + 88, + 50, + 49, + 48, + 35, + 19, + 96, + 95, + 91, + 80, + 74, + 73, + 26, + 22, + 15, + 13, + 3, + 81, + 79, + 78, + 75, + 21, + 11, + 7, + 94, + 87, + 69, + 56, + 53, + 52, + 37, + 30, + 29, + 16, + 6, + 1, + 88, + 57, + 50, + 14, + 7, + 95, + 81, + 38, + 10, + 4, + 98, + 86, + 83, + 9, + 74, + 67, + 54, + 12, + 70, + 69, + 18, + 45, + 21, + 20, + 2, + 87, + 47, + 32, + 99, + 79, + 68, + 46, + 17, + 13, + 3, + 66, + 53, + 44, + 37, + 30, + 28, + 23, + 16, + 11, + 6, + 41, + 29, + 25, + 22, + 82, + 58, + 56, + 55, + 52, + 33, + 97, + 90, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 15, + 1, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 82, + 33, + 98, + 57, + 49, + 69, + 58, + 51, + 48, + 41, + 18, + 2, + 92, + 90, + 81, + 74, + 59, + 44, + 43, + 40, + 38, + 85, + 70, + 30, + 22, + 9, + 5, + 97, + 87, + 79, + 66, + 62, + 53, + 46, + 31, + 17, + 16, + 1, + 0, + 83, + 72, + 60, + 47, + 45, + 37, + 34, + 32, + 23, + 4, + 3, + 90, + 80, + 95, + 10, + 59, + 51, + 79, + 32, + 96, + 83, + 49, + 28, + 13, + 78, + 71, + 50, + 35, + 8, + 4, + 43, + 37, + 27, + 6, + 91, + 88, + 68, + 66, + 25, + 98, + 89, + 73, + 30, + 22, + 18, + 7, + 3, + 85, + 70, + 65, + 42, + 38, + 17, + 16, + 92, + 75, + 74, + 54, + 45, + 44, + 14, + 0, + 94, + 93, + 86, + 48, + 47, + 41, + 39, + 34, + 24, + 12, + 11, + 99, + 97, + 87, + 81, + 64, + 53, + 26, + 15, + 9, + 82, + 72, + 60, + 58, + 56, + 55, + 52, + 33, + 31, + 5, + 78, + 50, + 98, + 73, + 13, + 6, + 97, + 89, + 67, + 65, + 56, + 19, + 9, + 2, + 99, + 87, + 82, + 74, + 57, + 26, + 18, + 7, + 88, + 81, + 68, + 66, + 52, + 38, + 25, + 93, + 86, + 48, + 41, + 39, + 33, + 24, + 15, + 12, + 11, + 71, + 64, + 59, + 42, + 29, + 21, + 10, + 83, + 72, + 60, + 47, + 45, + 37, + 32, + 23, + 4, + 3, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 69, + 95, + 94, + 46, + 43, + 77, + 70, + 59, + 51, + 9, + 71, + 66, + 55, + 52, + 33, + 27, + 16, + 8, + 4, + 83, + 41, + 93, + 82, + 57, + 56, + 18, + 7, + 3, + 87, + 86, + 75, + 63, + 20, + 0, + 68, + 58, + 29, + 26, + 17, + 10, + 99, + 88, + 81, + 50, + 49, + 30, + 19, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 86, + 70, + 57, + 25, + 5, + 2, + 93, + 87, + 72, + 62, + 60, + 56, + 50, + 43, + 18, + 15, + 89, + 88, + 84, + 81, + 71, + 66, + 46, + 3, + 83, + 76, + 74, + 36, + 22, + 0, + 90, + 75, + 65, + 50, + 48, + 95, + 78, + 22, + 98, + 74, + 71, + 10, + 9, + 82, + 67, + 20, + 5, + 2, + 85, + 43, + 39, + 38, + 33, + 27, + 91, + 80, + 73, + 51, + 44, + 41, + 31, + 28, + 25, + 11, + 94, + 69, + 56, + 53, + 52, + 30, + 29, + 16, + 6, + 83, + 60, + 47, + 45, + 34, + 32, + 23, + 4, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 51, + 50, + 20, + 95, + 31, + 22, + 10, + 99, + 89, + 86, + 78, + 72, + 58, + 48, + 14, + 13, + 8, + 80, + 71, + 69, + 15, + 1, + 98, + 87, + 57, + 4, + 83, + 77, + 76, + 64, + 49, + 7, + 90, + 79, + 59, + 46, + 44, + 40, + 32, + 55, + 43, + 39, + 37, + 27, + 6, + 91, + 88, + 81, + 68, + 66, + 52, + 47, + 34, + 25, + 94, + 93, + 92, + 85, + 74, + 70, + 65, + 42, + 38, + 33, + 24, + 17, + 16, + 12, + 99, + 65, + 7, + 92, + 74, + 62, + 25, + 23, + 16, + 5, + 98, + 87, + 73, + 29, + 26, + 90, + 84, + 82, + 75, + 69, + 30, + 22, + 13, + 4, + 0, + 85, + 81, + 38, + 37, + 27, + 89, + 78, + 66, + 60, + 55, + 54, + 52, + 45, + 43, + 21, + 6, + 3, + 94, + 93, + 86, + 48, + 47, + 41, + 39, + 34, + 33, + 24, + 15, + 12, + 11, + 51, + 48, + 14, + 52, + 28, + 53, + 80, + 60, + 98, + 71, + 47, + 27, + 10, + 82, + 67, + 20, + 5, + 2, + 83, + 70, + 58, + 24, + 17, + 16, + 15, + 9, + 91, + 88, + 77, + 61, + 50, + 22, + 21, + 11, + 93, + 76, + 69, + 63, + 45, + 41, + 23, + 92, + 90, + 79, + 74, + 46, + 44, + 43, + 38, + 32, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 88, + 87, + 67, + 65, + 50, + 10, + 5, + 85, + 74, + 9, + 70, + 32, + 18, + 78, + 35, + 19, + 76, + 63, + 59, + 54, + 40, + 82, + 69, + 60, + 4, + 99, + 90, + 79, + 3, + 80, + 73, + 66, + 53, + 51, + 44, + 37, + 30, + 23, + 16, + 6, + 0, + 75, + 31, + 25, + 98, + 84, + 83, + 77, + 46, + 29, + 22, + 14, + 13, + 7, + 94, + 93, + 86, + 48, + 47, + 39, + 34, + 33, + 24, + 15, + 12, + 11, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 80, + 69, + 27, + 1, + 81, + 79, + 77, + 76, + 49, + 44, + 7, + 94, + 93, + 85, + 74, + 38, + 33, + 24, + 12, + 75, + 72, + 70, + 65, + 47, + 25, + 16, + 15, + 3, + 83, + 71, + 64, + 59, + 34, + 29, + 23, + 21, + 10, + 5, + 4, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 51, + 24, + 97, + 95, + 94, + 76, + 65, + 35, + 30, + 86, + 70, + 25, + 88, + 53, + 69, + 20, + 93, + 72, + 56, + 50, + 36, + 18, + 96, + 87, + 82, + 67, + 5, + 90, + 79, + 74, + 59, + 44, + 40, + 32, + 85, + 81, + 38, + 37, + 33, + 27, + 89, + 78, + 66, + 60, + 55, + 54, + 47, + 39, + 21, + 11, + 6, + 3, + 98, + 84, + 83, + 77, + 48, + 46, + 29, + 22, + 15, + 14, + 13, + 7, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 70, + 69, + 60, + 5, + 99, + 85, + 20, + 17, + 15, + 96, + 89, + 71, + 55, + 1, + 83, + 77, + 76, + 64, + 49, + 47, + 42, + 7, + 90, + 81, + 79, + 59, + 46, + 43, + 40, + 38, + 32, + 91, + 80, + 73, + 66, + 53, + 51, + 41, + 37, + 31, + 30, + 28, + 25, + 23, + 16, + 11, + 6, + 94, + 92, + 87, + 82, + 75, + 74, + 58, + 54, + 45, + 44, + 33, + 26, + 14, + 0, + 99, + 85, + 31, + 30, + 20, + 93, + 76, + 69, + 63, + 59, + 40, + 89, + 66, + 55, + 39, + 21, + 6, + 70, + 65, + 25, + 16, + 87, + 82, + 75, + 74, + 54, + 44, + 33, + 0, + 98, + 84, + 77, + 48, + 46, + 29, + 22, + 15, + 14, + 13, + 7, + 94, + 79, + 78, + 11, + 83, + 72, + 60, + 47, + 37, + 34, + 32, + 23, + 4, + 3, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 95, + 94, + 65, + 57, + 35, + 82, + 60, + 28, + 24, + 21, + 10, + 86, + 70, + 64, + 58, + 55, + 52, + 8, + 89, + 88, + 71, + 36, + 93, + 76, + 69, + 63, + 54, + 23, + 92, + 81, + 74, + 59, + 44, + 40, + 38, + 97, + 87, + 72, + 53, + 47, + 32, + 16, + 1, + 0, + 99, + 90, + 79, + 68, + 31, + 30, + 3, + 78, + 66, + 25, + 20, + 98, + 84, + 83, + 77, + 62, + 48, + 46, + 45, + 43, + 41, + 29, + 22, + 17, + 15, + 14, + 13, + 7, + 99, + 92, + 85, + 20, + 73, + 29, + 26, + 98, + 74, + 71, + 40, + 27, + 9, + 59, + 28, + 10, + 5, + 69, + 58, + 51, + 22, + 18, + 2, + 95, + 84, + 30, + 13, + 77, + 76, + 64, + 49, + 44, + 7, + 91, + 88, + 81, + 68, + 38, + 97, + 87, + 79, + 53, + 46, + 31, + 17, + 1, + 0, + 89, + 78, + 66, + 55, + 54, + 52, + 43, + 21, + 6, + 75, + 70, + 65, + 62, + 42, + 25, + 16, + 94, + 93, + 86, + 48, + 41, + 39, + 33, + 24, + 15, + 12, + 11, + 83, + 72, + 60, + 47, + 45, + 37, + 34, + 32, + 23, + 4, + 3, + 59, + 40, + 20, + 87, + 37, + 5, + 82, + 89, + 64, + 52, + 38, + 16, + 10, + 8, + 70, + 69, + 51, + 32, + 18, + 91, + 57, + 2, + 79, + 68, + 66, + 3, + 67, + 56, + 55, + 27, + 26, + 75, + 58, + 25, + 99, + 88, + 81, + 50, + 49, + 30, + 19, + 98, + 84, + 83, + 77, + 62, + 46, + 45, + 43, + 29, + 22, + 17, + 14, + 13, + 7, + 94, + 93, + 86, + 47, + 41, + 39, + 34, + 33, + 24, + 12, + 11, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 15, + 9, + 97, + 82, + 73, + 2, + 74, + 32, + 96, + 71, + 33, + 28, + 90, + 22, + 95, + 70, + 65, + 21, + 13, + 11, + 6, + 4, + 83, + 79, + 76, + 47, + 44, + 42, + 38, + 7, + 86, + 20, + 99, + 88, + 50, + 48, + 35, + 30, + 19, + 98, + 93, + 77, + 68, + 64, + 29, + 16, + 14, + 12, + 8, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 40, + 37, + 18, + 3, + 1, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 98, + 59, + 51, + 38, + 24, + 20, + 94, + 86, + 57, + 31, + 28, + 75, + 41, + 37, + 2, + 82, + 64, + 34, + 7, + 5, + 93, + 87, + 83, + 72, + 62, + 60, + 43, + 36, + 18, + 15, + 97, + 76, + 67, + 56, + 53, + 14, + 12, + 78, + 71, + 66, + 65, + 55, + 52, + 33, + 27, + 16, + 8, + 4, + 0, + 91, + 90, + 77, + 63, + 61, + 40, + 22, + 21, + 11, + 3, + 68, + 58, + 29, + 26, + 17, + 10, + 99, + 88, + 81, + 50, + 49, + 48, + 35, + 30, + 19, + 1, + 57, + 50, + 43, + 40, + 38, + 24, + 20, + 14, + 90, + 97, + 82, + 33, + 13, + 4, + 86, + 68, + 60, + 35, + 9, + 56, + 10, + 8, + 70, + 69, + 58, + 48, + 47, + 32, + 22, + 18, + 2, + 96, + 89, + 76, + 74, + 71, + 55, + 1, + 98, + 87, + 83, + 78, + 77, + 72, + 67, + 64, + 59, + 73, + 66, + 53, + 44, + 41, + 37, + 30, + 28, + 25, + 23, + 16, + 11, + 6, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 84, + 83, + 76, + 40, + 24, + 10, + 86, + 77, + 70, + 64, + 48, + 46, + 14, + 13, + 80, + 15, + 99, + 79, + 22, + 9, + 71, + 65, + 50, + 35, + 27, + 8, + 4, + 0, + 88, + 81, + 38, + 34, + 25, + 89, + 78, + 66, + 54, + 47, + 39, + 21, + 11, + 3, + 94, + 87, + 69, + 53, + 37, + 30, + 29, + 16, + 6, + 1, + 82, + 72, + 60, + 56, + 55, + 33, + 31, + 5, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 88, + 84, + 43, + 40, + 3, + 59, + 55, + 54, + 2, + 77, + 76, + 67, + 58, + 50, + 27, + 14, + 12, + 79, + 72, + 62, + 47, + 46, + 32, + 17, + 91, + 80, + 73, + 66, + 51, + 44, + 41, + 31, + 28, + 25, + 23, + 11, + 0, + 99, + 97, + 81, + 64, + 33, + 26, + 15, + 9, + 94, + 87, + 69, + 56, + 53, + 52, + 37, + 30, + 29, + 16, + 6, + 1, + 99, + 91, + 62, + 7, + 88, + 20, + 5, + 53, + 2, + 90, + 67, + 31, + 22, + 12, + 93, + 76, + 69, + 63, + 46, + 41, + 23, + 89, + 78, + 60, + 52, + 47, + 43, + 39, + 21, + 11, + 6, + 94, + 92, + 82, + 75, + 74, + 58, + 45, + 44, + 33, + 26, + 14, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 62, + 7, + 99, + 86, + 64, + 46, + 14, + 53, + 2, + 91, + 83, + 28, + 68, + 50, + 35, + 16, + 8, + 95, + 70, + 65, + 30, + 13, + 12, + 4, + 96, + 76, + 74, + 71, + 51, + 44, + 23, + 85, + 38, + 88, + 77, + 67, + 48, + 29, + 27, + 26, + 89, + 78, + 47, + 45, + 43, + 39, + 21, + 11, + 6, + 82, + 60, + 58, + 56, + 52, + 33, + 31, + 5, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 95, + 86, + 85, + 80, + 74, + 89, + 65, + 34, + 21, + 19, + 83, + 62, + 43, + 36, + 51, + 11, + 10, + 8, + 76, + 50, + 14, + 12, + 91, + 2, + 93, + 75, + 57, + 35, + 18, + 7, + 3, + 0, + 88, + 77, + 67, + 48, + 27, + 99, + 97, + 81, + 64, + 26, + 15, + 9, + 94, + 87, + 69, + 53, + 37, + 30, + 29, + 16, + 6, + 1, + 82, + 72, + 60, + 58, + 56, + 55, + 52, + 33, + 31, + 5, + 51, + 24, + 95, + 65, + 46, + 30, + 94, + 50, + 31, + 70, + 36, + 25, + 22, + 79, + 99, + 88, + 64, + 34, + 98, + 74, + 38, + 32, + 4, + 48, + 83, + 78, + 19, + 93, + 82, + 75, + 56, + 35, + 7, + 86, + 85, + 76, + 69, + 20, + 16, + 14, + 5, + 87, + 84, + 81, + 72, + 66, + 59, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 90, + 85, + 66, + 99, + 86, + 78, + 64, + 46, + 38, + 13, + 8, + 65, + 61, + 4, + 83, + 81, + 40, + 23, + 16, + 15, + 9, + 77, + 76, + 67, + 53, + 27, + 70, + 69, + 51, + 47, + 32, + 98, + 97, + 89, + 73, + 30, + 18, + 7, + 3, + 50, + 35, + 10, + 24, + 21, + 12, + 6, + 48, + 29, + 25, + 22, + 94, + 87, + 75, + 74, + 54, + 44, + 14, + 0, + 82, + 72, + 60, + 56, + 55, + 33, + 31, + 5, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 50, + 48, + 24, + 20, + 97, + 82, + 73, + 33, + 13, + 11, + 86, + 70, + 60, + 35, + 30, + 9, + 88, + 47, + 17, + 15, + 6, + 53, + 2, + 76, + 69, + 45, + 41, + 92, + 90, + 79, + 74, + 46, + 44, + 43, + 38, + 32, + 78, + 67, + 63, + 51, + 28, + 83, + 71, + 42, + 34, + 23, + 21, + 10, + 5, + 4, + 98, + 93, + 77, + 68, + 64, + 29, + 16, + 14, + 12, + 8, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 74, + 46, + 28, + 24, + 10, + 40, + 44, + 70, + 68, + 59, + 51, + 93, + 87, + 62, + 50, + 36, + 86, + 17, + 16, + 9, + 94, + 25, + 20, + 2, + 84, + 75, + 69, + 41, + 13, + 98, + 92, + 30, + 22, + 18, + 7, + 0, + 88, + 81, + 77, + 67, + 29, + 27, + 26, + 89, + 66, + 54, + 43, + 39, + 21, + 11, + 6, + 82, + 58, + 56, + 55, + 52, + 33, + 5, + 83, + 47, + 45, + 37, + 34, + 32, + 23, + 4, + 3, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 82, + 73, + 86, + 19, + 2, + 89, + 83, + 65, + 58, + 30, + 12, + 7, + 4, + 90, + 88, + 77, + 50, + 40, + 22, + 21, + 11, + 3, + 99, + 87, + 76, + 74, + 72, + 28, + 26, + 24, + 20, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 74, + 39, + 24, + 67, + 55, + 54, + 21, + 99, + 93, + 60, + 56, + 50, + 36, + 18, + 89, + 30, + 12, + 9, + 97, + 87, + 79, + 66, + 53, + 32, + 1, + 72, + 70, + 65, + 47, + 25, + 23, + 16, + 4, + 3, + 98, + 84, + 83, + 77, + 48, + 46, + 29, + 22, + 15, + 14, + 13, + 7, + 92, + 68, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 19, + 2, + 90, + 88, + 50, + 22, + 21, + 11, + 3, + 93, + 76, + 69, + 54, + 46, + 45, + 41, + 40, + 23, + 86, + 35, + 29, + 20, + 98, + 87, + 83, + 78, + 77, + 72, + 67, + 64, + 59, + 28, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 96, + 90, + 73, + 50, + 89, + 86, + 70, + 58, + 55, + 52, + 48, + 46, + 13, + 88, + 82, + 74, + 57, + 18, + 79, + 76, + 47, + 44, + 38, + 7, + 78, + 72, + 67, + 63, + 51, + 28, + 83, + 71, + 42, + 34, + 23, + 21, + 10, + 5, + 4, + 99, + 97, + 81, + 56, + 53, + 33, + 26, + 15, + 9, + 98, + 93, + 87, + 77, + 68, + 66, + 64, + 59, + 49, + 29, + 16, + 14, + 12, + 8, + 1, + 0, + 87, + 86, + 39, + 57, + 46, + 43, + 41, + 37, + 10, + 5, + 99, + 67, + 56, + 34, + 19, + 91, + 89, + 83, + 61, + 58, + 7, + 79, + 22, + 9, + 2, + 71, + 68, + 66, + 52, + 50, + 27, + 8, + 95, + 88, + 84, + 55, + 49, + 30, + 21, + 13, + 11, + 6, + 0, + 94, + 93, + 92, + 74, + 38, + 33, + 24, + 17, + 12, + 75, + 70, + 62, + 47, + 45, + 42, + 25, + 23, + 16, + 4, + 3, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 75, + 67, + 5, + 2, + 95, + 22, + 10, + 94, + 85, + 74, + 58, + 65, + 50, + 35, + 27, + 4, + 76, + 71, + 36, + 88, + 38, + 34, + 33, + 97, + 62, + 32, + 99, + 90, + 79, + 48, + 17, + 13, + 46, + 20, + 91, + 80, + 73, + 53, + 51, + 44, + 41, + 31, + 30, + 28, + 25, + 23, + 89, + 78, + 60, + 52, + 47, + 45, + 43, + 39, + 21, + 11, + 6, + 98, + 93, + 77, + 68, + 64, + 29, + 16, + 14, + 12, + 8, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 75, + 66, + 41, + 11, + 10, + 91, + 62, + 84, + 69, + 40, + 37, + 20, + 3, + 99, + 89, + 65, + 34, + 21, + 19, + 9, + 7, + 2, + 90, + 74, + 54, + 31, + 22, + 97, + 76, + 58, + 53, + 50, + 14, + 12, + 96, + 82, + 68, + 43, + 5, + 98, + 87, + 83, + 78, + 72, + 64, + 63, + 59, + 51, + 28, + 88, + 81, + 77, + 67, + 60, + 56, + 55, + 48, + 29, + 27, + 26, + 97, + 86, + 70, + 60, + 51, + 9, + 69, + 21, + 15, + 6, + 78, + 71, + 65, + 55, + 27, + 4, + 96, + 82, + 67, + 5, + 88, + 81, + 47, + 38, + 34, + 33, + 25, + 99, + 90, + 79, + 48, + 46, + 31, + 30, + 13, + 3, + 50, + 35, + 10, + 98, + 93, + 87, + 77, + 66, + 64, + 59, + 49, + 29, + 16, + 14, + 12, + 8, + 1, + 0, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 97, + 35, + 77, + 73, + 44, + 80, + 71, + 42, + 38, + 27, + 88, + 79, + 68, + 21, + 17, + 15, + 10, + 67, + 43, + 70, + 58, + 51, + 48, + 47, + 32, + 31, + 2, + 93, + 63, + 59, + 54, + 46, + 45, + 40, + 23, + 90, + 84, + 82, + 75, + 60, + 41, + 39, + 22, + 13, + 4, + 0, + 86, + 85, + 76, + 57, + 28, + 20, + 18, + 14, + 5, + 3, + 94, + 87, + 69, + 56, + 53, + 52, + 37, + 30, + 29, + 16, + 6, + 1, + 98, + 80, + 57, + 43, + 36, + 73, + 44, + 99, + 89, + 78, + 64, + 52, + 46, + 14, + 8, + 86, + 77, + 68, + 60, + 59, + 35, + 83, + 81, + 40, + 69, + 58, + 51, + 48, + 41, + 31, + 18, + 2, + 95, + 88, + 84, + 55, + 49, + 21, + 13, + 11, + 6, + 0, + 79, + 32, + 30, + 22, + 9, + 5, + 94, + 93, + 92, + 85, + 74, + 38, + 33, + 24, + 17, + 12, + 75, + 72, + 70, + 65, + 62, + 47, + 45, + 42, + 25, + 23, + 16, + 15, + 4, + 3, + 98, + 87, + 47, + 40, + 37, + 9, + 80, + 69, + 38, + 15, + 91, + 49, + 28, + 13, + 11, + 6, + 78, + 68, + 65, + 52, + 50, + 35, + 33, + 27, + 16, + 8, + 0, + 88, + 84, + 81, + 66, + 46, + 36, + 3, + 96, + 89, + 77, + 76, + 74, + 55, + 51, + 44, + 1, + 83, + 71, + 64, + 59, + 42, + 34, + 29, + 23, + 21, + 10, + 5, + 4, + 86, + 38, + 14, + 13, + 8, + 50, + 43, + 36, + 91, + 89, + 30, + 12, + 93, + 7, + 79, + 53, + 46, + 17, + 98, + 77, + 67, + 64, + 63, + 51, + 99, + 94, + 74, + 61, + 28, + 26, + 24, + 20, + 75, + 70, + 62, + 42, + 25, + 16, + 82, + 58, + 56, + 52, + 33, + 5, + 83, + 47, + 45, + 34, + 32, + 23, + 4, + 87, + 84, + 81, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 0, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 99, + 64, + 88, + 86, + 83, + 59, + 49, + 4, + 77, + 70, + 69, + 82, + 61, + 5, + 87, + 47, + 39, + 34, + 29, + 24, + 98, + 92, + 89, + 58, + 33, + 18, + 7, + 66, + 53, + 51, + 44, + 41, + 37, + 28, + 25, + 23, + 16, + 11, + 6, + 0, + 96, + 95, + 91, + 74, + 30, + 26, + 22, + 13, + 3, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 62, + 39, + 25, + 5, + 11, + 78, + 66, + 60, + 41, + 86, + 56, + 2, + 47, + 37, + 27, + 10, + 9, + 88, + 64, + 34, + 18, + 7, + 98, + 57, + 49, + 4, + 67, + 31, + 89, + 77, + 71, + 55, + 51, + 23, + 1, + 90, + 81, + 79, + 59, + 46, + 43, + 40, + 32, + 83, + 36, + 99, + 76, + 72, + 61, + 28, + 20, + 93, + 85, + 70, + 65, + 42, + 38, + 24, + 17, + 16, + 12, + 96, + 95, + 91, + 80, + 73, + 30, + 22, + 15, + 13, + 3, + 94, + 92, + 87, + 82, + 75, + 74, + 58, + 54, + 45, + 44, + 33, + 26, + 14, + 0, + 67, + 66, + 50, + 37, + 10, + 99, + 17, + 2, + 90, + 84, + 69, + 60, + 39, + 13, + 93, + 57, + 56, + 18, + 86, + 35, + 20, + 48, + 41, + 29, + 22, + 72, + 70, + 65, + 47, + 42, + 25, + 23, + 16, + 15, + 4, + 3, + 92, + 87, + 82, + 74, + 58, + 54, + 45, + 44, + 33, + 26, + 14, + 81, + 79, + 78, + 30, + 21, + 11, + 7, + 1, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 95, + 43, + 30, + 17, + 52, + 21, + 10, + 91, + 82, + 67, + 58, + 56, + 53, + 50, + 27, + 12, + 88, + 84, + 66, + 96, + 89, + 71, + 55, + 51, + 81, + 79, + 77, + 64, + 49, + 47, + 44, + 42, + 38, + 7, + 93, + 63, + 59, + 54, + 46, + 45, + 41, + 40, + 23, + 83, + 36, + 22, + 0, + 99, + 94, + 87, + 74, + 61, + 26, + 24, + 86, + 69, + 57, + 28, + 20, + 18, + 16, + 14, + 5, + 3, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 18, + 2, + 73, + 69, + 5, + 99, + 52, + 86, + 70, + 35, + 30, + 9, + 97, + 58, + 53, + 91, + 90, + 61, + 50, + 40, + 21, + 11, + 3, + 96, + 89, + 74, + 71, + 23, + 79, + 76, + 47, + 44, + 42, + 38, + 78, + 72, + 63, + 51, + 28, + 88, + 81, + 67, + 60, + 56, + 55, + 27, + 26, + 84, + 83, + 62, + 48, + 46, + 45, + 43, + 41, + 22, + 17, + 15, + 13, + 7, + 98, + 93, + 87, + 77, + 68, + 66, + 64, + 59, + 49, + 29, + 16, + 14, + 12, + 8, + 1, + 0, + 96, + 88, + 17, + 95, + 91, + 74, + 37, + 22, + 34, + 5, + 82, + 26, + 10, + 99, + 86, + 70, + 58, + 38, + 14, + 13, + 71, + 68, + 50, + 33, + 27, + 16, + 8, + 4, + 0, + 57, + 41, + 19, + 98, + 87, + 83, + 77, + 67, + 64, + 63, + 59, + 51, + 28, + 46, + 25, + 20, + 89, + 66, + 55, + 54, + 52, + 47, + 43, + 39, + 6, + 94, + 45, + 3, + 81, + 79, + 75, + 30, + 21, + 11, + 7, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 82, + 33, + 88, + 69, + 28, + 15, + 10, + 6, + 57, + 65, + 52, + 2, + 83, + 77, + 76, + 64, + 49, + 42, + 92, + 74, + 59, + 44, + 43, + 40, + 38, + 85, + 70, + 22, + 9, + 5, + 97, + 87, + 72, + 62, + 53, + 47, + 32, + 16, + 0, + 99, + 90, + 68, + 66, + 48, + 46, + 41, + 31, + 17, + 13, + 94, + 45, + 3, + 81, + 79, + 78, + 75, + 30, + 21, + 11, + 7, + 1, + 98, + 93, + 70, + 33, + 9, + 40, + 82, + 86, + 81, + 56, + 2, + 71, + 69, + 52, + 42, + 38, + 27, + 66, + 53, + 44, + 41, + 37, + 25, + 23, + 16, + 11, + 6, + 99, + 87, + 28, + 24, + 20, + 96, + 95, + 74, + 30, + 26, + 22, + 13, + 3, + 97, + 90, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 15, + 1, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 31, + 22, + 4, + 82, + 10, + 95, + 86, + 80, + 2, + 70, + 58, + 24, + 23, + 17, + 16, + 89, + 71, + 36, + 83, + 76, + 42, + 92, + 90, + 74, + 46, + 44, + 32, + 85, + 43, + 39, + 6, + 91, + 68, + 52, + 47, + 38, + 34, + 25, + 77, + 67, + 60, + 29, + 27, + 88, + 50, + 48, + 35, + 19, + 99, + 97, + 64, + 56, + 53, + 33, + 26, + 15, + 9, + 79, + 78, + 75, + 30, + 21, + 11, + 7, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 46, + 24, + 21, + 97, + 59, + 51, + 49, + 11, + 6, + 50, + 79, + 48, + 32, + 81, + 78, + 15, + 10, + 91, + 80, + 76, + 73, + 61, + 28, + 40, + 37, + 20, + 2, + 99, + 88, + 64, + 34, + 98, + 86, + 83, + 23, + 17, + 16, + 9, + 96, + 68, + 67, + 43, + 90, + 84, + 69, + 41, + 39, + 30, + 22, + 13, + 4, + 93, + 57, + 35, + 18, + 7, + 3, + 1, + 94, + 92, + 87, + 75, + 74, + 54, + 45, + 44, + 26, + 14, + 0, + 82, + 72, + 60, + 58, + 56, + 55, + 52, + 33, + 31, + 5, + 52, + 73, + 99, + 97, + 2, + 93, + 56, + 50, + 18, + 89, + 65, + 61, + 30, + 12, + 86, + 82, + 31, + 70, + 58, + 40, + 24, + 9, + 96, + 91, + 55, + 33, + 16, + 11, + 6, + 81, + 79, + 49, + 44, + 38, + 57, + 35, + 19, + 76, + 74, + 36, + 0, + 87, + 78, + 67, + 63, + 51, + 28, + 98, + 84, + 77, + 62, + 48, + 46, + 43, + 41, + 22, + 17, + 15, + 14, + 13, + 7, + 71, + 64, + 59, + 42, + 29, + 21, + 10, + 5, + 83, + 72, + 60, + 47, + 45, + 37, + 34, + 32, + 23, + 4, + 3, + 52, + 28, + 24, + 16, + 10, + 53, + 67, + 20, + 5, + 2, + 95, + 70, + 65, + 47, + 21, + 12, + 11, + 6, + 89, + 88, + 76, + 71, + 36, + 90, + 82, + 75, + 69, + 60, + 39, + 30, + 4, + 98, + 83, + 77, + 62, + 48, + 46, + 45, + 43, + 41, + 29, + 22, + 17, + 15, + 14, + 13, + 7, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 66, + 58, + 41, + 47, + 45, + 44, + 11, + 95, + 56, + 2, + 81, + 55, + 43, + 39, + 37, + 27, + 6, + 79, + 32, + 30, + 22, + 9, + 99, + 87, + 26, + 86, + 69, + 57, + 28, + 20, + 18, + 14, + 3, + 93, + 92, + 74, + 70, + 42, + 38, + 33, + 24, + 17, + 16, + 12, + 97, + 90, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 15, + 1, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 65, + 88, + 50, + 7, + 43, + 36, + 25, + 97, + 73, + 6, + 4, + 95, + 81, + 80, + 74, + 56, + 99, + 89, + 78, + 72, + 64, + 58, + 55, + 52, + 46, + 38, + 8, + 77, + 70, + 68, + 59, + 51, + 30, + 90, + 61, + 19, + 2, + 98, + 83, + 82, + 60, + 31, + 23, + 22, + 17, + 13, + 9, + 87, + 75, + 63, + 49, + 35, + 29, + 0, + 85, + 76, + 69, + 57, + 28, + 20, + 18, + 16, + 14, + 5, + 3, + 94, + 93, + 86, + 48, + 47, + 41, + 39, + 34, + 33, + 24, + 15, + 12, + 11, + 65, + 41, + 48, + 2, + 95, + 91, + 22, + 73, + 39, + 13, + 71, + 27, + 10, + 88, + 34, + 7, + 60, + 50, + 36, + 38, + 4, + 96, + 43, + 5, + 79, + 62, + 47, + 46, + 32, + 31, + 17, + 86, + 35, + 83, + 78, + 67, + 63, + 51, + 85, + 80, + 76, + 61, + 28, + 24, + 20, + 92, + 82, + 75, + 74, + 58, + 45, + 44, + 99, + 97, + 33, + 26, + 15, + 9, + 98, + 93, + 77, + 68, + 64, + 14, + 12, + 8, + 94, + 69, + 56, + 53, + 52, + 30, + 29, + 16, + 6, + 87, + 84, + 81, + 72, + 66, + 59, + 57, + 55, + 54, + 49, + 40, + 37, + 18, + 3, + 1, + 0, + 97, + 94, + 86, + 78, + 41, + 31, + 14, + 73, + 54, + 53, + 43, + 79, + 69, + 59, + 28, + 17, + 15, + 10, + 5, + 87, + 82, + 74, + 64, + 57, + 18, + 7, + 90, + 63, + 61, + 40, + 22, + 95, + 70, + 65, + 21, + 13, + 12, + 11, + 6, + 4, + 0, + 89, + 84, + 76, + 71, + 46, + 36, + 3, + 91, + 68, + 66, + 52, + 47, + 38, + 34, + 33, + 25, + 77, + 67, + 60, + 56, + 55, + 29, + 27, + 26, + 99, + 88, + 81, + 50, + 49, + 48, + 35, + 30, + 19, + 1, + 86, + 70, + 64, + 48, + 38, + 16, + 14, + 13, + 8, + 99, + 67, + 56, + 34, + 19, + 9, + 2, + 91, + 83, + 72, + 65, + 62, + 61, + 12, + 4, + 88, + 84, + 81, + 46, + 36, + 96, + 77, + 76, + 74, + 71, + 51, + 44, + 23, + 1, + 98, + 97, + 92, + 73, + 58, + 33, + 30, + 22, + 18, + 7, + 0, + 89, + 78, + 66, + 60, + 55, + 54, + 52, + 47, + 45, + 43, + 39, + 21, + 11, + 6, + 3, + 98, + 96, + 64, + 51, + 33, + 37, + 10, + 26, + 94, + 58, + 86, + 19, + 5, + 2, + 67, + 54, + 12, + 91, + 88, + 77, + 63, + 61, + 50, + 49, + 21, + 11, + 84, + 82, + 75, + 69, + 39, + 22, + 4, + 0, + 92, + 81, + 74, + 59, + 44, + 43, + 40, + 38, + 32, + 99, + 79, + 68, + 66, + 46, + 41, + 30, + 17, + 13, + 3, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 97, + 18, + 99, + 67, + 54, + 87, + 78, + 10, + 82, + 76, + 89, + 72, + 65, + 12, + 7, + 4, + 83, + 71, + 55, + 90, + 77, + 50, + 40, + 21, + 56, + 48, + 88, + 81, + 47, + 38, + 33, + 66, + 53, + 44, + 37, + 25, + 23, + 16, + 11, + 6, + 96, + 95, + 74, + 73, + 30, + 22, + 15, + 13, + 3, + 92, + 68, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 39, + 25, + 23, + 5, + 99, + 47, + 20, + 15, + 11, + 90, + 81, + 79, + 59, + 46, + 40, + 32, + 98, + 97, + 89, + 73, + 60, + 30, + 22, + 18, + 7, + 3, + 93, + 85, + 70, + 65, + 38, + 24, + 16, + 12, + 94, + 87, + 82, + 75, + 74, + 54, + 44, + 33, + 14, + 0, + 92, + 91, + 68, + 62, + 58, + 57, + 52, + 45, + 43, + 42, + 41, + 28, + 26, + 17, + 2, + 99, + 80, + 13, + 9, + 83, + 62, + 60, + 50, + 43, + 36, + 76, + 69, + 63, + 54, + 46, + 45, + 40, + 23, + 82, + 75, + 72, + 57, + 56, + 35, + 18, + 7, + 3, + 92, + 85, + 74, + 70, + 65, + 42, + 38, + 17, + 94, + 86, + 48, + 47, + 41, + 39, + 34, + 33, + 24, + 15, + 11, + 98, + 93, + 87, + 77, + 68, + 66, + 64, + 59, + 49, + 29, + 16, + 14, + 12, + 8, + 1, + 0, + 95, + 46, + 43, + 35, + 88, + 57, + 50, + 7, + 90, + 66, + 60, + 25, + 21, + 2, + 99, + 76, + 72, + 28, + 20, + 70, + 65, + 42, + 38, + 17, + 92, + 82, + 74, + 58, + 54, + 44, + 26, + 14, + 93, + 86, + 48, + 47, + 41, + 39, + 33, + 24, + 15, + 12, + 79, + 78, + 45, + 11, + 3, + 87, + 69, + 56, + 53, + 52, + 37, + 30, + 29, + 16, + 6, + 1, + 94, + 91, + 85, + 80, + 75, + 63, + 62, + 61, + 51, + 49, + 34, + 31, + 5, + 0, + 94, + 76, + 57, + 46, + 43, + 35, + 17, + 7, + 87, + 78, + 66, + 38, + 37, + 33, + 31, + 10, + 86, + 85, + 81, + 56, + 2, + 88, + 84, + 70, + 65, + 55, + 49, + 47, + 21, + 12, + 11, + 6, + 4, + 0, + 96, + 95, + 91, + 80, + 74, + 73, + 30, + 26, + 22, + 15, + 13, + 3, + 98, + 90, + 78, + 64, + 0, + 83, + 49, + 33, + 28, + 16, + 11, + 6, + 89, + 77, + 76, + 71, + 55, + 51, + 44, + 23, + 1, + 87, + 82, + 68, + 67, + 43, + 5, + 96, + 95, + 91, + 80, + 74, + 73, + 30, + 26, + 22, + 15, + 13, + 3, + 88, + 69, + 68, + 43, + 91, + 86, + 82, + 59, + 51, + 49, + 13, + 11, + 6, + 4, + 83, + 34, + 21, + 19, + 2, + 77, + 67, + 50, + 27, + 14, + 12, + 98, + 92, + 89, + 58, + 30, + 22, + 18, + 7, + 3, + 79, + 66, + 62, + 47, + 46, + 32, + 17, + 16, + 0, + 99, + 87, + 81, + 64, + 56, + 53, + 33, + 26, + 9, + 97, + 90, + 85, + 80, + 78, + 76, + 73, + 72, + 65, + 60, + 48, + 35, + 31, + 15, + 1, + 50, + 20, + 96, + 90, + 99, + 80, + 70, + 39, + 34, + 26, + 24, + 6, + 71, + 47, + 40, + 37, + 27, + 10, + 86, + 82, + 31, + 23, + 9, + 74, + 57, + 38, + 32, + 4, + 97, + 92, + 89, + 73, + 60, + 58, + 33, + 30, + 18, + 3, + 78, + 72, + 67, + 63, + 51, + 28, + 84, + 83, + 62, + 48, + 46, + 45, + 43, + 41, + 22, + 17, + 15, + 13, + 7, + 98, + 93, + 87, + 77, + 68, + 66, + 64, + 59, + 49, + 29, + 16, + 14, + 12, + 8, + 1, + 0, + 73, + 39, + 98, + 93, + 91, + 54, + 92, + 75, + 47, + 45, + 44, + 11, + 86, + 78, + 77, + 70, + 58, + 55, + 38, + 16, + 14, + 8, + 62, + 52, + 89, + 83, + 67, + 65, + 21, + 2, + 82, + 57, + 34, + 18, + 7, + 90, + 79, + 68, + 66, + 46, + 41, + 31, + 17, + 13, + 3, + 94, + 85, + 80, + 76, + 74, + 72, + 61, + 28, + 24, + 20, + 88, + 50, + 49, + 48, + 35, + 30, + 19, + 1, + 99, + 97, + 87, + 81, + 64, + 56, + 53, + 33, + 26, + 15, + 9, +}; + +sparse_int_t H_cp[] = { + + 0, + 89, + 160, + 231, + 320, + 388, + 470, + 538, + 611, + 651, + 708, + 768, + 846, + 909, + 980, + 1048, + 1133, + 1220, + 1296, + 1359, + 1388, + 1444, + 1516, + 1593, + 1658, + 1717, + 1773, + 1841, + 1889, + 1962, + 2027, + 2111, + 2192, + 2242, + 2323, + 2393, + 2455, + 2485, + 2552, + 2620, + 2675, + 2741, + 2822, + 2876, + 2955, + 3016, + 3085, + 3157, + 3242, + 3323, + 3400, + 3475, + 3549, + 3624, + 3681, + 3739, + 3812, + 3876, + 3947, + 4028, + 4104, + 4186, + 4231, + 4304, + 4350, + 4414, + 4492, + 4575, + 4635, + 4704, + 4772, + 4844, + 4899, + 4979, + 5043, + 5128, + 5197, + 5276, + 5352, + 5431, + 5492, + 5558, + 5638, + 5717, + 5797, + 5860, + 5930, + 6008, + 6099, + 6174, + 6238, + 6306, + 6382, + 6441, + 6503, + 6575, + 6621, + 6660, + 6727, + 6800, + 6874, +}; + +real_t H_val[] = { + + 0.0036400623550257604, + 4.3451375820987274e-05, + 2.8154529321024527e-05, + 1.058349284017026e-06, + 1.5817505577012435e-06, + 0.00036269699602366277, + 1.5939223154984972e-06, + 1.9905781613356547e-05, + 0.006617942237573037, + 1.4703237898637284e-05, + 2.532220139804081e-05, + 2.0400045701197958e-05, + 9.786425522897559e-05, + 8.733381168004906e-06, + 0.008630783726605808, + 7.365929642574257e-05, + 5.8718839345831116e-05, + 1.1663596453736771e-05, + 0.007160597590819221, + 0.007847234151793583, + 4.799118855640533e-06, + 2.1017098271407778e-05, + 3.2854142780819036e-05, + 0.00012032027402574883, + 4.695908205301601e-05, + 3.391891618363114e-05, + 6.865839426972015e-08, + 0.00450565985570487, + 5.923465003761426e-07, + 1.6407079694044695e-06, + 1.1026494536511072e-06, + 2.0999175882370937e-06, + 0.0011110333225029594, + 1.8656782760597722e-05, + 0.00016463726515054288, + 1.9764588428937462e-05, + 7.048804349060899e-05, + 0.00016526594818091914, + 1.5739800122089514e-05, + 8.544810389600539e-05, + 0.0044510452107628835, + 0.00010202137810034909, + 3.076454718646216e-05, + 0.007042734309568557, + 0.00010528753431476505, + 0.00016056771047132448, + 3.89090190295633e-05, + 8.310218795996274e-05, + 2.6534495447257202e-05, + 0.005896520474143277, + 0.00010760530953880158, + 4.262629380572652e-05, + 3.7686390290702356e-05, + 1.0482807165536582e-05, + 8.2936366790311e-06, + 9.142508566084441e-05, + 0.0063393024704901345, + 4.2655792352873584e-05, + 0.009014740192242751, + 9.478196456125603e-05, + 0.00972144003206556, + 0.0001277688390982566, + 7.472068481635205e-05, + 1.8734155484644436e-06, + 1.5242491587519319e-05, + 7.71081508500837e-05, + 0.00010322667475459351, + 1.7857945324176098e-05, + 2.2088685428722426e-05, + 9.081164422170525e-05, + 7.412144330241568e-06, + 5.321768311467811e-05, + 8.54482043585373e-06, + 0.0019207585976825402, + 0.00011036718862435829, + 0.005713878505717975, + 0.008965663068428692, + 0.0029512563984702782, + 0.009287224138628118, + 0.008239347700691868, + 0.006329999010846514, + 0.005794533630906074, + 0.00574581527221644, + 0.0015286668560874448, + 0.0034194658432815557, + 0.007546820998713696, + 0.0020986143266744518, + 0.00848804115945128, + 1.0174228790450237, + 3.6211453017926045e-05, + 2.4723271872059743e-05, + 3.655322791892029e-05, + 1.1858073903861733e-05, + 8.138762190459502e-06, + 8.27067019911165e-06, + 8.098320768821391e-05, + 2.244436982658596e-06, + 0.0023922321366585796, + 1.6888929301382213e-05, + 4.8878825131751535e-05, + 3.366232988367765e-05, + 5.6550313371836705e-05, + 2.6958770302895138e-05, + 7.467161408604157e-05, + 5.018358904242168e-05, + 4.6357147705395986e-05, + 4.772181923265292e-06, + 4.1637468351522585e-05, + 0.005018402425556384, + 2.3102054619062538e-05, + 8.287239270239654e-05, + 1.6206885535492838e-05, + 5.422057846185583e-06, + 6.623595464622124e-05, + 7.419416670917138e-05, + 5.3873092159245e-05, + 0.009613346311948063, + 5.408312218936873e-05, + 5.264850636123655e-05, + 6.222207450410723e-05, + 2.5283835845936842e-05, + 0.00674617791236786, + 3.9709134277977404e-05, + 0.00842634005475897, + 5.0148776047508897e-05, + 6.522745373782873e-05, + 9.160651790060595e-05, + 0.00010183618537375991, + 0.0001204369410194575, + 9.45527466148835e-05, + 0.005131700163305644, + 0.00010653288579349231, + 7.014458098379015e-06, + 5.8729422882028494e-05, + 9.399386408590776e-05, + 0.0001129253805894384, + 7.645574527309935e-05, + 5.312082381498302e-05, + 2.8651042860903155e-05, + 0.00012261209406726128, + 5.263317597042702e-06, + 5.524170723711119e-05, + 5.386498799229628e-05, + 0.003258991502252713, + 0.00011036718862435829, + 0.008788743162951177, + 0.0009830902887607762, + 0.007315470196481674, + 0.006357808687633092, + 0.0027643037349795144, + 0.006085598405466598, + 0.0033801536148952, + 0.009060445131141749, + 0.009882759593724188, + 0.0006949372352616699, + 0.004220681095862514, + 0.012006271154335118, + 0.012813625909626442, + 0.00589213577782564, + 1.0096901756319723, + 1.972049328233557e-06, + 2.2433062721085766e-06, + 2.132797269703622e-06, + 1.933607075234137e-05, + 1.5324605124138993e-05, + 2.7934513576924285e-05, + 2.1276079051268394e-05, + 9.514188887823765e-06, + 6.627270386680282e-07, + 2.691506463774306e-06, + 0.0010612541856490243, + 1.1862578488334266e-06, + 1.656838550283511e-06, + 1.990227659369478e-06, + 4.558479926457905e-05, + 3.1492717831146598e-06, + 3.9331586555146806e-05, + 9.849916266201628e-06, + 1.440955553962265e-05, + 4.442344954711435e-05, + 0.0004195966818797722, + 7.092098892430295e-05, + 5.351529579156392e-05, + 0.004634066879474433, + 0.00788135828673028, + 0.0011035844870068423, + 9.108396625983994e-06, + 4.5744979932388834e-06, + 3.658505363849941e-05, + 0.00011449612249317954, + 5.367080479121616e-05, + 0.007536101314779872, + 7.932889293692498e-06, + 6.040915927635078e-05, + 3.0345710219469527e-05, + 1.5765266083114732e-05, + 0.007496747275018019, + 5.477360401773848e-05, + 0.00010740660096765256, + 4.7298225712617244e-05, + 0.007636030670880136, + 3.86650835506941e-05, + 7.339128572956441e-05, + 4.892233214493144e-05, + 8.031746833525979e-06, + 9.500151198094398e-05, + 7.891320233959729e-05, + 0.008774287957556134, + 5.454227235294692e-05, + 7.310290289575026e-06, + 0.00012240969635691026, + 7.473978611656519e-06, + 8.749361914559068e-05, + 6.094138202063724e-05, + 1.0786968122519265e-05, + 3.9008191727962326e-05, + 0.007720895238812851, + 0.009630677550983137, + 0.0008094970202235607, + 0.007513842671876183, + 0.004367331740704896, + 0.009041327173160378, + 0.009395193044154506, + 0.007106771127311314, + 0.0025027531135822763, + 0.001505445880622247, + 0.00032154997618342605, + 0.004275057037133662, + 0.0030972922175133, + 0.0019747358368568304, + 1.000396397501358, + 1.0443226802502651e-05, + 0.009743049631104774, + 3.1492717831146598e-06, + 5.433155133322079e-06, + 1.3878170459442497e-05, + 6.205293339025682e-06, + 5.326649168148768e-05, + 1.984736516522655e-05, + 0.008550548609811963, + 3.1527067534437825e-05, + 4.7248459417462044e-06, + 2.9408081782277706e-06, + 0.00010938912433855871, + 2.4213688635566925e-06, + 0.0005275661483209082, + 4.634868129524442e-05, + 4.3275702448087675e-05, + 6.787198893609816e-05, + 3.0274665047374855e-05, + 0.007790053939240377, + 5.8670941981003886e-05, + 6.37028078542803e-05, + 9.79414383924028e-05, + 1.833190249544069e-05, + 5.616434308975793e-05, + 0.004432264135737421, + 5.393172876158273e-05, + 6.101829323367727e-05, + 6.442624923415236e-05, + 7.583882756894263e-05, + 2.8292786126268883e-06, + 0.00012382073634337326, + 3.194862700383684e-06, + 0.0012815068139153654, + 9.262511050021996e-06, + 5.124321109448016e-05, + 7.419336729443077e-07, + 0.005738400102416387, + 2.6463650851974373e-05, + 3.749231695173124e-05, + 0.00011307173467956233, + 5.276511670132932e-05, + 0.00010015603807410011, + 6.944150722416447e-05, + 3.819063871128943e-06, + 2.6087163904935546e-05, + 6.771638314171035e-05, + 5.4053340630327065e-05, + 2.3321140638181313e-05, + 0.008315295754634805, + 7.755706793911599e-05, + 7.216524130910202e-05, + 0.00010527569821340091, + 6.648775300564829e-05, + 0.00013430194690215467, + 0.00019408068036398684, + 0.006586798633828459, + 6.965275646704858e-05, + 0.00016966285388558808, + 0.007973859332807587, + 9.513935743872953e-05, + 1.1173546844994064e-05, + 4.5523933983688476e-05, + 1.9266161726239038e-05, + 0.0020350525021958785, + 0.00014087934069183532, + 0.00694616003156225, + 0.00010411803164345695, + 0.00011889205758591477, + 3.8513269850336475e-05, + 6.807367336737874e-05, + 0.00013379945568627112, + 0.008665013304399156, + 0.0023031022140271094, + 0.002235762253920633, + 0.004679745180711632, + 0.008164860638231877, + 0.009496872318820002, + 0.007281113407364993, + 0.006620078112091664, + 0.009902295270012016, + 0.00890671898717624, + 0.005873673790252434, + 0.0017204913863231868, + 0.00629538472814543, + 0.007908396123318565, + 1.005946206360871, + 0.003258991502252713, + 0.0019207585976825402, + 2.162203723537085e-05, + 1.8853793968401794e-05, + 4.573845607783466e-06, + 8.17597435056736e-06, + 4.654126826922435e-07, + 8.645709649879834e-07, + 1.3866946691552715e-05, + 8.760010546227632e-06, + 0.0020676055741927837, + 1.66515736182694e-05, + 1.0116095375722495e-05, + 1.3460548600472357e-05, + 0.008441282349888507, + 8.565419016550504e-05, + 0.002284715759170237, + 2.983059461560402e-05, + 8.218202439742403e-05, + 3.453785158693196e-05, + 4.628791292582566e-05, + 1.9429607794752888e-05, + 0.004455228636882102, + 3.5838112986402865e-05, + 8.780755167910766e-05, + 1.9579120926910124e-05, + 2.3726769872314397e-05, + 9.364696675739478e-05, + 5.905432437917108e-05, + 3.191452729950644e-05, + 5.7954976624182934e-05, + 7.705892301173354e-05, + 2.1432104694935766e-05, + 3.1968056060833624e-05, + 2.058697160405831e-05, + 6.841599600088951e-05, + 1.2827787409715243e-05, + 3.2874580211676028e-06, + 2.134225602766022e-05, + 0.003224498097106496, + 9.73683053803303e-05, + 3.398949873757143e-05, + 4.5865172442288695e-05, + 5.8718839345831116e-05, + 5.646706491604017e-05, + 2.3104780332391485e-05, + 5.109858086914298e-05, + 3.781020879821394e-05, + 8.714215975638049e-06, + 0.003131018813857472, + 2.534535230410747e-05, + 7.044948047777424e-05, + 2.0879152531223147e-05, + 4.611385404600837e-05, + 7.846915829260045e-05, + 2.6713893738560452e-06, + 6.289543888777127e-05, + 0.006843301367477539, + 2.8884471967897036e-05, + 0.009827093921226878, + 0.0002095266612916967, + 0.004449428258901354, + 0.015334495722877418, + 0.0067128941927253345, + 0.005189010470211977, + 0.004507380604466488, + 0.00790089919579962, + 0.0034911392760475354, + 1.0002111134045482, + 0.008665013304399156, + 0.0037464921901482874, + 1.9459193714956095e-05, + 3.4937391624894854e-05, + 2.3477716972446635e-05, + 3.1326321629322294e-05, + 3.3405059603801925e-05, + 1.7541023247471673e-05, + 2.2413973752318735e-05, + 4.9736078040864996e-05, + 2.302150539269388e-05, + 5.2465533659413894e-05, + 2.8838670323751205e-05, + 5.2996539510238614e-05, + 8.971261774095474e-05, + 0.008978981047742522, + 4.700870048947649e-05, + 9.822974678059222e-05, + 5.425778203040552e-05, + 1.9888207898990585e-05, + 5.988673040886737e-05, + 1.3264134839712206e-05, + 2.306744948090414e-05, + 2.2085715213219096e-05, + 3.8701093554956196e-05, + 9.824640203003823e-05, + 0.007560260915174101, + 4.783186967344497e-06, + 0.00011449612249317954, + 2.7597202625547482e-05, + 2.799583849796062e-05, + 0.007388783088336085, + 0.006358011194064177, + 0.004193107812289965, + 7.929394171683288e-05, + 0.00016616202787009891, + 0.009362403878072032, + 5.5021419861820435e-05, + 2.6194607769450517e-05, + 4.88493666609293e-05, + 3.8313342227535594e-05, + 0.008601017543635006, + 0.00481031758485341, + 3.3583569172584694e-05, + 3.469139439790145e-05, + 2.1816080408894437e-05, + 5.0340873321860937e-05, + 0.001682110924335416, + 3.120558757653484e-05, + 1.2767150636099418e-05, + 0.00010015603807410011, + 5.311863651417748e-05, + 3.5510223520742805e-05, + 0.00011032302460473533, + 8.058865452382106e-05, + 3.6018542032361736e-05, + 1.6512283763228777e-06, + 7.128019767737525e-05, + 4.413969271119868e-05, + 0.004272437696748578, + 2.8884471967897036e-05, + 0.010279256328935539, + 0.005184694759674665, + 0.0008344352091233543, + 0.009543969020334744, + 0.004544223191595411, + 0.001842198992963593, + 0.006026699609445051, + 0.006615910659592654, + 4.679176487596852e-05, + 0.00012730643180779922, + 9.682822996583617e-05, + 8.369797878943574e-05, + 0.00012168058179273745, + 0.009918597864277588, + 6.717291162328866e-05, + 0.00016112846705804528, + 1.2083727420730855e-05, + 6.798716119619028e-05, + 0.0001841780532802329, + 0.006124314870517229, + 1.0007289097506258, + 0.00848804115945128, + 1.692812113220369e-05, + 3.025985047345458e-05, + 2.7396178308899984e-05, + 2.411402431329091e-05, + 7.91477008687552e-07, + 4.8643705562024125e-05, + 8.844973558735425e-06, + 0.0017964531586413168, + 2.80291057979106e-05, + 2.4093961985278423e-06, + 1.4570802453701416e-05, + 4.348502496106574e-07, + 1.3264134839712206e-05, + 5.066528936150447e-07, + 0.003405796470211449, + 7.01836851398739e-07, + 1.9466631885063608e-05, + 5.237202499739881e-05, + 3.717180985853054e-05, + 1.4378863651314058e-05, + 2.4633857595563536e-05, + 3.711164678999354e-05, + 3.272912969732364e-05, + 3.1968056060833624e-05, + 5.801413329136704e-05, + 4.3330251548595315e-05, + 3.061178252104105e-05, + 5.44501718787695e-05, + 7.50989203964441e-05, + 5.030491643952388e-05, + 0.00710973449326894, + 8.85326354907516e-05, + 2.0442660856813986e-05, + 2.0262792069064637e-05, + 0.0050024275339864265, + 2.6320072321074858e-05, + 6.948461639102615e-06, + 8.017101377762257e-06, + 1.0976407265594007e-05, + 4.990940581764883e-06, + 1.736187378464362e-05, + 0.0025523243434428344, + 3.076454718646216e-05, + 7.045607431884256e-05, + 6.305125415772337e-05, + 2.2346628787836468e-05, + 2.350896238431244e-05, + 0.00022920125990033514, + 6.570378455831617e-05, + 0.004427875840624922, + 6.060744515201521e-05, + 0.00012431712551823294, + 0.00011067717192639689, + 0.0074307455469537894, + 9.413567699746329e-05, + 9.262511050021996e-06, + 0.007738007485690339, + 0.0014518138740913999, + 0.0073028517638831615, + 0.0015313480060440388, + 0.0094797029371434, + 0.005788183044113987, + 0.014410087504995148, + 0.0024285342700700054, + 0.008170787291719226, + 0.003847059050273734, + 1.0002261925286142, + 0.005131700163305644, + 3.0438108375714784e-05, + 0.00961631256625307, + 0.004912962484832755, + 9.915672087837691e-05, + 4.968771746824327e-06, + 2.6361602054917756e-07, + 5.292434468074637e-06, + 1.2001044159749209e-05, + 3.746600959227912e-05, + 8.971261774095474e-05, + 5.356863279872683e-05, + 3.4603896728465273e-05, + 2.9001661252149522e-05, + 5.351529579156392e-05, + 0.0077918063111136705, + 4.0955284985322874e-05, + 7.076122568641112e-05, + 3.6412947427721105e-05, + 0.00019557453083133506, + 1.484422174725565e-05, + 1.6002638384314436e-05, + 0.007245395472591905, + 0.004990979010645134, + 4.2537623301663954e-05, + 1.0116095375722495e-05, + 4.419183138808709e-05, + 0.005248188198912619, + 7.256143633448298e-05, + 5.70986654635919e-05, + 1.7466550890309995e-05, + 0.00821078361998241, + 2.2283096906311314e-05, + 2.8118112264122915e-05, + 0.009180813294514662, + 2.3261520739724016e-05, + 0.00014086511687519626, + 7.199308136705757e-05, + 0.00509972235949859, + 4.9384061889323554e-05, + 6.264312554818843e-05, + 0.0012873218666964255, + 9.519664087722381e-05, + 1.8264595375149003e-05, + 6.813742258479065e-05, + 0.007255851338711169, + 5.314382935454645e-05, + 5.8670941981003886e-05, + 4.695908205301601e-05, + 6.162322138123376e-05, + 4.5873095412197237e-07, + 0.0002192081488419424, + 5.742437076531531e-05, + 4.014318685652859e-05, + 3.8142605394287925e-05, + 6.518935957422784e-05, + 8.167398243961086e-06, + 5.6797153003323836e-05, + 6.278689984787101e-05, + 4.713844281200795e-05, + 6.85314599261555e-05, + 0.000114720592022372, + 0.00011241173024402446, + 6.934688987924458e-05, + 0.007029917261468195, + 0.0039026607996137945, + 0.007621533699389588, + 0.0006133619759453804, + 0.0047020195291187054, + 0.008526010875557077, + 0.00930010985615086, + 0.003773876249747763, + 1.000556336660357, + 0.00674617791236786, + 2.9297849743894987e-05, + 3.447538930700454e-05, + 1.4517033957637429e-05, + 0.0036591943541357543, + 5.375142952456956e-06, + 3.4815135325005485e-05, + 3.084836036525695e-05, + 8.464235497657132e-06, + 4.948738034557916e-06, + 0.009283357720056219, + 5.763283032282485e-05, + 6.509424345376619e-05, + 7.083136365453295e-05, + 7.492454513155434e-06, + 4.036930180264357e-05, + 1.5593738377884085e-05, + 1.9541155247926564e-06, + 4.425405285903667e-05, + 5.7314371833237866e-05, + 0.005343984402739459, + 4.2987315002756274e-05, + 3.903353172128735e-05, + 2.348488155839762e-05, + 2.3726769872314397e-05, + 0.0024031231029667446, + 0.003277712058412189, + 0.0018293532128421254, + 0.0010902598840878482, + 0.000605441247258067, + 0.0024404954301714054, + 0.00689029288331709, + 0.009295057053681489, + 0.007342720305307154, + 0.00817565329544597, + 0.0002642212429301426, + 0.007719854747045573, + 0.005603989538199428, + 1.0001280303623055, + 0.009613346311948063, + 0.00972144003206556, + 0.004346782317554877, + 1.8428138804039813e-05, + 2.7871435289212096e-06, + 5.424328468668677e-05, + 0.006068265635885829, + 4.4092287379431386e-05, + 1.7494555237466507e-05, + 1.1148407990794493e-06, + 2.4756254396915698e-05, + 2.026619213012e-06, + 2.3765530992957984e-06, + 6.843153149414602e-07, + 1.9833815079607923e-06, + 3.4857573364954245e-06, + 9.286554580186971e-07, + 7.809001938097258e-06, + 2.813328553469004e-05, + 3.843436658672674e-05, + 4.97397276280948e-06, + 1.953667039460254e-05, + 2.9001661252149522e-05, + 4.0027338875076087e-05, + 3.3563580092853017e-06, + 5.6874060280116495e-06, + 0.0007922004510952769, + 4.2994741473518604e-08, + 2.2427517869522524e-05, + 5.433155133322079e-06, + 4.4844266449640813e-05, + 0.0033616025774451984, + 4.7368254369153736e-05, + 2.452345987381312e-05, + 3.085198020461461e-05, + 1.6112585805222823e-05, + 0.004060612310993983, + 4.73731084926689e-05, + 0.006076959034976081, + 5.477360401773848e-05, + 3.155285473097504e-05, + 4.2474491256049146e-05, + 0.0004400256081269027, + 0.004092254801917959, + 2.7418689915131593e-05, + 2.7100601453882536e-05, + 2.562502621448758e-05, + 3.8313342227535594e-05, + 0.008111144119919436, + 0.001357161489069189, + 0.0008191279921094674, + 0.008272674602401412, + 0.009532371787812329, + 0.004090065904547754, + 0.0012857957851166912, + 0.009640569433551922, + 0.004073822791191404, + 0.008813855862781005, + 1.00013773783821, + 0.006037442885632564, + 5.800260442591195e-05, + 2.6905188075855888e-05, + 1.8052719752213758e-05, + 2.7934513576924285e-05, + 6.684710209514219e-06, + 1.7917148373883355e-05, + 2.6281148204999713e-05, + 2.6075990744894606e-06, + 5.636155674345554e-06, + 1.9600997227302497e-06, + 3.082805406460417e-06, + 0.00640193868537032, + 5.49233249363574e-05, + 4.35156286886779e-05, + 2.8591836887176645e-06, + 1.437187119899864e-06, + 4.5311896319640864e-05, + 4.5190161299316886e-05, + 6.757292987282388e-05, + 9.782597090310911e-05, + 0.009832220847402985, + 5.66267224832227e-05, + 1.2987571936806203e-05, + 0.0009155504675766507, + 1.78718978296062e-05, + 4.334605723171568e-05, + 7.63198582473916e-05, + 7.494947992189717e-07, + 2.4756254396915698e-05, + 1.778782434313251e-06, + 1.1918029804950755e-06, + 3.9338609163468106e-07, + 3.0294756990803786e-05, + 4.412902333975753e-05, + 5.669926894785835e-05, + 4.348502496106574e-07, + 0.0008070845419398598, + 5.010532596552045e-06, + 1.7419893057828467e-05, + 4.62165565302197e-05, + 7.492454513155434e-06, + 0.00025118900478544144, + 2.1078685517739725e-05, + 2.9901307237916217e-05, + 1.5200482383733676e-05, + 0.002681107746571281, + 1.959416426729882e-05, + 0.0003744931963655796, + 0.012483629336950668, + 0.0030543276608787084, + 0.006164328751618406, + 0.00852430417569119, + 0.007254780340154869, + 0.00041322251086869325, + 0.009116386897353035, + 0.004851393663705584, + 1.0001992453416453, + 0.004272437696748578, + 0.006843301367477539, + 6.374362258410816e-05, + 4.9736078040864996e-05, + 5.1116032814248954e-05, + 3.4306264474122114e-05, + 3.557441043217354e-05, + 5.757301024859485e-05, + 3.101156235952684e-05, + 5.951938020031008e-06, + 6.782242961139645e-05, + 2.2621518051178686e-05, + 3.3820810315839816e-05, + 0.007629929362896941, + 4.62165565302197e-05, + 7.083136365453295e-05, + 1.6867752071647554e-06, + 0.007158975274909028, + 2.3365918073951653e-06, + 0.006691148114714365, + 1.8160182746121535e-05, + 8.119893134280176e-06, + 1.951610783233207e-05, + 4.794687006752578e-05, + 7.097168045875709e-05, + 2.529100990073698e-05, + 1.0025578146460832e-05, + 0.006330940003646736, + 1.914398375550642e-05, + 7.405308840517132e-06, + 4.2254995780583525e-05, + 0.0031233784413476104, + 1.992624250485789e-05, + 2.1432104694935766e-05, + 7.142381266046672e-05, + 3.9008191727962326e-05, + 0.00010016745206491854, + 0.009083110322041153, + 9.155010186532908e-05, + 4.351836384074313e-05, + 0.00014331101054724154, + 9.297493441906668e-05, + 0.0001581423678117155, + 5.128940535339805e-05, + 1.2029221063479777e-05, + 7.861658049290633e-05, + 0.009849147660169047, + 4.2143961054239465e-05, + 0.00010202137810034909, + 4.5377225727068476e-05, + 0.00010429519486518364, + 4.324578616775226e-05, + 0.0005189204241672527, + 4.231651410967184e-05, + 1.0605426200807425e-05, + 4.5049929939845996e-05, + 9.413567699746329e-05, + 1.380184495252424e-07, + 6.865750563308246e-05, + 5.7243482353636986e-05, + 0.002314784955476499, + 5.392157334207365e-05, + 2.47563889274485e-05, + 2.467467834180957e-06, + 1.5766822889265075e-05, + 1.590347727310638e-06, + 2.2944254966470916e-05, + 0.0014219585134118678, + 0.005835945780210611, + 0.005215496332165455, + 0.0020350525021958785, + 1.4573046498807523e-05, + 0.005903640664409296, + 0.0044026206126353655, + 0.007118970625743312, + 0.0001406914175397761, + 0.004809264790915783, + 1.0180586134528515, + 0.003773876249747763, + 2.5283835845936842e-05, + 8.181167154527567e-06, + 3.683536136168756e-05, + 5.0087594202736606e-05, + 2.8684972057005484e-06, + 5.259205737729365e-05, + 0.008694167441570979, + 4.2537623301663954e-05, + 5.6189019332360594e-06, + 0.0024160246204003987, + 2.398559145833957e-05, + 7.358615837206509e-06, + 3.269166597623609e-05, + 1.8323805044617538e-05, + 5.168247156296229e-05, + 4.279874378483436e-05, + 0.006810501117304453, + 6.547496387070687e-05, + 4.862023104542222e-05, + 4.0123999081499147e-05, + 8.073755821739811e-05, + 7.661734569325919e-05, + 4.548301416806034e-06, + 0.00013666632960500865, + 3.1424659084850304e-05, + 7.705892301173354e-05, + 0.0001423670210546449, + 0.00010264068062069862, + 8.85326354907516e-05, + 4.837751437608723e-05, + 2.1516653637500003e-05, + 5.7681226031826427e-05, + 5.950574219013195e-05, + 0.0001055661057078594, + 3.293840406858189e-05, + 3.0768169071865856e-05, + 0.005221264934321769, + 0.003566473707317041, + 0.003614653284985154, + 0.007559658489312481, + 0.015694012931671365, + 0.00224369175698486, + 0.009118215936367427, + 0.0017603968215497067, + 0.003501122986141881, + 0.008105714809448456, + 0.006834344870539171, + 0.0014219585134118678, + 1.3467076728030982e-05, + 0.00015990344757346706, + 1.0251676266438782e-05, + 5.597548049290373e-05, + 3.160726188317129e-06, + 1.3433271666820882e-05, + 3.8611487076955e-05, + 5.208940248579786e-05, + 0.00010829417935510544, + 4.581627553562489e-05, + 3.7911742073489405e-05, + 5.09326705826915e-05, + 1.0003144202198913, + 0.005603989538199428, + 5.3873092159245e-05, + 9.478196456125603e-05, + 0.003514649711063711, + 5.52110992687459e-06, + 4.812960853350476e-06, + 1.0436275612713423e-06, + 1.5202867029995339e-05, + 3.9574365777364284e-07, + 1.719028176153091e-05, + 1.274185590414587e-05, + 1.6007448693199368e-06, + 0.0013524119124650137, + 1.083030484391954e-07, + 1.286742358858376e-05, + 1.2569418638884622e-05, + 3.1283205561362908e-06, + 4.948738034557916e-06, + 4.64572228654459e-05, + 7.236902666097318e-05, + 2.2427517869522524e-05, + 4.1328595096240814e-05, + 6.343447748240056e-05, + 1.5676400112376638e-05, + 1.7404626310910644e-05, + 3.122237635000989e-05, + 4.413367626682505e-05, + 1.9635237808574706e-05, + 0.00855284750328267, + 5.6265324282509934e-05, + 0.003516730555426826, + 1.5901806361230987e-05, + 3.1424659084850304e-05, + 1.992624250485789e-05, + 3.272912969732364e-05, + 8.61084221273961e-05, + 6.511645296408814e-05, + 6.911311528819053e-06, + 0.009151840802452679, + 0.006803726876170835, + 4.5865172442288695e-05, + 7.365929642574257e-05, + 5.966011299312112e-05, + 6.304818718883307e-05, + 2.1655730003934487e-05, + 1.1621207799905132e-05, + 2.7073737897301418e-05, + 3.8941321970515616e-05, + 3.689614821820535e-05, + 2.2086846522067662e-05, + 4.129705794276378e-05, + 1.9452907879640914e-05, + 3.709196423785288e-05, + 0.0025021376078974, + 0.004193048518656666, + 2.6451525648099112e-05, + 9.513935743872953e-05, + 0.007525119344665386, + 0.00012090014934069268, + 0.00571553669088225, + 5.7475994530403656e-05, + 0.0013346887928212846, + 0.005471422643999203, + 0.007214311791655111, + 0.0011618057425408913, + 0.007812569537828521, + 0.0029778643265331926, + 0.006714025703901893, + 0.0011608902738247868, + 0.004095080169476463, + 0.006021015435910667, + 0.004094639868977095, + 1.0002535656443527, + 0.007029917261468195, + 6.526940843802335e-05, + 3.3864510266791785e-05, + 7.474339543658002e-05, + 2.7642468420145466e-05, + 8.453434392048e-06, + 4.431658039795528e-06, + 5.214824211776975e-06, + 7.623227138481154e-05, + 0.000553497892180952, + 8.130561009949154e-07, + 1.5070953927305015e-06, + 5.144251287968885e-06, + 1.3780010086691152e-05, + 5.414460890939888e-06, + 8.159669202728204e-06, + 7.088415884733152e-06, + 0.0011279691886657696, + 3.5019940290114174e-05, + 8.052582566310962e-06, + 0.00011214618521792638, + 8.100221253346378e-07, + 4.4724072133743586e-05, + 1.103134707835397e-06, + 0.00015054319828436234, + 3.20055874953058e-05, + 0.00012069185503087766, + 0.007589957624907277, + 1.2767150636099418e-05, + 5.276511670132932e-05, + 0.015956462186832294, + 0.006532895409013626, + 0.00795786731176502, + 0.0009234583894543225, + 0.007715697260558262, + 0.0018410580341127881, + 0.008406326448191252, + 0.0016311467511667876, + 0.006740073564627112, + 0.008032634006271282, + 2.6714321060972634e-07, + 1.817098185835928e-05, + 5.464070852933514e-06, + 3.108609273131704e-05, + 3.3996998096963766e-05, + 0.009300587252411117, + 4.146895381538172e-05, + 8.40175663732779e-05, + 4.488390245325977e-06, + 9.936512573515954e-05, + 2.1595110644548335e-05, + 0.004094639868977095, + 6.934688987924458e-05, + 0.008467305956396259, + 2.5296822458611236e-05, + 0.007255646153887324, + 1.858511569018207e-05, + 4.352960566006824e-06, + 1.8500337692731853e-05, + 5.322016823308476e-05, + 0.00014935807139830338, + 5.666986257986792e-05, + 9.054949682981293e-05, + 7.16441690773409e-05, + 1.000275395407536, + 5.09326705826915e-05, + 0.007719854747045573, + 7.419416670917138e-05, + 0.009014740192242751, + 4.8084221300370924e-06, + 1.843783095389692e-05, + 1.8221410812353872e-05, + 1.777519615716201e-05, + 1.877302672780624e-05, + 4.107847715552589e-05, + 3.63114731874677e-05, + 1.4482501638671528e-05, + 2.141230278799636e-05, + 8.572392299435928e-05, + 3.9934496549270716e-05, + 0.004934645058048987, + 0.00813513284380525, + 5.9923237944393764e-05, + 8.294525405860026e-06, + 2.6203882320019604e-05, + 5.669926894785835e-05, + 1.4570802453701416e-05, + 5.988673040886737e-05, + 1.839517068585072e-05, + 1.0439763834962318e-05, + 1.1519857580317528e-05, + 0.0012684392689259717, + 1.2510973873916954e-05, + 0.0019700424201241754, + 7.582184626453817e-05, + 7.501128852404918e-05, + 2.321148905500842e-05, + 5.887316971243261e-05, + 0.008222564658297488, + 2.534535230410747e-05, + 0.009809863027986832, + 0.009127873853865254, + 0.008073456212003685, + 0.008334515044103877, + 0.00883762015458032, + 0.007973859332807587, + 6.783584304793724e-05, + 3.4421275378160735e-07, + 4.485651296957946e-05, + 2.8032026778863344e-07, + 0.0019337748315410668, + 3.779260422389367e-05, + 5.31320982239297e-05, + 6.381972097879172e-05, + 3.537073978440055e-05, + 0.005804125652252279, + 4.280316431475197e-05, + 2.1595110644548335e-05, + 0.006021015435910667, + 0.00011241173024402446, + 3.627360518329618e-05, + 0.007507237381039352, + 9.10611133788154e-05, + 0.0001035434114937968, + 3.0625251536410894e-05, + 0.00010091988110382644, + 1.2031158987471699e-05, + 1.7007876674383676e-05, + 0.006834344870539171, + 2.2944254966470916e-05, + 0.009864768684482637, + 8.688208808112132e-05, + 0.00013652022364646203, + 8.366686264344738e-05, + 4.279985052176947e-05, + 1.1285596254064168e-05, + 0.00022212792443789914, + 0.0030008506551227453, + 0.008813855862781005, + 0.003047843274389201, + 5.699201280114511e-06, + 4.848704502905711e-05, + 0.0064067636604403086, + 0.0055860723141447684, + 3.5152894511271435e-05, + 0.007505476440510395, + 8.319739106311735e-05, + 0.00010981446149796692, + 4.7269354886358105e-06, + 0.00010448432381559467, + 2.2821029286700005e-05, + 2.5786673808607915e-05, + 1.000543071106035, + 0.00589213577782564, + 4.1662899268953135e-05, + 2.132797269703622e-06, + 0.007058824446817216, + 5.481084580463887e-05, + 4.5190161299316886e-05, + 7.190953694790406e-05, + 8.461744813480758e-05, + 0.00013449665841190302, + 7.395084545201742e-05, + 7.642218699679069e-05, + 1.594467635630258e-07, + 8.574514082806994e-05, + 0.004871900036639932, + 8.44689701773998e-05, + 1.6112585805222823e-05, + 6.324948152687383e-08, + 0.004448178781097971, + 1.7404626310910644e-05, + 7.490029829638944e-05, + 2.7897221652101157e-05, + 0.00010372821586498543, + 0.009530370211735932, + 7.666284096464855e-05, + 4.18825353448943e-05, + 0.00010345871344829712, + 3.2669094648244773e-06, + 0.00010548489137167106, + 7.806830397465771e-05, + 0.007404914265770819, + 8.805908936468158e-06, + 5.803857831012882e-06, + 1.4148013360018128e-05, + 3.019698382825305e-06, + 3.4841133653436712e-06, + 0.008750829676035217, + 4.2143961054239465e-05, + 0.0001088050593768327, + 0.00010779998862338913, + 8.445107658541375e-05, + 8.543183096335565e-05, + 6.936458064177405e-05, + 0.008659453264464056, + 3.120558757653484e-05, + 0.004533179197600133, + 3.004152528081633e-05, + 7.860681144132016e-05, + 6.242079514647868e-05, + 0.00011293821770791351, + 0.00015398277994120403, + 0.007125817969637223, + 0.0082645365245498, + 0.01169005897156178, + 0.0005409447801154472, + 0.0032229912057087124, + 0.00826115681055757, + 0.0034405225796962364, + 0.005204560921393831, + 0.0065922905508567185, + 0.0028683464195861283, + 0.007219324060662954, + 0.008222564658297488, + 0.003131018813857472, + 0.008315295754634805, + 5.841394323541241e-07, + 5.88847363590114e-05, + 8.651694171316354e-05, + 7.398325825980472e-05, + 0.0001284645428770314, + 1.9635793154361086e-06, + 2.058832098831185e-05, + 6.6127942078603766e-06, + 7.16441690773409e-05, + 3.7911742073489405e-05, + 0.0002642212429301426, + 4.2655792352873584e-05, + 4.119423434434955e-05, + 0.00013392696754589646, + 2.9204211939985304e-05, + 5.8641039681199165e-06, + 5.855432409621465e-05, + 0.0001502896301746381, + 3.689155146280462e-05, + 1.8660644278303113e-05, + 3.2699517481831474e-05, + 1.0005539499928202, + 0.003847059050273734, + 9.45527466148835e-05, + 0.00391967740274463, + 1.1461727965227623e-05, + 9.075276578589366e-05, + 0.0047951923711135385, + 4.498148682255461e-05, + 4.750657303075888e-05, + 3.3820810315839816e-05, + 4.918019805390054e-05, + 2.1796536959262597e-06, + 9.908776278140068e-06, + 4.333016980302816e-06, + 2.4093961985278423e-06, + 0.00011464695819708957, + 3.9953097404302765e-05, + 0.005562525093049638, + 9.862047675441458e-06, + 1.2380803640812112e-05, + 5.314728789067926e-05, + 2.562502621448758e-05, + 4.88493666609293e-05, + 5.5854783266968745e-05, + 6.77279581052288e-05, + 8.557631805263534e-06, + 1.1931230595413092e-05, + 6.619848851781917e-05, + 0.004213442564747276, + 5.018358904242168e-05, + 1.1026494536511072e-06, + 4.3880021412216516e-05, + 2.436312083575389e-05, + 4.928443982842512e-05, + 6.735818788402423e-05, + 0.006047231430546131, + 0.00408344249254145, + 6.442624923415236e-05, + 4.9810654609521915e-05, + 6.373008761573134e-05, + 1.959416426729882e-05, + 0.01165854614591907, + 0.0082483715939574, + 0.005454660455186017, + 0.00784335809733372, + 0.005760547974782387, + 0.008434198729491096, + 0.005892857278628511, + 0.0054098623552808365, + 0.005825670528245169, + 0.007125817969637223, + 0.005221264934321769, + 5.9320029439863275e-05, + 2.628279587583401e-07, + 7.454297128879022e-05, + 2.1404205094684842e-07, + 5.6973288496865745e-05, + 9.20890698185028e-05, + 8.76974162781124e-05, + 3.926594144929374e-05, + 4.280316431475197e-05, + 9.936512573515954e-05, + 0.004095080169476463, + 0.000114720592022372, + 0.009326835203001295, + 1.8417197291495864e-05, + 0.0013789509831549367, + 4.4290465341956033e-05, + 0.0013262776517449749, + 7.964997756107978e-05, + 1.0572160482083514e-05, + 1.5799611749605832e-05, + 3.7121389807687816e-05, + 0.006311483244382031, + 0.00014456637776158663, + 1.0352222185209052e-05, + 0.0072258859519244495, + 1.0003156453417406, + 0.0019747358368568304, + 0.00793893361762072, + 6.176049961778198e-05, + 4.005987306107562e-05, + 8.943649925289279e-06, + 3.369506848055413e-05, + 0.004710837294839253, + 3.9686777895044975e-05, + 1.3736242288739475e-05, + 5.458421368513962e-05, + 0.006195682247786596, + 6.129640226876825e-05, + 3.539059879489178e-05, + 3.47873892853305e-05, + 1.1519857580317528e-05, + 6.956014306610032e-06, + 0.0007520202876280246, + 7.868933400378229e-05, + 3.807858887188459e-06, + 4.543184892775909e-06, + 7.227804363621828e-06, + 7.000542902825968e-06, + 8.031746833525979e-06, + 5.5480085827694036e-05, + 4.7380954835658765e-05, + 1.2695145626776906e-05, + 4.909709825223077e-05, + 0.005511413361947338, + 2.4324983724006634e-07, + 1.4090856331832103e-06, + 1.649098475312688e-06, + 6.861453876372358e-07, + 7.863280354198881e-07, + 2.8074432059582885e-06, + 2.2152551541613593e-06, + 0.00018927640511463451, + 8.895582859343049e-07, + 3.5530845401021354e-06, + 5.314382935454645e-05, + 0.003988215269240574, + 0.00010672287848834117, + 0.005492684933484426, + 0.00014991626842961953, + 0.00415774313581574, + 0.008064959461052453, + 0.008659453264464056, + 0.007589957624907277, + 0.001682110924335416, + 9.067980198600438e-05, + 2.052195184514316e-06, + 5.267454634504788e-05, + 3.996606173962012e-05, + 8.942891187852903e-06, + 6.895434020954211e-06, + 0.009874079931003811, + 9.369045968381743e-06, + 8.382334225368937e-06, + 3.3215104390041955e-06, + 1.5398702046158918e-06, + 5.880937526079813e-06, + 1.0001554837903515, + 0.007908396123318565, + 5.386498799229628e-05, + 8.54482043585373e-06, + 6.360723619574272e-06, + 9.317462688392536e-06, + 3.356777733560644e-05, + 0.004828100933283703, + 3.2901582192803755e-05, + 4.585871273468841e-05, + 5.934792435440277e-06, + 1.953667039460254e-05, + 3.4603896728465273e-05, + 3.16864353202332e-06, + 4.154972671783279e-06, + 0.00048644854934731753, + 4.014886379571267e-06, + 4.783186967344497e-06, + 3.658505363849941e-05, + 3.232509725475268e-05, + 4.156106397999411e-06, + 9.853135724398703e-08, + 0.0004915262872471038, + 0.009262863782751712, + 0.0009509364771072949, + 0.0058645951237479765, + 0.00829695684417064, + 0.008106382247233694, + 0.009276745414995192, + 0.0077722776138475, + 0.006597636404530838, + 1.0000237879905225, + 0.005018402425556384, + 0.00706549802282827, + 6.51473398838025e-05, + 5.478106217644566e-05, + 4.202569748398294e-06, + 3.990835206191733e-06, + 1.049107635947085e-05, + 9.526712031344487e-05, + 4.552346662069953e-05, + 9.293417333806772e-05, + 4.750657303075888e-05, + 1.877302672780624e-05, + 2.147224746167066e-05, + 2.9990147075282934e-05, + 0.005850778163732161, + 2.055840385903111e-05, + 6.0060345185960196e-05, + 6.444748122258493e-05, + 2.4771419462574535e-05, + 1.3621500339103099e-06, + 0.0013096420345198375, + 9.563744905355311e-06, + 1.3926506083939243e-06, + 9.64519742464365e-06, + 7.142381266046672e-05, + 1.0786968122519265e-05, + 0.009924221952596258, + 1.6298167845171424e-06, + 1.9067817376664148e-05, + 2.9750955246120755e-05, + 0.00298039332094451, + 1.8656782760597722e-05, + 1.1752268666632123e-05, + 3.8907724284033985e-05, + 8.884186737477239e-06, + 0.006037553521700404, + 0.0008118108024197676, + 0.0017900443001192285, + 0.003607489004396031, + 0.0007179782566983814, + 0.009983239643101386, + 0.007382232899732989, + 0.006850510061810733, + 0.0027436258125378976, + 0.008189686869970838, + 3.316459337939621e-05, + 0.0017614905000378658, + 0.00215782461676853, + 1.6457045280624036e-05, + 0.00012218969694670703, + 0.0037919118349826818, + 1.0177223023903816, + 0.008064959461052453, + 6.936458064177405e-05, + 0.00012069185503087766, + 5.0340873321860937e-05, + 0.00011307173467956233, + 1.5169365522255912e-06, + 4.2505389300810915e-05, + 6.661613518538756e-05, + 1.7431546902319922e-06, + 5.481084580463887e-05, + 5.2504102984330765e-06, + 0.003230710684057512, + 5.652742040649498e-05, + 4.333016980302816e-06, + 2.6203882320019604e-05, + 1.6709407581142358e-05, + 1.6194195528969006e-06, + 1.8504975325063464e-05, + 8.37663585323914e-06, + 5.934792435440277e-06, + 4.97397276280948e-06, + 3.9045702490191184e-05, + 4.170074180386796e-05, + 4.953655337972678e-05, + 2.2149089869145255e-05, + 5.3235186612166245e-05, + 7.084291599007136e-05, + 9.830265710848967e-05, + 6.89877122653197e-05, + 2.0303929538564436e-05, + 8.257332596159574e-05, + 0.0078036394547676404, + 1.4997326509518679e-05, + 0.001254912207654518, + 0.008480512053198986, + 1.5901806361230987e-05, + 2.0400045701197958e-05, + 5.913696972297344e-05, + 5.5649786206448084e-05, + 7.238555613669371e-05, + 9.64519742464365e-06, + 6.094138202063724e-05, + 6.301974197764083e-05, + 0.008918644968355796, + 0.00010264068062069862, + 0.012865204471301449, + 0.00040951532149479774, + 0.003262568127085023, + 0.007320563611416953, + 0.008980663561578098, + 0.002246202067281234, + 0.005543813403275388, + 0.01574616148972817, + 0.009526728664990757, + 0.002532528169657162, + 0.0074307455469537894, + 0.0012815068139153654, + 8.163737875101414e-05, + 4.0346791468329965e-05, + 1.4663526011589675e-05, + 5.345428422257456e-05, + 4.0924344042050054e-05, + 4.6504964415883905e-05, + 1.8761291921232777e-06, + 4.376687482265514e-05, + 0.004851393663705584, + 4.413969271119868e-05, + 6.289543888777127e-05, + 3.586343427183496e-05, + 8.654641647049102e-05, + 0.008592458769033464, + 4.356112667058918e-05, + 0.00013146806430429055, + 1.0004190150021024, + 0.004809264790915783, + 0.00930010985615086, + 6.222207450410723e-05, + 0.003520165825018783, + 9.03558246672859e-06, + 2.1787544078622775e-05, + 4.221448294680072e-06, + 1.0481439960144256e-05, + 2.7583452473090147e-05, + 3.082805406460417e-06, + 4.470429515463049e-06, + 0.0021123970544425484, + 4.445366420884142e-05, + 1.594467635630258e-07, + 3.0453043375824447e-06, + 0.0030457536628856843, + 7.358615837206509e-06, + 7.288720745849373e-06, + 0.0031276072742181596, + 0.0025955043327308257, + 1.3142350549209993e-05, + 4.892233214493144e-05, + 1.7393470899108238e-05, + 2.1430325576489996e-05, + 5.15076415312748e-05, + 6.85439791623251e-05, + 0.008172434288961817, + 5.545703057791173e-05, + 6.89877122653197e-05, + 2.529100990073698e-05, + 5.6017542851683475e-05, + 4.266113161881524e-05, + 1.7160912740953665e-05, + 0.001344901064955023, + 3.398949873757143e-05, + 4.6518092916010685e-05, + 0.007620250945392171, + 4.699549064728338e-05, + 7.370596526041767e-05, + 3.066706376961309e-05, + 0.0056379696535372795, + 0.008482307511236168, + 3.5530845401021354e-06, + 0.00012032027402574883, + 6.902350664223597e-06, + 1.6306202238306393e-05, + 4.100952759170509e-05, + 0.0009201478342575923, + 2.7100601453882536e-05, + 2.6194607769450517e-05, + 0.0033159955720434213, + 0.005102547594472177, + 0.003043158741887113, + 0.007275297032222334, + 5.688094456474576e-05, + 7.979623164228452e-05, + 6.0430188781166103e-05, + 3.667290377192227e-05, + 0.00010056316074184729, + 7.807000346171727e-05, + 0.00010504777710321347, + 1.71528140695156e-05, + 0.00016966285388558808, + 4.8675343537910945e-05, + 5.233154862039399e-06, + 6.841527427324271e-05, + 4.798729591851256e-05, + 2.5844655406679966e-05, + 0.009360155982221886, + 7.854924150935622e-06, + 1.2737606264021523e-06, + 1.4874198614900185e-05, + 0.00557935728804668, + 0.008832053506273614, + 1.0003077707693604, + 3.926594144929374e-05, + 0.005804125652252279, + 4.488390245325977e-06, + 0.0011608902738247868, + 6.85314599261555e-05, + 0.008744145541964786, + 8.154231257388808e-05, + 4.1856189126207785e-05, + 2.7089114924897626e-05, + 5.706019083774347e-05, + 4.445366420884142e-05, + 7.236902666097318e-05, + 5.747989602628534e-05, + 0.007316043405194684, + 0.00010816771859609541, + 5.314728789067926e-05, + 3.085198020461461e-05, + 3.499529266183106e-05, + 2.401893992812954e-05, + 1.7230684945129012e-05, + 6.982511354897124e-05, + 6.226152553836605e-05, + 1.6888929301382213e-05, + 3.745663236051577e-05, + 7.431313644927198e-05, + 5.079816090900735e-06, + 3.117548029508032e-06, + 3.0856925473438306e-05, + 2.2756773597648387e-05, + 0.005638980724112857, + 0.007773325140821933, + 0.007938956551945167, + 0.003242508738519706, + 0.0075773494450229375, + 0.004418490344777326, + 0.009065125655137866, + 0.009782309454680381, + 0.0031757414411978605, + 0.004300984806407466, + 0.008664274028987562, + 0.0011313593767402364, + 0.009849147660169047, + 0.0025523243434428344, + 0.0044510452107628835, + 4.988319262381871e-05, + 4.055292891554118e-05, + 1.9073452472447576e-05, + 9.490674478102146e-05, + 0.006889523406357306, + 0.007219324060662954, + 5.887316971243261e-05, + 0.00010865683469747918, + 2.78444326678576e-05, + 7.564088304664701e-05, + 0.00011723158728588356, + 3.5625642103399774e-06, + 4.376687482265514e-05, + 0.009116386897353035, + 7.128019767737525e-05, + 0.00013616695276437934, + 1.6958464549274786e-05, + 0.007944636963792108, + 5.002017546540117e-05, + 0.00010459660272650717, + 0.009636119219212608, + 8.13393389642432e-05, + 2.6870034435190565e-05, + 1.0004047736401767, + 0.0034911392760475354, + 0.00013379945568627112, + 8.186621732546018e-05, + 5.403445097854669e-05, + 6.883962337457583e-05, + 5.281082680604117e-06, + 1.0003977443525997e-05, + 7.474339543658002e-05, + 3.2533800384630557e-05, + 5.023417761546015e-05, + 2.3477716972446635e-05, + 4.3451375820987274e-05, + 0.0070778397836248255, + 3.8744548382065554e-05, + 4.810990280897296e-05, + 3.1610493407164625e-06, + 1.5889218365970699e-06, + 4.5311896319640864e-05, + 0.008911991690964146, + 0.0068864505226439, + 2.3781942172827e-05, + 1.719028176153091e-05, + 9.548755468020766e-05, + 5.731589450935227e-05, + 0.000145030445193013, + 0.00010816771859609541, + 2.452345987381312e-05, + 0.014405048700368052, + 0.008918644968355796, + 0.00710973449326894, + 6.4177551223725635e-06, + 7.060536541393035e-05, + 5.73502575314267e-06, + 7.760430092050088e-05, + 5.896737874814423e-05, + 5.472011340191899e-05, + 7.853535375098192e-05, + 8.901347096340515e-05, + 0.008189686869970838, + 0.0063204791660593125, + 3.7779296004229136e-05, + 0.00015788936748717885, + 7.092654206774545e-05, + 4.89366368790601e-05, + 3.669353473460797e-05, + 4.7459302796212956e-05, + 0.005825670528245169, + 0.00015398277994120403, + 2.7271073892822847e-05, + 4.808848753479633e-05, + 4.101264839737831e-06, + 1.3592364534603364e-05, + 2.279851190786204e-05, + 2.545741842614761e-06, + 0.00013713865786819753, + 3.089131374698755e-06, + 3.5406938460700636e-05, + 1.0003688756664544, + 1.7007876674383676e-05, + 0.008105714809448456, + 1.590347727310638e-06, + 0.008016194859820336, + 4.163593054971914e-05, + 7.475390977604764e-05, + 5.023417761546015e-05, + 0.0026360543980688145, + 5.629750213349031e-06, + 7.944851687717692e-06, + 7.131101283954011e-06, + 5.2465533659413894e-05, + 7.627186117384875e-05, + 1.0222702906452622e-05, + 7.238555613669371e-05, + 8.749361914559068e-05, + 1.2511572762084668e-05, + 1.2234782130969098e-05, + 9.324987802129278e-06, + 2.1402630556665295e-05, + 1.2594651748272449e-05, + 0.002518284793421295, + 7.44429777262454e-06, + 0.0019505472223636333, + 0.0014745260047490116, + 0.006037553521700404, + 7.710549309795944e-05, + 5.400377972758566e-05, + 2.2056768611094835e-05, + 0.00652056301061857, + 3.005623947511771e-05, + 6.161934999922442e-05, + 1.851882951395248e-05, + 6.542968016277152e-05, + 6.938926754019389e-05, + 7.695933612238808e-06, + 7.861658049290633e-05, + 1.736187378464362e-05, + 8.544810389600539e-05, + 3.681826033099115e-05, + 6.785098793438811e-05, + 6.172582231664433e-05, + 0.0001226963844664554, + 6.415363463656095e-05, + 0.007275297032222334, + 4.735984999341235e-05, + 7.6171374432633975e-06, + 1.3632792315744896e-05, + 8.927093181596704e-06, + 6.478983772859016e-05, + 2.1376951580614815e-05, + 0.009676960075387354, + 1.849718928212902e-05, + 1.0002779240850257, + 0.006889523406357306, + 0.0028683464195861283, + 2.321148905500842e-05, + 8.714215975638049e-06, + 2.3321140638181313e-05, + 3.52533981816771e-05, + 3.4306264474122114e-05, + 0.001232839274524128, + 4.706223389482264e-05, + 2.1638565938509677e-05, + 9.671370476470335e-05, + 4.8643705562024125e-05, + 2.6109734895727233e-05, + 1.3736242288739475e-05, + 1.484422174725565e-05, + 0.005453446633799271, + 2.3242003711048557e-05, + 1.741084018960257e-05, + 8.738491375979277e-06, + 1.9299368127396475e-05, + 1.6946522582387045e-05, + 0.002988631887868677, + 0.0037110609109953898, + 0.005695212786820327, + 0.008459663950100319, + 0.002681107746571281, + 4.662078208548067e-06, + 5.699395700018925e-06, + 1.990714084779318e-05, + 1.847328180131288e-05, + 8.901347096340515e-05, + 0.0027436258125378976, + 2.9019803498547727e-05, + 2.700232458322728e-05, + 2.0646085382212123e-05, + 0.009813729259187031, + 2.614368819921816e-05, + 1.71528140695156e-05, + 2.6451525648099112e-05, + 6.965275646704858e-05, + 6.607100977039375e-05, + 7.923441900497486e-05, + 9.019246741974433e-06, + 0.0001783375337444304, + 6.752494369555874e-05, + 1.310240486264126e-05, + 0.008032634006271282, + 0.00010760530953880158, + 5.987655235048369e-05, + 5.50711807066434e-06, + 0.00013417932789838304, + 6.479496401931944e-05, + 0.002954714475054873, + 3.2475583311200885e-05, + 5.238104174226221e-06, + 9.334297135713388e-05, + 0.0030008506551227453, + 0.004073822791191404, + 7.639022655726693e-05, + 5.2769736697683524e-05, + 0.0034227338913006555, + 2.3174984669763992e-05, + 0.007925813749040412, + 3.750389361508163e-05, + 1.6582000373062033e-05, + 7.528097178324361e-05, + 7.669424770295681e-06, + 4.662805809938742e-06, + 8.102003010137707e-07, + 2.3376055606366328e-05, + 1.0002503655015804, + 0.0072258859519244495, + 0.0030972922175133, + 5.848653372189761e-07, + 1.7920640048420202e-06, + 4.762214563038365e-07, + 1.3348925708514831e-06, + 4.302624219575653e-07, + 7.494947992189717e-07, + 1.1148407990794493e-06, + 1.1992982759795414e-05, + 0.004357343568433076, + 1.8808918578478595e-05, + 2.141230278799636e-05, + 3.655322791892029e-05, + 3.426856622257189e-05, + 1.920766372314651e-05, + 2.410980125288674e-05, + 0.00713900933396598, + 8.052582566310962e-06, + 4.862023104542222e-05, + 2.973840254558375e-05, + 0.0002330089418659586, + 3.4185747076641285e-05, + 3.5817131940039534e-05, + 1.6125188709193586e-06, + 5.142917252934526e-05, + 0.004478441911544396, + 3.5472752645703684e-05, + 4.18825353448943e-05, + 2.348488155839762e-05, + 1.9579120926910124e-05, + 1.5939223154984972e-06, + 7.667920282896653e-05, + 7.186162010213901e-05, + 5.621054680408905e-05, + 5.330234599939667e-05, + 0.009963497689544864, + 9.795274955841379e-05, + 7.50989203964441e-05, + 0.0020341300219831504, + 0.00648503653023617, + 0.00782914362550076, + 0.00587733230650688, + 0.002923910238477404, + 0.00537362751138068, + 0.006523181202208075, + 0.005670327835012276, + 0.006685049011509828, + 1.0001886258980548, + 0.002988631887868677, + 1.2456287254784247e-07, + 2.6361602054917756e-07, + 0.006854405223712914, + 4.65911604680687e-05, + 1.538762457161008e-06, + 3.617988384313475e-05, + 3.942136473014121e-05, + 7.694523948548027e-06, + 5.035059539802786e-06, + 2.7545876117955095e-06, + 5.652742040649498e-05, + 8.294525405860026e-06, + 4.412902333975753e-05, + 6.401808159144565e-06, + 8.868053332557463e-06, + 0.0018340534860973967, + 5.732217749423728e-06, + 1.0291812167812526e-05, + 1.5676400112376638e-05, + 0.006243726979236103, + 0.0007991026022771701, + 0.0019808005861819576, + 0.009439959067106114, + 0.0013354308950555116, + 0.003925877503611112, + 0.005796324582018182, + 0.006162464895893152, + 1.106115656959078e-05, + 8.572705345464126e-06, + 4.998900482600028e-06, + 0.005005735433951281, + 3.0800189049306255e-06, + 1.0882148447506776e-05, + 4.920404084443367e-06, + 9.802407665341985e-06, + 7.695933612238808e-06, + 0.0011313593767402364, + 1.2029221063479777e-05, + 4.990940581764883e-06, + 1.5739800122089514e-05, + 2.9679459951328885e-06, + 6.0329364738038516e-05, + 0.00983724045435927, + 1.6037235818269438e-05, + 3.687809075046072e-05, + 0.009742433538967666, + 3.555021927781079e-05, + 7.853535375098192e-05, + 1.7099755476563073e-05, + 6.830114907139503e-06, + 0.0016040258767245185, + 2.266246567558815e-06, + 0.0037919118349826818, + 0.00415774313581574, + 8.543183096335565e-05, + 3.20055874953058e-05, + 2.1816080408894437e-05, + 3.749231695173124e-05, + 3.3007267523658666e-05, + 6.668280050031122e-05, + 0.001026103455904006, + 3.1987418151162497e-05, + 1.8606361438029243e-05, + 7.92758331939025e-05, + 2.5948670913940536e-05, + 8.43286912301128e-07, + 1.05857717104082e-05, + 6.43586700597802e-06, + 5.140845459602858e-06, + 1.0001044156480565, + 2.3376055606366328e-05, + 1.0352222185209052e-05, + 0.004275057037133662, + 0.0034534397792633023, + 7.66947463026765e-06, + 3.4278764461559064e-05, + 2.3781942172827e-05, + 0.00033545871412157813, + 0.0005468462075336555, + 0.00298039332094451, + 1.3598258892740924e-05, + 4.296992740599398e-05, + 3.8945017106828324e-05, + 1.9546483249476834e-05, + 4.31693251840473e-05, + 0.006685049011509828, + 3.1195312461147066e-05, + 0.01003009867110116, + 0.008459663950100319, + 0.005765427248372032, + 0.00011108092659027222, + 2.6302692348604317e-05, + 6.415363463656095e-05, + 4.3755520141460105e-07, + 8.949628991663872e-06, + 0.00015665184080786005, + 4.804107451422301e-05, + 7.790378110650544e-06, + 5.238644335009593e-05, + 6.842886526534604e-05, + 0.008832053506273614, + 8.76974162781124e-05, + 3.537073978440055e-05, + 0.006714025703901893, + 4.713844281200795e-05, + 2.988522877189406e-05, + 3.284174067021099e-06, + 3.331186062669915e-06, + 3.382565471615017e-06, + 3.5625642103399774e-06, + 1.8761291921232777e-06, + 0.00041322251086869325, + 1.6512283763228777e-06, + 2.6713893738560452e-06, + 8.629260269443107e-05, + 2.6797437391880606e-05, + 6.116235985298115e-05, + 3.336172852818558e-05, + 1.959778315481159e-05, + 5.752384109440578e-05, + 7.840140364717967e-05, + 0.006457783551165847, + 9.054949682981293e-05, + 4.581627553562489e-05, + 0.00817565329544597, + 0.0063393024704901345, + 6.309220182886564e-05, + 0.006382219318046553, + 5.9520335109750265e-05, + 4.810896760486375e-05, + 7.720124525653074e-05, + 4.7059955452611104e-05, + 5.583329608951207e-05, + 1.9269813166188358e-05, + 1.0003835897306816, + 3.2699517481831474e-05, + 0.008170787291719226, + 0.0001204369410194575, + 5.105886593647359e-06, + 1.4344908058887058e-05, + 3.4053751828548573e-07, + 1.78710524516326e-05, + 5.518628161876147e-05, + 1.8634392412703953e-05, + 3.2394319262609834e-05, + 1.8552101725878217e-06, + 3.401408920663357e-05, + 0.005622981904158817, + 7.174147412406096e-05, + 4.967058051043821e-06, + 0.009915476597542466, + 0.00013666632960500865, + 0.0010816938755075934, + 1.3926506083939243e-06, + 7.473978611656519e-06, + 0.0001087401656131354, + 3.8048334218202605e-05, + 0.006531871891578125, + 9.73683053803303e-05, + 6.039959268436595e-06, + 2.610848019012817e-05, + 4.0947561295588445e-05, + 4.0860568906730575e-05, + 7.511646879857002e-05, + 6.354986925006403e-05, + 0.004714008058034636, + 8.895582859343049e-07, + 4.5312749216232344e-05, + 0.009658027123380798, + 0.005894124979405421, + 2.7418689915131593e-05, + 5.5021419861820435e-05, + 0.0048535845820513075, + 0.0028935743279264107, + 0.00934538949869626, + 0.00408344249254145, + 0.006655999042995089, + 0.00013249423111395283, + 2.3587666620726074e-05, + 0.008487759100771796, + 0.009403452575118026, + 9.802407665341985e-06, + 6.938926754019389e-05, + 0.008664274028987562, + 0.00016526594818091914, + 0.009891145193876386, + 9.717628586914298e-05, + 5.4740304521921515e-05, + 0.00012679733007272525, + 0.00877995928880234, + 8.6638070301256e-05, + 0.006597636404530838, + 8.669584320980875e-05, + 0.0018705960191203576, + 0.00014399155572362174, + 0.0001246807859027139, + 7.30700720386402e-05, + 0.00011304389453428674, + 2.614368819921816e-05, + 0.00010504777710321347, + 0.00883762015458032, + 0.004193048518656666, + 0.006586798633828459, + 7.131459924188185e-05, + 0.011055507216417616, + 4.5797633600523134e-06, + 0.00010236722183861859, + 0.00013146806430429055, + 0.0001406914175397761, + 0.008526010875557077, + 3.224942461389203e-05, + 3.3593084677221634e-06, + 2.3911820891969514e-05, + 3.6191356626329917e-06, + 6.0660365159832946e-05, + 1.3640677423618407e-05, + 9.952230383561446e-05, + 1.0006292240898653, + 1.9269813166188358e-05, + 1.8660644278303113e-05, + 0.0024285342700700054, + 0.00010183618537375991, + 3.3857206954811586e-06, + 3.035721643280287e-06, + 2.3478257525078564e-06, + 8.453434392048e-06, + 4.968771746824327e-06, + 1.70842049509094e-05, + 5.744975875099374e-06, + 6.664276479027353e-06, + 1.9600997227302497e-06, + 1.8853793968401794e-05, + 2.875512039779854e-07, + 9.945503597024794e-06, + 5.068234755661218e-07, + 4.2994741473518604e-08, + 8.747730094430352e-05, + 9.92624527811888e-06, + 0.009927709865127338, + 2.398559145833957e-05, + 8.610593246983417e-05, + 5.663119294446125e-05, + 7.000542902825968e-06, + 0.007428312764656902, + 5.5649786206448084e-05, + 9.563744905355311e-06, + 0.00012240969635691026, + 0.011109083184725779, + 0.0068070609766084575, + 0.009015583601663752, + 9.19925473013565e-05, + 0.00042286073353053205, + 2.647290542189767e-05, + 0.0033100343649935427, + 0.006047231430546131, + 3.8941321970515616e-05, + 6.101829323367727e-05, + 0.004924228234314472, + 0.002007918983284649, + 1.1707850048249682e-05, + 5.890353781510846e-05, + 0.009403452575118026, + 4.920404084443367e-06, + 0.004300984806407466, + 0.008750829676035217, + 5.128940535339805e-05, + 1.0976407265594007e-05, + 0.0001730131989390535, + 2.6302692348604317e-05, + 0.0001226963844664554, + 0.003043158741887113, + 2.843055287948848e-06, + 9.171185102672263e-05, + 2.7758845583371817e-05, + 1.1253258306963982e-05, + 3.681470226756574e-05, + 5.481835722109314e-05, + 0.009349294168833915, + 7.245178783852634e-05, + 3.527685498118427e-05, + 2.6724663523493806e-05, + 2.8841903361718384e-05, + 0.0014978319467007927, + 4.35561991898656e-05, + 7.028971907680665e-05, + 0.00020232834080867164, + 1.2133601264377871e-05, + 2.5786673808607915e-05, + 0.012813625909626442, + 0.0010867090112958687, + 5.315905599966685e-05, + 3.7744090451044085e-05, + 7.774943916630372e-05, + 2.4967263474904864e-05, + 1.1796041331419004e-05, + 0.00403467118712389, + 1.0623499542258326e-05, + 0.00935065634121103, + 6.0942507176717e-06, + 1.4071215559756605e-05, + 1.0004218519602772, + 0.006124314870517229, + 0.0020986143266744518, + 1.4425087088570349e-05, + 7.582968560795405e-06, + 5.5673337197063254e-05, + 0.00944967063640076, + 3.2010750229393997e-05, + 5.8469634307341134e-05, + 1.8910845561383668e-05, + 0.009611182680216403, + 0.00010507947812848234, + 5.8064098366541744e-05, + 7.227804363621828e-06, + 7.339128572956441e-05, + 4.712760169925774e-06, + 6.279997697755538e-05, + 2.0880117819139736e-05, + 0.00011036325907642369, + 8.7581123233078e-06, + 7.37269460960388e-05, + 4.036902259548693e-05, + 8.2327661535784e-05, + 0.008398373248306222, + 0.007710383702448548, + 0.00814747827758538, + 0.005894124979405421, + 0.0009201478342575923, + 0.004092254801917959, + 0.009362403878072032, + 8.311017407393698e-05, + 0.00015183555325760058, + 0.007699851554496911, + 4.3088882703026115e-05, + 3.5918105428542704e-05, + 1.7753298709646568e-05, + 7.23500655525631e-05, + 0.009015583601663752, + 0.004213442564747276, + 7.806830397465771e-05, + 7.467161408604157e-05, + 1.6407079694044695e-06, + 7.007217650806319e-05, + 1.4313504055806974e-05, + 3.5011884286798186e-05, + 0.00017742194051728995, + 5.2766472087971785e-05, + 4.0365730413813014e-05, + 3.512428669001458e-05, + 1.0004028442802682, + 2.6870034435190565e-05, + 0.00790089919579962, + 6.807367336737874e-05, + 1.5309273798143577e-06, + 1.7199603304863812e-05, + 4.912466317868146e-05, + 5.636155674345554e-06, + 4.960478974867715e-06, + 8.569855998237978e-05, + 0.0024985379607832957, + 7.582968560795405e-06, + 0.009964003685006098, + 0.0011979513772529824, + 2.1511734531140814e-05, + 1.0291812167812526e-05, + 6.343447748240056e-05, + 0.0001594947964237924, + 4.852011383706507e-05, + 0.007329413538344493, + 5.895822008701363e-05, + 3.903353172128735e-05, + 8.780755167910766e-05, + 4.7595573412324026e-05, + 0.006649128264608228, + 9.795274955841379e-05, + 5.44501718787695e-05, + 6.124403934534732e-05, + 1.4892552717406243e-05, + 6.791867953427332e-05, + 8.085035701929519e-05, + 7.44429777262454e-06, + 0.0013328777498254356, + 0.003625097313221236, + 0.004318123334226994, + 0.004714008058034636, + 0.008482307511236168, + 0.00018927640511463451, + 0.007255851338711169, + 0.007790053939240377, + 7.308022435673637e-05, + 6.63684483593648e-05, + 7.144392268361971e-05, + 3.412817285756006e-05, + 9.283171180278325e-05, + 0.0054098623552808365, + 0.00011293821770791351, + 0.008806804007942875, + 6.224177478794206e-06, + 0.00018398308294319499, + 5.665925866907958e-05, + 6.265458442021338e-05, + 1.0994049097566663e-05, + 0.006740073564627112, + 0.005896520474143277, + 7.276064269692673e-05, + 0.00410196302462687, + 8.081471592653644e-05, + 4.9006522974493814e-05, + 3.7046042910373765e-05, + 7.792064738492659e-06, + 0.00010268918814354037, + 0.003003633597689924, + 3.5406938460700636e-05, + 0.003501122986141881, + 1.5766822889265075e-05, + 0.008643936765229692, + 0.005573949689002543, + 0.006554729173032643, + 0.00014836819241966453, + 0.00015854687935395274, + 1.2373222472231526e-05, + 9.334297135713388e-05, + 0.00022212792443789914, + 0.009640569433551922, + 9.175661661202585e-05, + 3.41674962668119e-05, + 0.0025456088283974092, + 0.003961812646855485, + 6.91575555913188e-05, + 0.0056954290527608375, + 9.731186228103503e-05, + 1.0005973513724646, + 5.481835722109314e-05, + 0.006615910659592654, + 2.7198580063679282e-05, + 2.656716793804512e-05, + 7.657450367907001e-07, + 0.0001585354537356698, + 3.9574365777364284e-07, + 7.91477008687552e-07, + 1.2513410853218346e-05, + 1.83301846932302e-05, + 6.603767343972547e-05, + 0.009498292054863657, + 6.472707200050332e-05, + 4.585871273468841e-05, + 3.843436658672674e-05, + 7.092098892430295e-05, + 0.00012167373322091522, + 1.2505689816741404e-05, + 0.009295247913139942, + 6.025817506004486e-05, + 2.8207005358445007e-05, + 2.6109734895727233e-05, + 3.9686777895044975e-05, + 0.00019557453083133506, + 0.005053902503785076, + 0.004926455754866431, + 0.0037547983552217367, + 0.0046012907750768986, + 0.008617980389554532, + 0.005071360807378818, + 0.002518284793421295, + 1.7334319453500232e-07, + 6.3632241538920716e-06, + 1.3307998776586948e-05, + 3.949787837533425e-06, + 1.7625297649508442e-05, + 0.003003633597689924, + 3.089131374698755e-06, + 1.2031158987471699e-05, + 0.0017603968215497067, + 2.467467834180957e-06, + 6.096919802748503e-05, + 0.008538605385254245, + 4.470787698074131e-05, + 6.18419543473045e-05, + 3.382565471615017e-06, + 4.6504964415883905e-05, + 0.007254780340154869, + 0.00014728026048875834, + 1.999352945584506e-05, + 1.9808276545164153e-05, + 0.004811970719232071, + 2.9853088250532845e-05, + 2.2837261326316132e-05, + 3.512428669001458e-05, + 8.13393389642432e-05, + 0.004507380604466488, + 3.8513269850336475e-05, + 4.816330275016268e-05, + 0.009821730370983375, + 2.1903716683254796e-05, + 6.244920472937696e-05, + 6.0194675001078164e-05, + 4.695475624562457e-05, + 4.27333714582164e-05, + 4.2287392648719884e-05, + 1.0820437241554723e-05, + 2.425848205412946e-05, + 1.01439085131741, + 1.4071215559756605e-05, + 0.0001841780532802329, + 0.007546820998713696, + 5.689189388216512e-06, + 0.005768832749769458, + 1.7916668586350402e-05, + 8.89251286687329e-06, + 1.035275889637705e-05, + 1.5211346445822785e-05, + 0.0026401284607189303, + 5.136316317798199e-06, + 1.4886813989585618e-05, + 9.286554580186971e-07, + 2.3553570961174583e-05, + 6.556057476266936e-05, + 5.179424309578726e-05, + 3.520187008799863e-05, + 5.895822008701363e-05, + 3.5472752645703684e-05, + 7.666284096464855e-05, + 4.2987315002756274e-05, + 3.5838112986402865e-05, + 3.503912963572349e-06, + 0.0005045514329730584, + 0.005574292792643197, + 0.005304731871977922, + 0.006044533045230626, + 0.004589697180653488, + 0.005511413361947338, + 0.00509972235949859, + 0.0005275661483209082, + 6.323381054764368e-05, + 8.274536257263668e-06, + 0.002360689141632851, + 5.458741613905111e-06, + 2.9750955246120755e-05, + 0.0011110333225029594, + 0.0001185655905667058, + 4.497861352315392e-05, + 0.01003009867110116, + 0.005695212786820327, + 6.373008761573134e-05, + 1.5200482383733676e-05, + 7.17937085081615e-05, + 3.652138838893042e-05, + 4.5579882391700233e-05, + 0.00815744384912862, + 0.0001268512726099513, + 8.6638070301256e-05, + 0.0077722776138475, + 0.0023218250123088584, + 2.6816888588111612e-06, + 1.9955252480012823e-05, + 1.7279945498281717e-05, + 6.600953573744792e-05, + 3.3409698001656547e-05, + 9.220435186640806e-06, + 0.0005756933364419036, + 6.052485692047022e-05, + 1.5696421917549157e-05, + 8.348550647548584e-05, + 1.0003106846527967, + 1.2133601264377871e-05, + 2.2821029286700005e-05, + 0.012006271154335118, + 0.0027052178017184657, + 1.2649299473656828e-05, + 5.7774606273442145e-06, + 7.131101283954011e-06, + 2.302150539269388e-05, + 2.1276079051268394e-05, + 2.243657506251215e-05, + 2.5151047401374303e-05, + 2.6479781054830162e-05, + 0.005614779437366768, + 2.108479944985597e-06, + 2.1569779244003335e-05, + 5.5549294698932425e-05, + 4.0225705652420965e-05, + 3.47873892853305e-05, + 1.0439763834962318e-05, + 8.7746997810561e-06, + 4.87111811559589e-06, + 6.052271248082022e-06, + 6.901220565399228e-06, + 7.794108624284254e-06, + 3.8655259029171693e-07, + 0.001080774936663883, + 4.7248459417462044e-06, + 0.0015357985919753874, + 0.006116514527944604, + 0.00028570917724010436, + 1.0000400120259487, + 0.007620250945392171, + 0.007847234151793583, + 0.009556394617234216, + 6.942689596137118e-05, + 4.258700237407619e-05, + 3.165157237555567e-05, + 2.2362468666237055e-05, + 5.981155540148864e-05, + 4.849876254314921e-05, + 2.7583452473090147e-05, + 9.177955235317567e-06, + 7.276203856300719e-05, + 0.002882958045542563, + 7.63198582473916e-05, + 1.7494555237466507e-05, + 2.170212323715844e-05, + 0.004325677183490168, + 2.4771419462574535e-05, + 9.824640203003823e-05, + 4.558479926457905e-05, + 0.007696421638836545, + 0.00725057399154552, + 0.005641947917987453, + 0.0040844313409666155, + 0.006649128264608228, + 0.009963497689544864, + 0.00011225674094685073, + 7.636203446290959e-05, + 3.1188552603485446e-05, + 8.713054812012184e-05, + 2.6185861521000763e-05, + 5.878795178602236e-05, + 5.890353781510846e-05, + 1.0882148447506776e-05, + 6.542968016277152e-05, + 0.0001581423678117155, + 5.298779824764253e-05, + 6.104874933017689e-05, + 1.0486260105233297e-05, + 0.00010733714305272089, + 3.952316376324563e-05, + 9.952230383561446e-05, + 5.583329608951207e-05, + 3.689155146280462e-05, + 0.014410087504995148, + 4.5559832168017325e-05, + 2.2764179043432686e-05, + 6.543058866391555e-05, + 3.430793407922378e-05, + 2.2837261326316132e-05, + 4.0365730413813014e-05, + 0.009636119219212608, + 0.005189010470211977, + 0.007887920773598681, + 2.8923941111746002e-05, + 0.0057750436745369355, + 5.1312749912381697e-05, + 0.0001805488747476753, + 4.497641852423167e-05, + 4.045190920950058e-05, + 0.003804170827353817, + 6.955184983029764e-05, + 2.1665009509667407e-05, + 4.2864901433654665e-05, + 1.0003829763539198, + 5.880937526079813e-06, + 0.00629538472814543, + 5.524170723711119e-05, + 5.321768311467811e-05, + 1.151237528350908e-05, + 8.831803944007171e-07, + 1.049107635947085e-05, + 2.2727801295909092e-05, + 6.664276479027353e-06, + 1.0481439960144256e-05, + 2.6075990744894606e-06, + 1.8520492490083216e-05, + 2.1793448813973866e-05, + 9.176872048322657e-06, + 2.116693775127853e-05, + 0.002313141822622935, + 2.200821759837018e-05, + 1.805138943886443e-05, + 1.3780010086691152e-05, + 3.1283205561362908e-06, + 8.464235497657132e-06, + 8.111616680886158e-06, + 2.4636259992210228e-05, + 0.0029471484685646876, + 1.4482501638671528e-05, + 2.4723271872059743e-05, + 0.0014970770754504084, + 0.0029935243072698762, + 0.0020874736505889233, + 2.983059461560402e-05, + 2.2622216737783084e-05, + 2.627011625477693e-05, + 5.312316031361682e-06, + 2.225316986181994e-05, + 3.102418440017793e-05, + 2.2283096906311314e-05, + 0.007495164151567807, + 0.008963041275584496, + 0.0010589697528595465, + 0.005221329997523486, + 0.008805068794976455, + 0.00983176233371314, + 0.008398373248306222, + 2.149929346326834e-05, + 0.0048489996336509, + 2.2912513589703315e-05, + 0.0040844313409666155, + 5.330234599939667e-05, + 3.061178252104105e-05, + 5.3005380202982966e-05, + 2.519599844706269e-05, + 0.0025612490314566227, + 1.877880444362138e-05, + 2.6583074685513483e-05, + 8.637677701681919e-05, + 4.268506539575916e-05, + 0.005071360807378818, + 1.2594651748272449e-05, + 9.64121073613786e-06, + 4.860647658428452e-05, + 0.0006170670814896797, + 5.5540199060968216e-05, + 0.005621853829576654, + 3.710823378319444e-05, + 4.957894886944058e-05, + 0.0027637787011062917, + 1.0001133734472036, + 9.283171180278325e-05, + 4.7459302796212956e-05, + 0.005892857278628511, + 6.242079514647868e-05, + 3.0768169071865856e-05, + 0.003949451860214621, + 1.0730957657725968e-05, + 3.0438108375714784e-05, + 0.00932536085802224, + 4.843570844089803e-05, + 4.8413826881802706e-05, + 7.475390977604764e-05, + 8.154231257388808e-05, + 4.1662899268953135e-05, + 3.4937391624894854e-05, + 4.794364658652151e-05, + 8.949778834480208e-05, + 0.009959454332578336, + 3.4278764461559064e-05, + 9.671370476470335e-05, + 0.006384550706521437, + 0.003837912559068474, + 0.0016826044433800413, + 0.009605685363234352, + 0.0010195254958027743, + 0.006531871891578125, + 0.001344901064955023, + 0.006803726876170835, + 0.003224498097106496, + 0.008630783726605808, + 4.3422810041187425e-05, + 3.2432119128314313e-05, + 2.2912513589703315e-05, + 0.005641947917987453, + 5.621054680408905e-05, + 2.430199355672523e-05, + 2.174789309648852e-05, + 1.0371090875917845e-06, + 0.0018398040804846942, + 3.9616146869272896e-05, + 2.2662814589453177e-05, + 5.679787494029275e-06, + 2.0904964629571314e-05, + 6.482136076334683e-05, + 0.002532528169657162, + 0.00011067717192639689, + 3.194862700383684e-06, + 3.244198568147392e-05, + 8.978547674713963e-07, + 5.9772051130068166e-05, + 6.893059851074438e-05, + 8.47381590041747e-05, + 0.006639242346381749, + 1.0003224726853233, + 1.7625297649508442e-05, + 0.00010268918814354037, + 0.00013713865786819753, + 0.00010091988110382644, + 0.009118215936367427, + 2.47563889274485e-05, + 3.118964717770214e-05, + 2.272185625473179e-06, + 3.3864510266791785e-05, + 2.357371016367183e-06, + 3.617988384313475e-05, + 1.4998249072389926e-05, + 0.005641913561175485, + 5.2689843753786996e-05, + 0.004030203448740924, + 0.002341990597880902, + 1.70170076060978e-05, + 4.302624219575653e-07, + 4.334605723171568e-05, + 6.045509972018361e-05, + 0.006157260534451727, + 6.444748122258493e-05, + 3.8701093554956196e-05, + 1.990227659369478e-06, + 8.886247607167789e-05, + 5.0907829920540994e-05, + 0.009863281735601262, + 0.000145030445193013, + 1.2380803640812112e-05, + 8.44689701773998e-05, + 1.2510973873916954e-05, + 4.7368254369153736e-05, + 7.174832499906487e-06, + 4.904713082344558e-05, + 3.982086179258424e-05, + 4.279407556548083e-05, + 5.9341106802033e-05, + 5.545703057791173e-05, + 9.830265710848967e-05, + 7.097168045875709e-05, + 0.006728550378096911, + 0.0018061101135306693, + 0.0009286021346292216, + 0.0005778280391964555, + 0.009043811346655235, + 0.006223166372485518, + 0.005638980724112857, + 5.5266816322073946e-06, + 0.0001071678049589081, + 8.80187196272973e-05, + 6.0474015681588885e-05, + 0.004140227199330784, + 8.646002429487938e-05, + 0.00014266893334484952, + 0.00983176233371314, + 8.2327661535784e-05, + 2.657005871295784e-05, + 0.005316713458998503, + 0.005263923874568061, + 1.3166789154235854e-05, + 2.8191053266072524e-05, + 0.003554991012200417, + 3.5073730595340513e-05, + 1.600133368842961e-05, + 0.00559334195236974, + 0.00679557347143215, + 1.0003877656218436, + 4.2864901433654665e-05, + 1.5398702046158918e-06, + 0.0017204913863231868, + 5.263317597042702e-06, + 7.412144330241568e-06, + 2.8897167742560854e-05, + 1.2642191068013989e-05, + 2.8726589223701957e-05, + 1.3325165197173029e-05, + 2.9942269848555094e-05, + 1.8052719752213758e-05, + 2.2413973752318735e-05, + 0.009339513385827183, + 2.956871823131433e-05, + 3.4857573364954245e-06, + 0.009965742385508356, + 5.8064098366541744e-05, + 4.543184892775909e-06, + 0.008534519561254493, + 0.0005045514329730584, + 0.0004915262872471038, + 1.0957915206616842e-05, + 3.485116857707309e-06, + 4.103470307486917e-05, + 3.449505512877965e-05, + 0.006223166372485518, + 1.1136795167012167e-05, + 4.917905109956431e-05, + 0.0001391716422599186, + 2.134225602766022e-05, + 8.181076850756026e-05, + 0.003107753790333846, + 4.3871349822661094e-05, + 5.393172876158273e-05, + 2.4937042062898712e-05, + 1.0185038332521287e-05, + 0.00017606248522604556, + 1.3878912028461374e-05, + 0.006125638375565562, + 8.551342755536584e-06, + 5.878795178602236e-05, + 0.008487759100771796, + 0.0031757414411978605, + 3.4841133653436712e-06, + 8.017101377762257e-06, + 7.048804349060899e-05, + 0.00010363848198497155, + 0.0001730131989390535, + 6.172582231664433e-05, + 2.160030838240172e-05, + 2.5591472821463486e-05, + 0.007337281118937193, + 5.7250640224978076e-05, + 0.00012396204296597862, + 6.842886526534604e-05, + 0.00557935728804668, + 8.40175663732779e-05, + 0.0029778643265331926, + 6.278689984787101e-05, + 0.008723263430352006, + 4.2093820849666625e-05, + 0.00010989645420088088, + 0.00021230858415933394, + 4.543103795564365e-05, + 0.006639242346381749, + 3.949787837533425e-06, + 7.792064738492659e-06, + 2.545741842614761e-06, + 3.0625251536410894e-05, + 0.00224369175698486, + 5.392157334207365e-05, + 2.0196582070012896e-06, + 3.511630656969946e-05, + 9.071001496701286e-05, + 5.826260311688797e-06, + 8.051282580337352e-05, + 0.00022871279642392865, + 1.400441455646313e-06, + 5.970059231580564e-05, + 2.3294854918457073e-05, + 3.9379968694698984e-07, + 1.0005122858742035, + 5.140845459602858e-06, + 8.102003010137707e-07, + 0.00014456637776158663, + 0.00032154997618342605, + 1.188084764263294e-05, + 0.004316602141437835, + 1.8808918578478595e-05, + 3.6211453017926045e-05, + 0.005005808894482987, + 0.00188385009334873, + 0.006948275793281259, + 0.0019574602954816533, + 0.008837333888313868, + 0.002127269661302731, + 0.00821078361998241, + 1.0321254222034239e-05, + 5.203493787178862e-05, + 2.5997154839160077e-05, + 4.9454216424904526e-05, + 0.0027637787011062917, + 3.412817285756006e-05, + 3.669353473460797e-05, + 3.293840406858189e-05, + 5.411376477769995e-05, + 1.765487079884287e-05, + 3.9117221191864173e-05, + 7.376706734812109e-05, + 0.006976247125852938, + 1.849718928212902e-05, + 0.0065922905508567185, + 7.501128852404918e-05, + 5.4053340630327065e-05, + 0.008338421645317543, + 0.0001077222898127599, + 0.0081575359016717, + 5.253136891324345e-05, + 6.18419543473045e-05, + 3.331186062669915e-06, + 0.00011723158728588356, + 4.0924344042050054e-05, + 0.00852430417569119, + 3.6018542032361736e-05, + 7.846915829260045e-05, + 7.007475291609435e-05, + 1.4040406457210514e-05, + 1.2186539544715434e-06, + 6.497358014457847e-05, + 6.552162915475501e-06, + 1.3483569982537823e-05, + 3.9956313402664994e-05, + 3.4374901122417665e-05, + 3.7277412385885987e-06, + 1.0001762329550616, + 3.9379968694698984e-07, + 6.43586700597802e-06, + 4.662805809938742e-06, + 0.006311483244382031, + 0.001505445880622247, + 8.735938285280393e-06, + 1.0003977443525997e-05, + 0.004015417380052825, + 0.0001950264761052023, + 6.057074090214067e-07, + 5.702868336995201e-07, + 1.034996127455612e-06, + 1.035275889637705e-05, + 3.4053751828548573e-07, + 0.003013917957663592, + 1.4092747286854697e-05, + 7.944851687717692e-06, + 8.241318856450491e-05, + 2.0365071098452272e-05, + 3.320383246689815e-05, + 6.0060345185960196e-05, + 2.282562280992101e-05, + 2.6938937550086616e-05, + 2.1943796847118125e-05, + 5.718269734234039e-05, + 4.0225705652420965e-05, + 3.539059879489178e-05, + 0.006712215563463177, + 0.006834759289973527, + 0.004525181008797196, + 0.0090398684568361, + 0.004193107812289965, + 3.611195890619833e-05, + 4.315960899625176e-05, + 2.6676388625680194e-05, + 1.5425238648487882e-05, + 4.239530929527569e-05, + 0.00014266893334484952, + 4.036902259548693e-05, + 5.551330944747475e-05, + 0.00706018696690996, + 0.0048489996336509, + 0.00725057399154552, + 4.7595573412324026e-05, + 7.186162010213901e-05, + 9.141793619796793e-05, + 8.181005804706189e-05, + 2.1441172414522936e-05, + 3.2648313100976816e-05, + 9.658299046784831e-05, + 0.00013607125408058739, + 8.960823855955737e-06, + 6.482136076334683e-05, + 0.009526728664990757, + 4.5049929939845996e-05, + 0.00012431712551823294, + 0.00012382073634337326, + 0.0011849502227732189, + 4.985196467268206e-05, + 8.500073672303659e-05, + 4.1517316058143174e-07, + 4.302550318241803e-05, + 8.133660879343081e-05, + 5.238644335009593e-05, + 1.4874198614900185e-05, + 6.381972097879172e-05, + 4.146895381538172e-05, + 0.007812569537828521, + 5.6797153003323836e-05, + 2.1828240989408474e-05, + 2.3093786328915213e-05, + 0.0013164853450756745, + 0.005741093990493656, + 1.0777056264245487e-05, + 3.7073972839090896e-05, + 3.4622617627696845e-05, + 8.820430628239255e-05, + 1.0004204390472344, + 3.7277412385885987e-06, + 2.3294854918457073e-05, + 1.05857717104082e-05, + 7.669424770295681e-06, + 3.7121389807687816e-05, + 0.0025027531135822763, + 2.9691546746360525e-05, + 2.8683298392619073e-06, + 1.9556388210223286e-05, + 4.700870048947649e-05, + 7.916043971640084e-06, + 3.0086491323618898e-05, + 9.293417333806772e-05, + 4.498148682255461e-05, + 1.777519615716201e-05, + 0.004956907702287139, + 0.003402162384553347, + 0.004538686199959361, + 0.008819032847634595, + 0.0023922321366585796, + 1.773236913896812e-05, + 0.007690836904536741, + 0.00914181407893777, + 1.7297893003350107e-05, + 1.879939226741259e-05, + 5.7897047412305844e-05, + 0.002127269661302731, + 1.7466550890309995e-05, + 6.595216521287041e-05, + 3.25768819028559e-05, + 8.283092032568344e-05, + 9.197717876650045e-06, + 4.577243436511334e-05, + 4.239530929527569e-05, + 8.646002429487938e-05, + 0.008805068794976455, + 7.37269460960388e-05, + 2.1162142534132394e-05, + 2.1613058386334702e-05, + 5.243876354047514e-05, + 2.062861723670921e-05, + 1.2028922085198997e-05, + 0.0009628796387270497, + 8.551342755536584e-06, + 2.6185861521000763e-05, + 1.1707850048249682e-05, + 2.3587666620726074e-05, + 3.0800189049306255e-06, + 1.851882951395248e-05, + 0.009782309454680381, + 3.019698382825305e-06, + 9.297493441906668e-05, + 6.948461639102615e-06, + 7.16707002124421e-05, + 0.00010580887260818803, + 1.1792268179702386e-05, + 1.298044941180189e-05, + 0.009382044831691094, + 0.0035186077058957845, + 2.9882322235776724e-06, + 1.3711952075214602e-05, + 3.615448220528084e-05, + 1.0002074290941974, + 1.0994049097566663e-05, + 1.310240486264126e-05, + 0.0016311467511667876, + 2.6534495447257202e-05, + 1.8884198800659427e-06, + 7.177313382859093e-06, + 0.007428312764656902, + 0.0010816938755075934, + 0.0013096420345198375, + 6.085174025597421e-05, + 1.592458114561165e-05, + 8.252627901419628e-06, + 5.064743170214215e-06, + 3.161582560257577e-05, + 0.009043811346655235, + 7.921050259260159e-05, + 3.3803783166902323e-06, + 6.029281872575666e-05, + 2.0904964629571314e-05, + 0.01574616148972817, + 6.060744515201521e-05, + 2.407729671365154e-06, + 1.6446658316063207e-05, + 0.009676960075387354, + 0.005204560921393831, + 6.720359856629058e-05, + 7.397498922067364e-05, + 0.0022893814596128765, + 7.172381736447735e-05, + 0.00020214142289124118, + 3.615448220528084e-05, + 6.265458442021338e-05, + 8.310218795996274e-05, + 8.657135190825022e-06, + 7.581259308717127e-08, + 6.174032240952402e-08, + 6.303672765175599e-06, + 4.529426116266005e-05, + 7.790378110650544e-06, + 1.2737606264021523e-06, + 5.31320982239297e-05, + 0.009300587252411117, + 0.0011618057425408913, + 8.167398243961086e-06, + 0.00800148732862001, + 2.2852157316310878e-05, + 8.784487795116046e-05, + 0.005215496332165455, + 6.471299638717376e-05, + 1.537618440707853e-05, + 0.0011141911866881654, + 9.379407508341833e-05, + 3.430793407922378e-05, + 2.9853088250532845e-05, + 5.2766472087971785e-05, + 0.00010459660272650717, + 0.0067128941927253345, + 0.00011889205758591477, + 8.377027048123183e-05, + 1.839704114108649e-06, + 1.5967932983625997e-07, + 4.571840485343565e-05, + 1.7888324242610096e-05, + 1.7667422410700649e-06, + 1.9568895044000717e-05, + 1.0003300690091148, + 8.820430628239255e-05, + 3.4374901122417665e-05, + 5.970059231580564e-05, + 8.43286912301128e-07, + 7.528097178324361e-05, + 1.5799611749605832e-05, + 0.007106771127311314, + 0.0015414752433633417, + 4.7874678062921025e-06, + 8.180534967924788e-06, + 1.2663767548591473e-05, + 8.89251286687329e-06, + 1.2288862401220086e-06, + 1.5259333259623386e-06, + 1.538762457161008e-06, + 1.5889218365970699e-06, + 1.7431546902319922e-06, + 1.437187119899864e-06, + 3.3445602506082165e-05, + 1.2383720746665643e-05, + 6.751158464193462e-07, + 8.021012974644137e-05, + 2.2954687209557798e-05, + 7.845275276930699e-05, + 3.084836036525695e-05, + 0.00819832382907284, + 0.004509471864731448, + 0.007211592682138772, + 0.001080774936663883, + 2.7505844109233254e-05, + 0.006896939223886141, + 3.7303041062276185e-06, + 2.2893352845326236e-06, + 2.2659425801912526e-05, + 2.2756773597648387e-05, + 2.9258570574108967e-06, + 0.00639840042891731, + 2.880137609004941e-05, + 1.9728161055912034e-05, + 4.577243436511334e-05, + 0.004140227199330784, + 0.005221329997523486, + 3.000535237006113e-05, + 2.858263139481979e-05, + 0.008434966654025614, + 6.409491851623345e-06, + 2.1784560596789215e-05, + 7.23500655525631e-05, + 0.00010548489137167106, + 2.6958770302895138e-05, + 5.923465003761426e-07, + 0.00015933951733862196, + 8.394452031494062e-05, + 9.705123470081156e-05, + 2.6429175994417655e-05, + 0.0033100343649935427, + 0.00934538949869626, + 0.004432264135737421, + 1.2854505722798077e-05, + 0.00044431236058949623, + 0.0014745260047490116, + 8.884186737477239e-06, + 5.3386122069419955e-05, + 0.0058248967139245935, + 3.390535436114262e-05, + 2.7398964806537252e-05, + 2.2529968517451576e-05, + 0.00018257796352744485, + 1.0002684437688334, + 4.529426116266005e-05, + 8.133660879343081e-05, + 0.00012396204296597862, + 4.804107451422301e-05, + 7.854924150935622e-06, + 9.20890698185028e-05, + 3.779260422389367e-05, + 3.3996998096963766e-05, + 0.007214311791655111, + 6.518935957422784e-05, + 3.87764533289644e-06, + 4.4185831029026516e-05, + 1.473775828964842e-05, + 4.552346662069953e-05, + 0.0022208218820898985, + 7.66947463026765e-06, + 2.1638565938509677e-05, + 3.3858432172866734e-05, + 1.8834701174318686e-05, + 0.0072660443733186895, + 1.70170076060978e-05, + 1.3348925708514831e-06, + 4.4092287379431386e-05, + 1.9900331944692724e-05, + 2.7545876117955095e-06, + 3.0294756990803786e-05, + 1.9888207898990585e-05, + 3.5181354807464185e-05, + 9.962891593689917e-06, + 0.005063505532808123, + 1.3142350549209993e-05, + 3.807858887188459e-06, + 3.86650835506941e-05, + 0.004483194454930572, + 0.008560723438005933, + 0.009915476597542466, + 0.003516730555426826, + 4.831905131488414e-05, + 1.3612387774774914e-05, + 5.654731790071036e-05, + 0.007563873760525239, + 5.7897047412305844e-05, + 5.70986654635919e-05, + 4.580812393541896e-05, + 0.00906453844049525, + 5.794297254880646e-05, + 0.002711227563482645, + 4.268506539575916e-05, + 6.294100436684671e-05, + 0.000144358736576273, + 2.8887654452486578e-05, + 1.3444929746094877e-05, + 2.1784560596789215e-05, + 0.0068070609766084575, + 6.619848851781917e-05, + 5.6550313371836705e-05, + 0.00450565985570487, + 9.025925841730478e-06, + 8.077315543870918e-06, + 5.4622505552109676e-05, + 0.000515067873673531, + 8.417123614646206e-06, + 4.257501182633146e-05, + 8.960823855955737e-06, + 0.005543813403275388, + 0.004427875840624922, + 0.004622968368555527, + 0.0033598743762273376, + 0.005683899652143301, + 5.493834356565433e-05, + 0.006976247125852938, + 2.1376951580614815e-05, + 0.0034405225796962364, + 5.2530022158616034e-05, + 6.513160904765917e-07, + 2.3909045231668042e-05, + 9.080223448683296e-05, + 4.543103795564365e-05, + 8.47381590041747e-05, + 3.7046042910373765e-05, + 2.279851190786204e-05, + 0.0001035434114937968, + 0.015694012931671365, + 0.002314784955476499, + 0.0001351869158332422, + 2.0501915098524828e-05, + 4.159463451217095e-05, + 1.0148477207275832, + 9.379407508341833e-05, + 6.543058866391555e-05, + 0.004811970719232071, + 0.00017742194051728995, + 5.002017546540117e-05, + 0.015334495722877418, + 0.00010411803164345695, + 5.208047344244813e-06, + 2.272185625473179e-06, + 3.990835206191733e-06, + 6.256499749409017e-05, + 2.2362468666237055e-05, + 1.7541023247471673e-05, + 4.328259607237442e-05, + 7.010848482190836e-05, + 5.959071178316483e-07, + 6.915969718176827e-05, + 1.805138943886443e-05, + 0.00013449665841190302, + 1.7419893057828467e-05, + 6.509424345376619e-05, + 8.546051687200953e-05, + 4.901761593493149e-05, + 0.008087170381398456, + 0.00010507947812848234, + 7.868933400378229e-05, + 0.00951396970838286, + 0.007820308463700465, + 0.008774287957556134, + 0.00915211765251319, + 2.451747705959345e-05, + 6.689722171556712e-05, + 5.616434308975793e-05, + 5.551480015170474e-05, + 0.006489894070843838, + 5.687817152330025e-05, + 0.005670327835012276, + 1.6946522582387045e-05, + 0.0071044223349299536, + 0.00013392222673275266, + 6.785098793438811e-05, + 0.00023047033185757222, + 2.035577968764197e-05, + 0.00015039691379098406, + 8.505517007946614e-05, + 7.51821387975411e-05, + 0.00877995928880234, + 0.009276745414995192, + 0.0006052639682745074, + 3.5405275164337536e-07, + 2.408253652537229e-05, + 0.00013940450826643473, + 7.241693757591757e-06, + 0.00018257796352744485, + 6.303672765175599e-06, + 4.302550318241803e-05, + 0.00015665184080786005, + 0.009360155982221886, + 5.6973288496865745e-05, + 3.108609273131704e-05, + 0.005471422643999203, + 3.8142605394287925e-05, + 2.6896745391710108e-05, + 7.443863429482305e-07, + 5.6847103838554745e-05, + 9.080223448683296e-05, + 0.00021230858415933394, + 6.893059851074438e-05, + 1.3307998776586948e-05, + 4.9006522974493814e-05, + 1.3592364534603364e-05, + 0.007559658489312481, + 5.7243482353636986e-05, + 3.6438697281287586e-05, + 0.002385822926232189, + 3.0255537649567676e-05, + 2.619931980962859e-05, + 2.0225316812531166e-05, + 2.5078590911148673e-05, + 1.3979739129546218e-05, + 0.007478559973594072, + 5.130159250113782e-05, + 1.945367154999441e-05, + 1.000693637634093, + 8.348550647548584e-05, + 0.00020232834080867164, + 0.00010448432381559467, + 0.004220681095862514, + 4.8084221300370924e-06, + 2.7871435289212096e-06, + 5.961322642576858e-06, + 9.647701407466116e-06, + 6.06595718656155e-07, + 4.5744979932388834e-06, + 2.863731908220287e-05, + 3.2010750229393997e-05, + 1.0909411956329585e-05, + 1.5112175287129863e-05, + 2.1511734531140814e-05, + 5.732217749423728e-06, + 0.004967052543479441, + 0.008172434288961817, + 3.315445346260335e-05, + 3.0110710713604018e-05, + 4.195497660194445e-05, + 0.008480512053198986, + 5.6265324282509934e-05, + 0.0031233784413476104, + 3.711164678999354e-05, + 5.7954976624182934e-05, + 0.0013023827143545978, + 1.6648212270453975e-05, + 1.7298730204288893e-05, + 0.007563873760525239, + 1.879939226741259e-05, + 0.008837333888313868, + 3.102418440017793e-05, + 7.256143633448298e-05, + 4.832756745625646e-05, + 1.9067817376664148e-05, + 7.641123007827406e-05, + 0.0022039957819478574, + 0.008459447326873511, + 7.51821387975411e-05, + 0.0001268512726099513, + 0.00012679733007272525, + 0.008106382247233694, + 4.00526336990222e-05, + 0.0006679276000648783, + 0.005937531341288544, + 4.1413939487704946e-06, + 0.00012245212128581448, + 0.006457783551165847, + 6.6127942078603766e-06, + 5.666986257986792e-05, + 0.00010829417935510544, + 0.007342720305307154, + 8.804415323161467e-05, + 7.08690593428671e-05, + 9.546069637881966e-05, + 2.840085319715022e-05, + 5.054622426696256e-05, + 9.885006688172613e-05, + 0.0034103459841710953, + 0.003163709767952356, + 3.087999998307821e-05, + 0.00679557347143215, + 2.1665009509667407e-05, + 3.3215104390041955e-06, + 0.005873673790252434, + 0.00012261209406726128, + 1.8146882092870154e-05, + 0.001098848492576027, + 9.486510994712678e-06, + 2.9776421787722422e-05, + 6.276963263902074e-05, + 0.006806823890020743, + 1.8507845222880758e-05, + 0.006358998048098247, + 5.813175701629659e-06, + 1.000951998583775, + 2.425848205412946e-05, + 6.0942507176717e-06, + 6.798716119619028e-05, + 0.0034194658432815557, + 0.0005948016310838955, + 5.484361314441554e-06, + 4.611686965275673e-06, + 8.831803944007171e-07, + 5.281082680604117e-06, + 4.202569748398294e-06, + 0.002307342766061188, + 2.2130008087780147e-05, + 1.050353687539633e-05, + 2.3478257525078564e-06, + 1.2456287254784247e-07, + 2.4062175400161237e-05, + 2.9942269848555094e-05, + 3.165157237555567e-05, + 1.5324605124138993e-05, + 0.0028681574720703117, + 2.8449049102145023e-05, + 2.656716793804512e-05, + 3.746600959227912e-05, + 5.2996539510238614e-05, + 3.9533904636675386e-05, + 4.7675626079801785e-05, + 0.00010228567311313031, + 5.2572209354611396e-05, + 0.009893406378396238, + 3.7152036280563222e-06, + 5.718269734234039e-05, + 5.5549294698932425e-05, + 6.129640226876825e-05, + 1.839517068585072e-05, + 4.6148138070912694e-05, + 2.5866209626581253e-05, + 0.00010136556747827229, + 9.842205408662057e-05, + 0.009613824701437153, + 3.5019940290114174e-05, + 6.547496387070687e-05, + 0.006796385353731588, + 0.0029280711260348193, + 0.008164029212026792, + 0.0003816885689634088, + 0.006438821015870284, + 0.004376133859150393, + 0.007329413538344493, + 0.004478441911544396, + 0.009530370211735932, + 0.005343984402739459, + 0.004455228636882102, + 0.00036269699602366277, + 1.8017238244775715e-05, + 0.0033535155434166993, + 0.00011970197773206852, + 2.2006625594661942e-05, + 5.2892774698968354e-05, + 5.9341106802033e-05, + 6.85439791623251e-05, + 7.084291599007136e-05, + 4.794687006752578e-05, + 1.984736516522655e-05, + 0.007791658840435856, + 6.177626701645455e-05, + 3.1195312461147066e-05, + 0.0037110609109953898, + 4.9810654609521915e-05, + 2.9901307237916217e-05, + 7.664256895218439e-05, + 3.3428408975038574e-05, + 4.865829265027054e-05, + 1.0038200792272656, + 0.008459447326873511, + 8.505517007946614e-05, + 0.00815744384912862, + 5.4740304521921515e-05, + 0.00829695684417064, + 4.1637468351522585e-05, + 4.7185395178301896e-05, + 4.611686965275673e-06, + 8.735938285280393e-06, + 3.118964717770214e-05, + 1.151237528350908e-05, + 6.883962337457583e-05, + 5.478106217644566e-05, + 6.526940843802335e-05, + 1.3190033228713383e-06, + 4.673612943620091e-06, + 1.9953765773175086e-05, + 8.569855998237978e-05, + 1.0436275612713423e-06, + 8.645709649879834e-07, + 1.8874859837226256e-05, + 3.809734129067859e-05, + 2.9475059591468917e-05, + 1.4886813989585618e-05, + 1.9833815079607923e-06, + 0.006208188035058918, + 5.010532596552045e-06, + 5.763283032282485e-05, + 0.014888439801268014, + 0.006083500465316787, + 0.0019675877767165563, + 0.008087170381398456, + 0.005063505532808123, + 0.009611182680216403, + 0.0025955043327308257, + 0.0007520202876280246, + 0.007636030670880136, + 0.008572476068270435, + 3.191972451121407e-06, + 8.573114353939069e-06, + 3.243705960449583e-06, + 4.25828037495546e-06, + 8.274181744819948e-06, + 2.244436982658596e-06, + 0.007812326963274855, + 4.907519256652523e-05, + 0.0009434926438126656, + 7.040445704723166e-05, + 8.193477229159464e-05, + 4.853197343199784e-05, + 6.671127692826823e-06, + 7.717911239137264e-05, + 0.00011728024289987551, + 0.00010792890575392393, + 6.86394345037373e-05, + 4.0024903276032146e-05, + 0.0009628796387270497, + 0.006125638375565562, + 8.713054812012184e-05, + 0.00013249423111395283, + 0.005005735433951281, + 6.161934999922442e-05, + 0.009065125655137866, + 1.4148013360018128e-05, + 0.00014331101054724154, + 2.6320072321074858e-05, + 8.09437286214573e-06, + 8.315043882107788e-05, + 4.231435282329788e-06, + 8.39792052135796e-05, + 1.1628614234344098e-05, + 3.802634538910261e-05, + 8.255379593155514e-06, + 8.169223873696375e-06, + 1.000314224235949, + 5.813175701629659e-06, + 1.0820437241554723e-05, + 0.00935065634121103, + 1.2083727420730855e-05, + 0.0015286668560874448, + 0.0004466121637889875, + 4.18806829585507e-06, + 3.831561999862129e-06, + 2.357371016367183e-06, + 3.1610493407164625e-06, + 2.8591836887176645e-06, + 3.6872163354419606e-05, + 2.9786294750743373e-05, + 1.3652454735223686e-05, + 7.442826532368355e-07, + 6.915969718176827e-05, + 7.845275276930699e-05, + 5.144251287968885e-06, + 1.2569418638884622e-05, + 2.0337974678940336e-05, + 3.63114731874677e-05, + 7.48601038810743e-05, + 0.003910368997623035, + 0.0031276072742181596, + 0.006076959034976081, + 7.45391906916999e-05, + 0.0023320464877719343, + 0.004376133859150393, + 3.520187008799863e-05, + 5.142917252934526e-05, + 5.7314371833237866e-05, + 1.9429607794752888e-05, + 1.5817505577012435e-06, + 4.281663812917758e-05, + 4.186941554450491e-05, + 8.637677701681919e-05, + 0.008617980389554532, + 2.1402630556665295e-05, + 0.00010908601690073171, + 5.977129380080876e-05, + 0.0033216559080485038, + 2.006953745216285e-05, + 4.257501182633146e-05, + 5.679787494029275e-06, + 0.002246202067281234, + 1.0605426200807425e-05, + 2.8292786126268883e-06, + 4.466158367344553e-05, + 8.20396676808335e-06, + 0.007431416098998833, + 5.464906557027554e-05, + 3.952316376324563e-05, + 1.3640677423618407e-05, + 4.7059955452611104e-05, + 0.0001502896301746381, + 0.005788183044113987, + 9.160651790060595e-05, + 4.862973927123171e-06, + 0.009325200209838529, + 1.5043418041883717e-05, + 3.622517432977772e-05, + 8.087032305166897e-05, + 9.731186228103503e-05, + 3.681470226756574e-05, + 0.006026699609445051, + 4.13354242155286e-05, + 0.00013284441629376648, + 7.017012962279487e-05, + 0.007838582074793548, + 0.0001692474180237501, + 5.344940792856073e-05, + 1.0003473717192444, + 1.9568895044000717e-05, + 3.4622617627696845e-05, + 3.9956313402664994e-05, + 1.400441455646313e-06, + 2.5948670913940536e-05, + 1.6582000373062033e-05, + 1.0572160482083514e-05, + 0.009395193044154506, + 1.958894495909591e-05, + 6.9481289418868506e-06, + 2.0365071098452272e-05, + 1.4998249072389926e-05, + 1.0443226802502651e-05, + 0.004026712082539978, + 4.238725016304624e-06, + 3.981529552547065e-05, + 3.0345710219469527e-05, + 0.007331530231065854, + 0.0026905222874216293, + 0.007233946888549284, + 0.003377191445622171, + 0.009613824701437153, + 0.00713900933396598, + 0.0011279691886657696, + 0.006810501117304453, + 7.429189137403037e-07, + 2.8372766896015674e-06, + 8.003274135724149e-06, + 1.3444929746094877e-05, + 6.409491851623345e-06, + 1.7753298709646568e-05, + 1.1931230595413092e-05, + 3.434636208153656e-05, + 3.5078202872376415e-05, + 1.4326993554005429e-05, + 5.039565961946691e-05, + 4.0024903276032146e-05, + 1.2028922085198997e-05, + 1.3878912028461374e-05, + 0.002007918983284649, + 4.998900482600028e-06, + 3.005623947511771e-05, + 0.004418490344777326, + 4.351836384074313e-05, + 1.9764588428937462e-05, + 1.0388433136278484e-05, + 0.004820441889805756, + 0.0029571873238747764, + 1.2256683466934352e-05, + 1.2373222472231526e-05, + 5.238104174226221e-06, + 1.1285596254064168e-05, + 0.0012857957851166912, + 7.326674752573379e-05, + 3.207616483694981e-05, + 6.911886475228355e-05, + 0.006303951277465212, + 1.000139489888943, + 5.464906557027554e-05, + 0.00010733714305272089, + 6.0660365159832946e-05, + 7.720124525653074e-05, + 5.855432409621465e-05, + 0.0094797029371434, + 6.522745373782873e-05, + 3.0658884688565634e-05, + 9.023068062958051e-05, + 4.544248644969524e-06, + 1.2001044159749209e-05, + 1.8785954384074086e-05, + 2.055840385903111e-05, + 2.2085715213219096e-05, + 3.981529552547065e-05, + 6.040915927635078e-05, + 0.0023256807425682856, + 0.0045434752542678775, + 0.009927709865127338, + 0.0030457536628856843, + 0.0024160246204003987, + 3.729640223912626e-05, + 9.760272777704633e-06, + 1.4237690377161014e-05, + 3.104211937400289e-06, + 2.2659425801912526e-05, + 3.449505512877965e-05, + 3.0856925473438306e-05, + 0.009872411943305133, + 7.684621219798062e-05, + 2.8652478623502918e-05, + 2.006953745216285e-05, + 8.417123614646206e-06, + 0.00013607125408058739, + 2.2662814589453177e-05, + 0.008980663561578098, + 4.231651410967184e-05, + 6.570378455831617e-05, + 6.429821139034277e-05, + 5.4917651460058454e-05, + 8.490755068004092e-05, + 7.762892683073968e-06, + 0.006997835355462587, + 1.5400242532702548e-05, + 0.00020214142289124118, + 1.3711952075214602e-05, + 5.665925866907958e-05, + 6.752494369555874e-05, + 0.008406326448191252, + 8.105068432626227e-05, + 3.8638061642113294e-05, + 0.002859745735827901, + 7.167385084465495e-05, + 9.382078897977693e-05, + 0.00794874308179511, + 5.765771555038821e-05, + 0.00020298304343537954, + 1.0004371964060472, + 3.087999998307821e-05, + 0.00559334195236974, + 6.955184983029764e-05, + 8.382334225368937e-06, + 0.00890671898717624, + 2.8651042860903155e-05, + 9.081164422170525e-05, + 2.0040038050023106e-06, + 5.292434468074637e-06, + 3.5321432741907855e-05, + 1.0802323681468716e-05, + 2.180501874404649e-07, + 2.2954687209557798e-05, + 1.5070953927305015e-06, + 4.238725016304624e-06, + 7.932889293692498e-06, + 0.004191427400667957, + 0.009546401607162315, + 0.0018340534860973967, + 4.991506895964298e-05, + 0.006438821015870284, + 5.179424309578726e-05, + 0.00010372821586498543, + 4.425405285903667e-05, + 2.245811070471092e-06, + 5.658566875586513e-06, + 5.196399985490808e-06, + 4.967058051043821e-06, + 0.00855284750328267, + 4.548301416806034e-06, + 3.191452729950644e-05, + 0.003534239376464677, + 8.058523579155135e-05, + 3.049006450511041e-05, + 0.004894035966285886, + 8.274181744819948e-06, + 0.008819032847634595, + 6.226152553836605e-05, + 2.880816747198646e-05, + 2.149929346326834e-05, + 1.7654607315174462e-05, + 8.046991690297857e-05, + 5.077626632758732e-05, + 5.687817152330025e-05, + 4.31693251840473e-05, + 0.006523181202208075, + 1.9299368127396475e-05, + 0.004441591003607541, + 0.00010936821654083165, + 0.000515067873673531, + 6.029281872575666e-05, + 9.658299046784831e-05, + 3.9616146869272896e-05, + 0.007320563611416953, + 0.0005189204241672527, + 0.00022920125990033514, + 7.391753503787828e-07, + 4.3743752451769124e-05, + 4.348830887366919e-05, + 4.2782354320608835e-05, + 8.087032305166897e-05, + 0.0056954290527608375, + 1.1253258306963982e-05, + 0.001842198992963593, + 2.266465386200731e-05, + 2.5613491124066854e-05, + 7.991859104992195e-05, + 0.0028124813517910368, + 0.0001482169747593478, + 0.0011243045085116564, + 6.444479221415082e-05, + 1.0003563067916093, + 0.00020298304343537954, + 0.003163709767952356, + 1.600133368842961e-05, + 0.003804170827353817, + 9.369045968381743e-06, + 0.009902295270012016, + 5.312082381498302e-05, + 2.2088685428722426e-05, + 6.182638644992776e-05, + 4.6149482328255726e-05, + 4.30662229714024e-06, + 1.7490310600702375e-05, + 0.0068963851965890615, + 1.3151090432536203e-05, + 0.00681460115425272, + 6.472707200050332e-05, + 8.37663585323914e-06, + 3.2901582192803755e-05, + 7.438842701197541e-05, + 0.003841607579534625, + 2.1943796847118125e-05, + 2.1569779244003335e-05, + 0.006208188035058918, + 0.007629929362896941, + 0.0008070845419398598, + 0.009283357720056219, + 1.6907856271275485e-05, + 9.842205408662057e-05, + 7.088415884733152e-06, + 4.279874378483436e-05, + 8.545533305049899e-07, + 7.891320233959729e-05, + 4.0935322624666356e-05, + 2.7372743738309747e-05, + 4.61354304564752e-05, + 0.004589697180653488, + 4.909709825223077e-05, + 7.199308136705757e-05, + 2.4213688635566925e-06, + 4.799118855640533e-06, + 1.0839399538239977e-05, + 8.751376430531743e-05, + 0.00012388258501309837, + 0.006489894070843838, + 0.00537362751138068, + 6.871895392907351e-05, + 4.463507283417051e-05, + 0.00010310363765821542, + 3.872517421314511e-05, + 3.2475583311200885e-05, + 4.279985052176947e-05, + 0.004090065904547754, + 1.1849582333965748e-05, + 2.2472137285700316e-05, + 1.1178736689857231e-05, + 0.006303951277465212, + 1.0486260105233297e-05, + 3.6191356626329917e-06, + 4.810896760486375e-05, + 5.8641039681199165e-06, + 0.0015313480060440388, + 5.0148776047508897e-05, + 2.6170465216380154e-05, + 4.411509974638011e-05, + 2.0662887478761327e-05, + 6.459296738261779e-05, + 1.000242876722117, + 4.2782354320608835e-05, + 3.622517432977772e-05, + 6.91575555913188e-05, + 2.7758845583371817e-05, + 0.004544223191595411, + 4.7185395178301896e-05, + 5.403445097854669e-05, + 0.00821535577889686, + 4.3598497940565115e-05, + 1.2663767548591473e-05, + 1.4344908058887058e-05, + 0.003008892442669965, + 1.050353687539633e-05, + 3.035721643280287e-06, + 9.986170939792048e-06, + 5.7774606273442145e-06, + 5.629750213349031e-06, + 4.470429515463049e-06, + 4.962050411035719e-06, + 2.8704814649242224e-05, + 2.9134358931703176e-05, + 0.0033481834471345106, + 2.8207005358445007e-05, + 0.011977395320336965, + 0.006793715977169662, + 0.0020874736505889233, + 0.00944967063640076, + 0.002284715759170237, + 0.007820308463700465, + 1.468252114735999e-06, + 2.883557709799689e-05, + 9.853135724398703e-08, + 3.3429279893770895e-05, + 4.470866250334624e-05, + 6.897424097163955e-05, + 4.61354304564752e-05, + 0.006044533045230626, + 0.00014086511687519626, + 0.0022034474410589774, + 1.0479176239748488e-06, + 7.795590519058728e-05, + 1.42711447725146e-06, + 0.00012218969694670703, + 8.445107658541375e-05, + 0.00015054319828436234, + 3.469139439790145e-05, + 0.0077137338986100305, + 1.4115982854095151e-05, + 6.897019142137336e-06, + 5.633371613685428e-05, + 0.0017554784915360983, + 0.00010354443959710574, + 6.444479221415082e-05, + 5.765771555038821e-05, + 0.0034103459841710953, + 3.5073730595340513e-05, + 4.045190920950058e-05, + 0.009874079931003811, + 0.006620078112091664, + 7.645574527309935e-05, + 1.7857945324176098e-05, + 6.915242362438579e-05, + 8.633795911073606e-05, + 7.250283695571141e-06, + 6.857877591054047e-05, + 3.8981566327742296e-05, + 1.0004484710811958, + 5.344940792856073e-05, + 1.7667422410700649e-06, + 3.7073972839090896e-05, + 1.3483569982537823e-05, + 0.00022871279642392865, + 7.92758331939025e-05, + 3.750389361508163e-05, + 7.964997756107978e-05, + 0.009041327173160378, + 1.5943467644657593e-05, + 0.004215542482180343, + 3.832907709147249e-05, + 7.617858133867746e-05, + 3.774635551090802e-05, + 1.1261487041142267e-05, + 7.61928649524494e-07, + 8.021012974644137e-05, + 2.200821759837018e-05, + 1.286742358858376e-05, + 3.4815135325005485e-05, + 1.026479569747631e-05, + 0.008215388579910384, + 1.66515736182694e-05, + 0.004038422827637369, + 0.007856691498778193, + 0.009863281735601262, + 0.007316043405194684, + 0.004871900036639932, + 0.0012684392689259717, + 0.0033616025774451984, + 5.5252471143096764e-05, + 9.086408853336123e-06, + 2.4430423550093762e-05, + 0.003377191445622171, + 2.410980125288674e-05, + 0.005193523917210944, + 1.1969821155206793e-05, + 0.0019675877767165563, + 9.962891593689917e-06, + 1.8910845561383668e-05, + 4.994533857957476e-06, + 3.780064200939412e-05, + 0.00013853609608595324, + 1.614530164100325e-05, + 6.354986925006403e-05, + 2.2152551541613593e-06, + 6.813742258479065e-05, + 3.0274665047374855e-05, + 6.177626701645455e-05, + 4.497861352315392e-05, + 2.1078685517739725e-05, + 0.014405048700368052, + 6.301974197764083e-05, + 0.0001423670210546449, + 5.030491643952388e-05, + 0.00013392222673275266, + 0.00011108092659027222, + 3.681826033099115e-05, + 0.005102547594472177, + 2.77877047137349e-05, + 1.3244196667398672e-05, + 1.8420403038691553e-05, + 2.74813477149931e-05, + 1.5400242532702548e-05, + 2.9882322235776724e-06, + 0.0018410580341127881, + 3.89090190295633e-05, + 1.8408154591897332e-05, + 0.00956642620888577, + 5.147977149152313e-05, + 6.459296738261779e-05, + 4.348830887366919e-05, + 0.003961812646855485, + 9.171185102672263e-05, + 0.009543969020334744, + 7.943201654792854e-05, + 4.832204262125161e-05, + 3.053482229077703e-05, + 8.226129661953519e-05, + 1.0004567971543645, + 3.8981566327742296e-05, + 0.0001692474180237501, + 1.7888324242610096e-05, + 1.0777056264245487e-05, + 6.552162915475501e-06, + 8.051282580337352e-05, + 1.8606361438029243e-05, + 0.007925813749040412, + 0.0013262776517449749, + 0.004367331740704896, + 5.484361314441554e-06, + 5.208047344244813e-06, + 8.186621732546018e-05, + 6.51473398838025e-05, + 2.155358575807791e-05, + 3.4881950218393824e-05, + 2.193189938950662e-06, + 4.960478974867715e-06, + 4.812960853350476e-06, + 3.101156235952684e-05, + 4.2157943183771885e-05, + 0.001945479696999113, + 1.0169619211581902e-05, + 5.136316317798199e-06, + 1.8634392412703953e-05, + 6.843153149414602e-07, + 5.429085810404545e-05, + 1.9900331944692724e-05, + 9.908776278140068e-06, + 5.9923237944393764e-05, + 2.80291057979106e-05, + 0.004026712082539978, + 0.007536101314779872, + 6.155588174262378e-06, + 1.5196701226806156e-05, + 3.161582560257577e-05, + 4.103470307486917e-05, + 5.879348156754798e-07, + 7.834536780450026e-06, + 4.573898088787692e-05, + 5.787477450346718e-06, + 1.9728161055912034e-05, + 9.197717876650045e-06, + 1.5425238648487882e-05, + 0.0010589697528595465, + 8.7581123233078e-06, + 1.2188625738568068e-05, + 8.219456431663026e-06, + 3.76336116087435e-05, + 0.00011728024289987551, + 0.006162464895893152, + 0.004340989890632332, + 5.179000999773563e-05, + 5.253136891324345e-05, + 4.470787698074131e-05, + 7.564088304664701e-05, + 5.345428422257456e-05, + 0.006164328751618406, + 8.058865452382106e-05, + 4.611385404600837e-05, + 0.009281254762723639, + 5.3988536601202625e-05, + 7.933617991373189e-05, + 0.007406400889151284, + 0.00010702878044929721, + 7.840140364717967e-05, + 2.058832098831185e-05, + 0.00014935807139830338, + 5.208940248579786e-05, + 0.009295057053681489, + 9.414993358493272e-05, + 1.5694842719006986e-05, + 0.006161186192549629, + 0.00011875593959169661, + 9.067481939191294e-05, + 1.0003904807244115, + 0.00010354443959710574, + 0.0011243045085116564, + 0.00794874308179511, + 9.885006688172613e-05, + 0.003554991012200417, + 4.497641852423167e-05, + 6.895434020954211e-06, + 0.007281113407364993, + 0.0001129253805894384, + 0.00010322667475459351, + 2.5507526232547014e-05, + 1.5259333259623386e-06, + 4.65911604680687e-05, + 4.810990280897296e-05, + 4.35156286886779e-05, + 5.2689843753786996e-05, + 1.9556388210223286e-05, + 0.005248491323114544, + 3.5317987962918195e-05, + 1.0169619211581902e-05, + 2.9475059591468917e-05, + 1.5005851203904687e-06, + 1.6821322945941589e-06, + 0.00037552320060045606, + 3.7152036280563222e-06, + 2.108479944985597e-06, + 0.0034308146917214903, + 0.005562525093049638, + 7.642218699679069e-05, + 0.0007922004510952769, + 3.467896560878684e-05, + 1.0222702906452622e-05, + 1.3621500339103099e-06, + 7.310290289575026e-06, + 0.006804287846315139, + 1.7594688486085036e-05, + 3.913977044227693e-06, + 0.0001391716422599186, + 0.009151840802452679, + 0.005289247804570505, + 2.213282547714912e-05, + 7.511646879857002e-05, + 0.0056379696535372795, + 2.8074432059582885e-06, + 1.8264595375149003e-05, + 3.2854142780819036e-05, + 5.947613597670801e-06, + 1.879420935773223e-05, + 0.0037882592550023573, + 1.7033791982717998e-05, + 1.9546483249476834e-05, + 0.002923910238477404, + 8.738491375979277e-06, + 3.993375566796682e-05, + 7.456582558012644e-05, + 2.8652478623502918e-05, + 3.2648313100976816e-05, + 0.0018398040804846942, + 0.003262568127085023, + 4.324578616775226e-05, + 2.350896238431244e-05, + 0.0072466957647136405, + 5.147977149152313e-05, + 2.0662887478761327e-05, + 4.3743752451769124e-05, + 1.5043418041883717e-05, + 0.0025456088283974092, + 0.0008344352091233543, + 0.009423377551926036, + 4.159463451217095e-05, + 0.0011141911866881654, + 2.2764179043432686e-05, + 1.9808276545164153e-05, + 3.5011884286798186e-05, + 0.007944636963792108, + 0.004449428258901354, + 0.00694616003156225, + 2.01100155359697e-05, + 4.2842658647721135e-05, + 0.008061790939854345, + 0.0030345791284893233, + 2.9396639749410458e-05, + 6.24900923096088e-05, + 4.399702131495049e-05, + 1.3007037389759159e-05, + 6.804885467463613e-06, + 1.001620013315965, + 1.945367154999441e-05, + 1.5696421917549157e-05, + 7.028971907680665e-05, + 4.7269354886358105e-06, + 0.0006949372352616699, + 8.484749056658531e-06, + 3.3014866340073654e-05, + 7.073516401505625e-05, + 4.014886379571267e-06, + 9.108396625983994e-06, + 0.004321927299556481, + 0.0058768241372289, + 0.001274567154347896, + 0.008215388579910384, + 0.005622981904158817, + 0.008694167441570979, + 0.004990979010645134, + 0.0020676055741927837, + 8.507831038245505e-05, + 1.3421878168480512e-05, + 3.698500719033811e-05, + 5.2892774698968354e-05, + 4.279407556548083e-05, + 5.15076415312748e-05, + 5.3235186612166245e-05, + 1.951610783233207e-05, + 5.326649168148768e-05, + 5.409762971466342e-06, + 2.416269384841492e-05, + 0.006778124499406896, + 6.72187870424122e-05, + 0.0003862692349598243, + 3.555021927781079e-05, + 1.847328180131288e-05, + 5.472011340191899e-05, + 0.006850510061810733, + 4.319694231074623e-05, + 0.0010627994318390286, + 2.817754802475255e-05, + 7.164637249194579e-05, + 4.5445832281131216e-05, + 0.00833339346667911, + 0.006202938017977235, + 1.0203266725336442, + 8.169223873696375e-06, + 0.006358998048098247, + 4.2287392648719884e-05, + 1.0623499542258326e-05, + 0.00016112846705804528, + 0.00574581527221644, + 2.696520810397456e-05, + 4.8413826881802706e-05, + 3.2533800384630557e-05, + 1.4154750529256727e-06, + 2.0040038050023106e-06, + 4.544248644969524e-06, + 1.5169365522255912e-06, + 1.5813697966072556e-06, + 0.0039959851162086795, + 0.00037552320060045606, + 0.003841607579534625, + 0.009893406378396238, + 0.005614779437366768, + 0.006195682247786596, + 0.0004904804093198068, + 3.401408920663357e-05, + 5.259205737729365e-05, + 4.73731084926689e-05, + 3.746647411616235e-05, + 0.004515126381855252, + 3.46151188786036e-05, + 0.0009421147252950182, + 8.003274135724149e-06, + 3.5918105428542704e-05, + 3.366232988367765e-05, + 0.004745979425066099, + 3.7947580282532233e-06, + 5.1798205991187264e-05, + 5.493834356565433e-05, + 6.478983772859016e-05, + 9.490674478102146e-05, + 0.00826115681055757, + 3.781020879821394e-05, + 6.771638314171035e-05, + 9.945364267061394e-06, + 8.709392167994599e-08, + 0.008851514555513171, + 7.092762014150933e-08, + 7.241693757591757e-06, + 2.2529968517451576e-05, + 8.949628991663872e-06, + 2.5844655406679966e-05, + 0.0019337748315410668, + 5.464070852933514e-06, + 0.0013346887928212846, + 4.014318685652859e-05, + 0.005249400737137344, + 6.056929639322962e-06, + 8.226129661953519e-05, + 6.857877591054047e-05, + 0.007838582074793548, + 4.571840485343565e-05, + 0.005741093990493656, + 6.497358014457847e-05, + 5.826260311688797e-06, + 3.1987418151162497e-05, + 2.3174984669763992e-05, + 4.4290465341956033e-05, + 0.007513842671876183, + 3.19672703161189e-05, + 0.00013016863433750942, + 1.671129286964195e-05, + 4.764519943351331e-05, + 0.00011371720186554668, + 3.582381449643013e-05, + 1.0002999647818855, + 0.006202938017977235, + 8.255379593155514e-06, + 1.8507845222880758e-05, + 4.27333714582164e-05, + 0.00403467118712389, + 6.717291162328866e-05, + 0.005794533630906074, + 0.00048644854934731753, + 0.0011035844870068423, + 0.006548836331007934, + 5.5843212860730985e-06, + 2.2006625594661942e-05, + 2.1430325576489996e-05, + 2.2149089869145255e-05, + 8.119893134280176e-06, + 6.205293339025682e-06, + 3.7681435698580956e-06, + 9.861034013834767e-07, + 5.110303605181262e-07, + 3.104211937400289e-06, + 2.2893352845326236e-06, + 5.064743170214215e-06, + 3.485116857707309e-06, + 0.0005778280391964555, + 3.117548029508032e-06, + 0.008570542520500277, + 5.458741613905111e-06, + 0.0005468462075336555, + 1.6298167845171424e-06, + 3.619066817315635e-05, + 6.040661971505374e-05, + 4.157804352074367e-06, + 1.1478516439581388e-05, + 7.01050892693061e-05, + 5.631224140776579e-05, + 7.740590924596806e-06, + 2.2755660280173264e-05, + 3.76336116087435e-05, + 0.005796324582018182, + 3.5125133690867506e-05, + 5.803877605658419e-05, + 1.836210569087713e-05, + 5.235179554840961e-05, + 5.359866281977652e-05, + 1.0034658106515606, + 3.582381449643013e-05, + 0.00833339346667911, + 3.802634538910261e-05, + 0.006806823890020743, + 4.695475624562457e-05, + 1.1796041331419004e-05, + 0.009918597864277588, + 0.006329999010846514, + 0.006765004772106684, + 1.041461905701894e-06, + 6.165144402688587e-05, + 2.8449049102145023e-05, + 7.544933136494426e-07, + 3.177050433723157e-07, + 1.176349128772483e-07, + 7.61928649524494e-07, + 2.180501874404649e-07, + 7.442826532368355e-07, + 5.959071178316483e-07, + 6.751158464193462e-07, + 1.083030484391954e-07, + 0.0018985266027096914, + 0.013780337834186657, + 0.007152670825092443, + 0.0033481834471345106, + 0.004710837294839253, + 1.5318526814856903e-05, + 1.5917088164935347e-05, + 5.654731790071036e-05, + 1.7297893003350107e-05, + 2.225316986181994e-05, + 0.005248188198912619, + 8.477351939698314e-05, + 0.00013867448984484528, + 5.242738108525685e-06, + 2.2755660280173264e-05, + 7.717911239137264e-05, + 0.003925877503611112, + 0.00012386310278921677, + 2.5668579786795284e-05, + 0.0081575359016717, + 0.008538605385254245, + 2.78444326678576e-05, + 1.4663526011589675e-05, + 0.0030543276608787084, + 0.00011032302460473533, + 2.0879152531223147e-05, + 0.00858142603278076, + 1.2886151317740457e-05, + 0.00011931118425226127, + 3.872517421314511e-05, + 1.2256683466934352e-05, + 0.00015854687935395274, + 0.002954714475054873, + 8.366686264344738e-05, + 0.009532371787812329, + 6.303360450230218e-05, + 2.2583435590428477e-05, + 0.0014282378997911738, + 0.0001012477669236068, + 3.88605346505195e-06, + 1.6515955131066794e-05, + 1.0003730467323628, + 0.00010702878044929721, + 0.00012245212128581448, + 5.752384109440578e-05, + 1.9635793154361086e-06, + 5.322016823308476e-05, + 3.8611487076955e-05, + 0.00689029288331709, + 6.623595464622124e-05, + 9.142508566084441e-05, + 1.9982365220095112e-05, + 1.844624633903237e-05, + 1.0730957657725968e-05, + 4.3598497940565115e-05, + 8.180534967924788e-06, + 1.034996127455612e-06, + 1.3325165197173029e-05, + 4.258700237407619e-05, + 2.6905188075855888e-05, + 3.3405059603801925e-05, + 0.007984668065463083, + 0.006995397184540966, + 0.00681460115425272, + 0.009498292054863657, + 0.004828100933283703, + 1.3509640250550743e-05, + 0.001935240152718257, + 0.005956877741835263, + 0.001274567154347896, + 1.026479569747631e-05, + 0.007245395472591905, + 9.09074558996317e-06, + 7.288720745849373e-06, + 0.004060612310993983, + 0.007496747275018019, + 1.0706972202517327e-06, + 2.844506535959634e-06, + 2.16038287937511e-05, + 0.0023320464877719343, + 0.0003816885689634088, + 1.6125188709193586e-06, + 1.9541155247926564e-06, + 0.005332022790581705, + 5.8749181656967195e-05, + 4.787322589202522e-05, + 5.196399985490808e-06, + 4.195497660194445e-05, + 7.174147412406096e-05, + 0.001254912207654518, + 1.9635237808574706e-05, + 4.2254995780583525e-05, + 2.4633857595563536e-05, + 2.532220139804081e-05, + 3.0247199102358532e-05, + 6.939682639117589e-05, + 7.795414495027033e-05, + 6.595502583296869e-05, + 4.957894886944058e-05, + 7.144392268361971e-05, + 4.89366368790601e-05, + 0.008434198729491096, + 0.0001055661057078594, + 5.849183962449663e-05, + 6.810953124830916e-05, + 5.1798205991187264e-05, + 0.005683899652143301, + 1.6446658316063207e-05, + 7.376706734812109e-05, + 8.927093181596704e-06, + 1.9073452472447576e-05, + 0.0032229912057087124, + 5.109858086914298e-05, + 2.6087163904935546e-05, + 0.001402735417636479, + 0.004466014513292503, + 0.00010630503753370316, + 6.203012046578658e-05, + 2.9507190624179216e-05, + 7.489498443709168e-05, + 5.6129781407169457e-05, + 9.723714884303621e-05, + 1.0002718330049372, + 6.804885467463613e-06, + 5.130159250113782e-05, + 6.052485692047022e-05, + 4.35561991898656e-05, + 0.00010981446149796692, + 0.009882759593724188, + 3.0360842724742417e-05, + 4.01489884515465e-05, + 3.1326321629322294e-05, + 1.933607075234137e-05, + 9.153726814948286e-06, + 4.221448294680072e-06, + 2.6281148204999713e-05, + 2.9711268059919924e-05, + 0.009092323764615015, + 3.877812615061973e-05, + 3.832907709147249e-05, + 2.16038287937511e-05, + 0.008164029212026792, + 6.556057476266936e-05, + 3.5817131940039534e-05, + 4.628791292582566e-05, + 2.461900532024616e-06, + 2.636155130685005e-05, + 3.8655259029171693e-07, + 4.134393643718326e-05, + 2.6583074685513483e-05, + 0.0046012907750768986, + 8.085035701929519e-05, + 4.494637145322238e-05, + 0.0009421147252950182, + 4.3088882703026115e-05, + 0.00020211630792040222, + 0.004245174591239174, + 0.002965796072866161, + 6.689722171556712e-05, + 6.735818788402423e-05, + 2.7073737897301418e-05, + 0.00044431236058949623, + 3.8907724284033985e-05, + 0.00011641156866472645, + 6.015624802294293e-05, + 2.4569621790304322e-05, + 5.039565961946691e-05, + 6.86394345037373e-05, + 2.062861723670921e-05, + 0.00017606248522604556, + 0.004924228234314472, + 0.006655999042995089, + 8.572705345464126e-06, + 0.00652056301061857, + 0.0075773494450229375, + 6.833509523082159e-06, + 7.849728077354606e-05, + 7.456582558012644e-05, + 0.0033216559080485038, + 5.4622505552109676e-05, + 3.3803783166902323e-06, + 2.1441172414522936e-05, + 1.0371090875917845e-06, + 0.00040951532149479774, + 0.00010429519486518364, + 2.2346628787836468e-05, + 5.760504239152818e-06, + 7.85697336266132e-06, + 2.5853406633669654e-06, + 0.00010021526772651202, + 1.6515955131066794e-05, + 1.959778315481159e-05, + 0.0001284645428770314, + 1.8500337692731853e-05, + 1.3433271666820882e-05, + 0.0024404954301714054, + 0.001268052671563556, + 2.8342207263042518e-05, + 0.002554135913483182, + 8.335327060635427e-05, + 1.000455544525457, + 9.067481939191294e-05, + 0.0017554784915360983, + 0.0001482169747593478, + 9.382078897977693e-05, + 5.054622426696256e-05, + 2.8191053266072524e-05, + 0.0001805488747476753, + 8.942891187852903e-06, + 0.009496872318820002, + 9.399386408590776e-05, + 7.71081508500837e-05, + 6.979561412464874e-05, + 4.01489884515465e-05, + 2.8726589223701957e-05, + 6.374362258410816e-05, + 5.800260442591195e-05, + 5.464438004534413e-05, + 1.4154750529256727e-06, + 0.0036699814726822077, + 0.002612451324535824, + 0.006157260534451727, + 0.004325677183490168, + 0.005850778163732161, + 0.009743049631104774, + 4.617323056512292e-05, + 0.003061799067835776, + 0.006995397184540966, + 6.603767343972547e-05, + 1.8504975325063464e-05, + 3.356777733560644e-05, + 2.813328553469004e-05, + 5.356863279872683e-05, + 0.0004195966818797722, + 0.009609472854344313, + 6.9319518972996804e-06, + 0.0045434752542678775, + 9.92624527811888e-06, + 3.0453043375824447e-06, + 4.3883882401521954e-05, + 1.94630953296662e-05, + 2.4430423550093762e-05, + 0.007233946888549284, + 0.00010136556747827229, + 8.159669202728204e-06, + 5.168247156296229e-05, + 9.073084147842132e-07, + 0.005126444542508474, + 1.7327129637714894e-07, + 0.0090398684568361, + 0.006358011194064177, + 8.338065908363515e-06, + 1.4039561271931087e-05, + 4.232256890170172e-05, + 2.6445664430825162e-06, + 1.2973929579280214e-05, + 5.242738108525685e-06, + 7.740590924596806e-06, + 8.219456431663026e-06, + 6.671127692826823e-06, + 0.0013354308950555116, + 1.185020908107824e-05, + 3.744616336372351e-05, + 0.00011094755414201958, + 1.0002389983320283, + 1.7033791982717998e-05, + 0.00012388258501309837, + 5.077626632758732e-05, + 5.551480015170474e-05, + 3.8945017106828324e-05, + 0.00587733230650688, + 1.741084018960257e-05, + 0.008126126390881718, + 1.260606554655423e-05, + 0.006756440638648885, + 3.5317987962918195e-05, + 3.809734129067859e-05, + 2.3765530992957984e-06, + 0.0016452738524017194, + 0.003230710684057512, + 0.00813513284380525, + 0.0017964531586413168, + 5.245897082846726e-05, + 2.2699011482774208e-05, + 2.844506535959634e-06, + 4.991506895964298e-05, + 3.4185747076641285e-05, + 3.453785158693196e-05, + 8.604060923538484e-06, + 5.742099408205895e-06, + 1.7327129637714894e-07, + 0.007388783088336085, + 0.0074382588194354445, + 1.824223373856259e-05, + 0.002711227563482645, + 1.877880444362138e-05, + 0.0037547983552217367, + 6.791867953427332e-05, + 9.324987802129278e-06, + 2.7808250649402162e-05, + 1.3612134800845368e-05, + 0.004938488230247744, + 2.451747705959345e-05, + 2.6429175994417655e-05, + 2.647290542189767e-05, + 0.0028935743279264107, + 1.1621207799905132e-05, + 1.833190249544069e-05, + 0.007791658840435856, + 0.0001185655905667058, + 0.00025118900478544144, + 1.3553940587364827e-06, + 1.8486741044336282e-06, + 9.760124850673267e-06, + 3.9536170159753443e-05, + 0.00010021526772651202, + 3.88605346505195e-06, + 0.007406400889151284, + 4.1413939487704946e-06, + 3.336172852818558e-05, + 7.398325825980472e-05, + 4.352960566006824e-06, + 3.160726188317129e-06, + 0.000605441247258067, + 5.422057846185583e-06, + 8.2936366790311e-06, + 6.25004168927728e-06, + 4.367459088655561e-05, + 1.0002082081931074, + 6.056929639322962e-06, + 3.053482229077703e-05, + 7.250283695571141e-06, + 7.017012962279487e-05, + 1.5967932983625997e-07, + 0.0013164853450756745, + 1.2186539544715434e-06, + 9.071001496701286e-05, + 0.001026103455904006, + 0.0034227338913006555, + 0.0013789509831549367, + 0.0008094970202235607, + 0.0024756450814178467, + 5.689189388216512e-06, + 0.0005478704792354883, + 4.5637951432835935e-06, + 2.8683298392619073e-06, + 0.002752361059311225, + 0.008359354900165079, + 0.004316602141437835, + 0.0029471484685646876, + 0.004357343568433076, + 3.3602864974098526e-05, + 8.001581192602237e-06, + 0.0016452738524017194, + 5.2504102984330765e-06, + 2.1796536959262597e-06, + 0.004934645058048987, + 3.9338609163468106e-07, + 0.002612451324535824, + 3.320383246689815e-05, + 5.937810771779099e-05, + 1.1969821155206793e-05, + 0.006083500465316787, + 4.901761593493149e-05, + 3.5181354807464185e-05, + 5.8469634307341134e-05, + 5.663119294446125e-05, + 4.7298225712617244e-05, + 6.139913854674415e-06, + 5.110303605181262e-07, + 1.5196701226806156e-05, + 1.4237690377161014e-05, + 3.7303041062276185e-06, + 8.252627901419628e-06, + 0.0009286021346292216, + 5.079816090900735e-06, + 6.509212224544221e-06, + 1.3500497663962548e-05, + 1.5106463096119683e-05, + 9.793241132476954e-06, + 3.913977044227693e-06, + 4.917905109956431e-05, + 0.0010195254958027743, + 1.7160912740953665e-05, + 6.911311528819053e-06, + 3.2874580211676028e-06, + 8.733381168004906e-06, + 5.796526019303194e-07, + 1.5511247519254373e-08, + 2.4050974985867775e-06, + 1.42711447725146e-06, + 2.266246567558815e-06, + 1.6457045280624036e-05, + 0.00014991626842961953, + 1.103134707835397e-06, + 3.3583569172584694e-05, + 2.6463650851974373e-05, + 5.648693036805958e-05, + 1.0376186007173165e-05, + 1.0001080862476222, + 1.1178736689857231e-05, + 6.911886475228355e-05, + 0.007431416098998833, + 6.104874933017689e-05, + 2.3911820891969514e-05, + 5.9520335109750265e-05, + 2.9204211939985304e-05, + 0.0073028517638831615, + 0.00842634005475897, + 3.335370314286377e-05, + 3.716813088547636e-05, + 9.986170939792048e-06, + 1.4092747286854697e-05, + 1.2649299473656828e-05, + 4.724217381934257e-05, + 2.9691546746360525e-05, + 3.283564120768238e-05, + 1.3839749949607112e-05, + 1.7386720499088466e-06, + 1.176349128772483e-07, + 1.3652454735223686e-05, + 1.2383720746665643e-05, + 8.130561009949154e-07, + 5.375142952456956e-06, + 0.00654750217444128, + 0.011437588139071007, + 0.006756440638648885, + 0.005248491323114544, + 0.001945479696999113, + 0.0026401284607189303, + 2.059942267026535e-05, + 4.05511193210967e-05, + 5.0907829920540994e-05, + 5.937810771779099e-05, + 0.005193523917210944, + 0.014888439801268014, + 8.546051687200953e-05, + 0.009965742385508356, + 8.610593246983417e-05, + 6.956014306610032e-06, + 0.00010740660096765256, + 1.4633962622208773e-05, + 2.9446476827046725e-05, + 2.7943759314982804e-05, + 5.658566875586513e-06, + 3.0110710713604018e-05, + 1.4997326509518679e-05, + 4.413367626682505e-05, + 7.405308840517132e-06, + 1.4378863651314058e-05, + 1.4703237898637284e-05, + 3.6960655441931726e-05, + 0.00814747827758538, + 0.009658027123380798, + 4.100952759170509e-05, + 0.0004400256081269027, + 0.00016616202787009891, + 9.35929561527854e-06, + 0.008814308982101544, + 5.30035956401809e-05, + 8.570889656902395e-05, + 0.00012252356756068845, + 3.710823378319444e-05, + 6.63684483593648e-05, + 7.092654206774545e-05, + 0.005760547974782387, + 5.950574219013195e-05, + 3.823333055521334e-06, + 0.0014701890195581973, + 1.0003536160802096, + 6.810953124830916e-05, + 3.7947580282532233e-06, + 0.0033598743762273376, + 2.407729671365154e-06, + 3.9117221191864173e-05, + 1.3632792315744896e-05, + 4.055292891554118e-05, + 0.0005409447801154472, + 7.582184626453817e-05, + 2.3104780332391485e-05, + 3.819063871128943e-06, + 0.003183520221360109, + 0.009754505241349513, + 0.0072660443733186895, + 0.002341990597880902, + 0.002882958045542563, + 0.006068265635885829, + 2.3007962908176834e-05, + 0.008359354900165079, + 2.4636259992210228e-05, + 4.107847715552589e-05, + 2.0074075568947277e-05, + 1.5112175287129863e-05, + 8.868053332557463e-06, + 4.1328595096240814e-05, + 2.3365918073951653e-06, + 7.01836851398739e-07, + 1.974601693940481e-05, + 2.2699011482774208e-05, + 1.0706972202517327e-06, + 7.45391906916999e-05, + 0.0029280711260348193, + 2.3553570961174583e-05, + 4.852011383706507e-05, + 0.0002330089418659586, + 2.7897221652101157e-05, + 1.5593738377884085e-05, + 1.058349284017026e-06, + 3.250308511474092e-05, + 4.038446263170618e-05, + 4.6049172717572536e-05, + 2.636155130685005e-05, + 0.007211592682138772, + 7.794108624284254e-06, + 3.1527067534437825e-05, + 3.937530357228339e-05, + 7.399152158740839e-05, + 1.1077299584837934e-05, + 9.111253699030105e-05, + 0.002607844948965233, + 0.004894035966285886, + 4.25828037495546e-06, + 0.004538686199959361, + 8.098320768821391e-05, + 4.880167751546794e-05, + 1.0002450362935638, + 2.5668579786795284e-05, + 5.179000999773563e-05, + 0.0001077222898127599, + 6.096919802748503e-05, + 3.284174067021099e-06, + 0.00010865683469747918, + 4.0346791468329965e-05, + 0.012483629336950668, + 3.5510223520742805e-05, + 7.044948047777424e-05, + 0.003967276004683859, + 0.002313141822622935, + 0.000553497892180952, + 0.0013524119124650137, + 0.0036591943541357543, + 5.2572209354611396e-05, + 2.6938937550086616e-05, + 2.6479781054830162e-05, + 3.167044894012793e-07, + 0.009423005118956355, + 1.8552101725878217e-06, + 2.8684972057005484e-06, + 2.1917380980842736e-05, + 2.3261520739724016e-05, + 5.328558922832335e-07, + 2.8372766896015674e-06, + 0.008434966654025614, + 8.557631805263534e-06, + 6.065882887747172e-05, + 0.003296579722968024, + 1.2973929579280214e-05, + 0.00013867448984484528, + 5.631224140776579e-05, + 4.853197343199784e-05, + 0.00801246907316579, + 1.2460811952974336e-05, + 7.243617434429084e-05, + 0.0003862692349598243, + 0.009742433538967666, + 1.990714084779318e-05, + 5.896737874814423e-05, + 0.007382232899732989, + 2.3553444460228956e-05, + 0.0014701890195581973, + 0.004745979425066099, + 1.765487079884287e-05, + 7.6171374432633975e-06, + 0.01169005897156178, + 0.002066966424496967, + 0.00956642620888577, + 4.411509974638011e-05, + 0.009325200209838529, + 3.41674962668119e-05, + 0.005184694759674665, + 6.311322749339541e-05, + 2.0501915098524828e-05, + 1.537618440707853e-05, + 1.999352945584506e-05, + 1.4313504055806974e-05, + 1.6958464549274786e-05, + 0.0002095266612916967, + 0.0001739067643966113, + 1.754746680391694e-05, + 8.573630025876962e-06, + 8.335327060635427e-05, + 0.00011875593959169661, + 5.633371613685428e-05, + 0.0028124813517910368, + 7.167385084465495e-05, + 2.840085319715022e-05, + 1.3166789154235854e-05, + 5.1312749912381697e-05, + 3.996606173962012e-05, + 0.008164860638231877, + 1.5242491587519319e-05, + 9.110823057042535e-05, + 8.783274600292875e-06, + 7.790316917247569e-05, + 6.180610405893971e-05, + 0.0012335807356279886, + 6.951085703673046e-05, + 3.0199481909460294e-05, + 1.000357354602237, + 9.723714884303621e-05, + 1.3007037389759159e-05, + 0.007478559973594072, + 0.0005756933364419036, + 0.0014978319467007927, + 8.319739106311735e-05, + 0.009060445131141749, + 0.008476403295092551, + 6.165144402688587e-05, + 0.00888209193214149, + 6.204363681200837e-05, + 0.0005059685367658173, + 2.193189938950662e-06, + 6.06595718656155e-07, + 4.654126826922435e-07, + 0.008330062152010861, + 4.724217381934257e-05, + 4.5637951432835935e-06, + 2.3463588718664166e-05, + 3.3014866340073654e-05, + 9.822974678059222e-05, + 0.006152628018747152, + 0.0022208218820898985, + 0.009959454332578336, + 0.0001585354537356698, + 0.0034534397792633023, + 0.0068864505226439, + 0.004865248238712459, + 3.6195734375041716e-05, + 1.5060068616501702e-05, + 1.614530164100325e-05, + 0.004318123334226994, + 7.863280354198881e-07, + 9.519664087722381e-05, + 2.4569621790304322e-05, + 1.4326993554005429e-05, + 0.00010792890575392393, + 5.243876354047514e-05, + 1.0185038332521287e-05, + 3.1188552603485446e-05, + 1.106115656959078e-05, + 2.2056768611094835e-05, + 0.003242508738519706, + 5.803857831012882e-06, + 9.155010186532908e-05, + 0.0050024275339864265, + 0.00016463726515054288, + 0.009248274563630471, + 6.757392944389293e-05, + 0.00011849937708924003, + 0.0001332272819942979, + 0.00011304389453428674, + 0.009813729259187031, + 7.807000346171727e-05, + 0.0025021376078974, + 0.00019408068036398684, + 5.4768435409716286e-05, + 6.224525801469073e-05, + 2.4500541892901417e-05, + 0.00010797040109734197, + 7.405061225080043e-05, + 0.004901352788596833, + 1.000421730166304, + 3.0199481909460294e-05, + 5.6129781407169457e-05, + 4.399702131495049e-05, + 1.3979739129546218e-05, + 9.220435186640806e-06, + 2.8841903361718384e-05, + 0.007505476440510395, + 0.0033801536148952, + 2.696520810397456e-05, + 4.843570844089803e-05, + 4.163593054971914e-05, + 1.9459193714956095e-05, + 5.1116032814248954e-05, + 5.157027738322318e-05, + 3.877812615061973e-05, + 2.5507526232547014e-05, + 2.956871823131433e-05, + 0.00669183652199143, + 0.0068963851965890615, + 0.0010612541856490243, + 1.8834701174318686e-05, + 7.276203856300719e-05, + 4.762214563038365e-07, + 1.78718978296062e-05, + 5.424328468668677e-05, + 0.008121860669464572, + 0.007152670825092443, + 6.025817506004486e-05, + 3.369506848055413e-05, + 3.6412947427721105e-05, + 8.198454746167677e-05, + 0.006793715977169662, + 2.863731908220287e-05, + 8.565419016550504e-05, + 6.9319518972996804e-06, + 8.747730094430352e-05, + 1.1762304592131597e-05, + 8.43803120629424e-06, + 0.002607844948965233, + 3.049006450511041e-05, + 3.243705960449583e-06, + 6.982511354897124e-05, + 8.27067019911165e-06, + 0.00012212415535175345, + 0.005161235266164338, + 4.959806571644058e-05, + 5.787477450346718e-06, + 2.880137609004941e-05, + 2.6676388625680194e-05, + 6.0474015681588885e-05, + 0.00011036325907642369, + 4.246587373330859e-07, + 0.00028570917724010436, + 9.009488664252652e-05, + 5.4075447940124195e-05, + 7.243617434429084e-05, + 6.72187870424122e-05, + 3.687809075046072e-05, + 0.009983239643101386, + 0.008961675208398875, + 0.003839725262471517, + 0.00012252356756068845, + 6.595502583296869e-05, + 4.9454216424904526e-05, + 0.005621853829576654, + 0.00015788936748717885, + 0.00784335809733372, + 7.860681144132016e-05, + 5.7681226031826427e-05, + 9.824617476956339e-05, + 0.009104111949848063, + 7.854359390138303e-05, + 0.0026332132949579883, + 0.0001332272819942979, + 7.30700720386402e-05, + 0.00010056316074184729, + 0.008334515044103877, + 3.709196423785288e-05, + 0.00013430194690215467, + 9.903821108325084e-05, + 0.005320131680220553, + 0.00851023050101972, + 8.894990992311741e-05, + 7.12512536575226e-06, + 1.0007327698873956, + 2.74813477149931e-05, + 0.006997835355462587, + 7.172381736447735e-05, + 0.0035186077058957845, + 0.00018398308294319499, + 0.0001783375337444304, + 0.007715697260558262, + 0.00016056771047132448, + 6.979561412464874e-05, + 3.0360842724742417e-05, + 2.4062175400161237e-05, + 6.942689596137118e-05, + 5.66267224832227e-05, + 0.0008438794789498705, + 0.0047951923711135385, + 9.500151198094398e-05, + 0.0073262954486466875, + 3.686578049401734e-05, + 9.793241132476954e-06, + 1.7594688486085036e-05, + 0.009605685363234352, + 6.511645296408814e-05, + 1.2839983888251582e-05, + 6.897424097163955e-05, + 2.7372743738309747e-05, + 1.2695145626776906e-05, + 1.9242846360984317e-06, + 0.002360689141632851, + 0.009924221952596258, + 0.0071044223349299536, + 0.00010363848198497155, + 0.005765427248372032, + 0.0033159955720434213, + 2.3553444460228956e-05, + 3.823333055521334e-06, + 5.849183962449663e-05, + 0.004622968368555527, + 5.411376477769995e-05, + 4.735984999341235e-05, + 4.988319262381871e-05, + 0.0082645365245498, + 0.0019700424201241754, + 5.646706491604017e-05, + 6.944150722416447e-05, + 0.009622053112821669, + 4.301334828362342e-05, + 4.003025947351584e-05, + 7.12512536575226e-06, + 1.8420403038691553e-05, + 7.762892683073968e-06, + 0.0022893814596128765, + 0.009382044831691094, + 6.224177478794206e-06, + 9.019246741974433e-06, + 0.0009234583894543225, + 3.0746562325406976e-05, + 3.567549464296331e-05, + 0.00130153079327133, + 0.00010236722183861859, + 4.356112667058918e-05, + 0.007118970625743312, + 0.0047020195291187054, + 5.264850636123655e-05, + 0.006362434526919624, + 9.34511827892779e-05, + 0.0032308706257639114, + 6.711352737675126e-05, + 1.000401498616877, + 5.359866281977652e-05, + 0.00011371720186554668, + 4.5445832281131216e-05, + 1.1628614234344098e-05, + 6.276963263902074e-05, + 6.0194675001078164e-05, + 2.4967263474904864e-05, + 0.00012168058179273745, + 0.008239347700691868, + 0.0029241508388424798, + 5.702868336995201e-07, + 5.105886593647359e-06, + 1.1461727965227623e-05, + 3.831561999862129e-06, + 6.661613518538756e-05, + 5.49233249363574e-05, + 0.006868664937349099, + 0.0013013807746215947, + 1.94630953296662e-05, + 9.086408853336123e-06, + 1.6907856271275485e-05, + 0.0026905222874216293, + 2.5866209626581253e-05, + 1.920766372314651e-05, + 1.8323805044617538e-05, + 3.559764352524221e-05, + 0.008617716809513676, + 2.461900532024616e-06, + 4.529448782957032e-05, + 8.697263095435295e-05, + 9.111253699030105e-05, + 8.058523579155135e-05, + 8.573114353939069e-06, + 5.375160122425016e-05, + 3.6875617603695455e-06, + 5.562833465377535e-05, + 1.5917088164935347e-05, + 1.7298730204288893e-05, + 1.3612387774774914e-05, + 0.00914181407893777, + 0.0019574602954816533, + 5.312316031361682e-06, + 4.419183138808709e-05, + 1.184780867061854e-05, + 9.861034013834767e-07, + 6.155588174262378e-06, + 9.760272777704633e-06, + 0.006896939223886141, + 1.592458114561165e-05, + 1.0957915206616842e-05, + 0.0018061101135306693, + 7.431313644927198e-05, + 0.00010584745468589411, + 0.006116514527944604, + 4.6518092916010685e-05, + 0.007160597590819221, + 1.669025577009584e-06, + 1.2649259146947333e-05, + 7.454698894418567e-06, + 5.4075447940124195e-05, + 0.006778124499406896, + 5.699395700018925e-06, + 7.760430092050088e-05, + 2.1906009920850237e-05, + 2.4050974985867775e-06, + 7.795590519058728e-05, + 0.0016040258767245185, + 0.00215782461676853, + 0.005492684933484426, + 0.00010779998862338913, + 4.4724072133743586e-05, + 0.00481031758485341, + 0.005738400102416387, + 6.52507212958729e-05, + 5.906509606247966e-06, + 4.812969575941697e-05, + 0.002946774207824383, + 1.658640530590938e-05, + 1.0003355129147409, + 0.004901352788596833, + 6.951085703673046e-05, + 7.489498443709168e-05, + 6.24900923096088e-05, + 2.5078590911148673e-05, + 3.3409698001656547e-05, + 2.6724663523493806e-05, + 3.5152894511271435e-05, + 0.006085598405466598, + 6.176049961778198e-05, + 2.2433062721085766e-06, + 0.008330062152010861, + 0.0005478704792354883, + 0.008978981047742522, + 2.5660230268410952e-05, + 2.9786294750743373e-05, + 2.3464494097835496e-05, + 0.011437588139071007, + 1.5211346445822785e-05, + 5.518628161876147e-05, + 2.026619213012e-06, + 3.554312579674117e-05, + 5.5252471143096764e-05, + 0.007331530231065854, + 0.007785646161814149, + 2.8971481713675734e-05, + 3.698500719033811e-05, + 0.00011970197773206852, + 3.982086179258424e-05, + 4.953655337972678e-05, + 1.8160182746121535e-05, + 1.3878170459442497e-05, + 1.2098027758146606e-05, + 3.8498380768415485e-05, + 8.43803120629424e-06, + 1.1077299584837934e-05, + 1.7230684945129012e-05, + 1.3089510001785621e-05, + 5.562833465377535e-05, + 4.831905131488414e-05, + 0.007690836904536741, + 0.006948275793281259, + 2.627011625477693e-05, + 2.2487394622544145e-05, + 0.003296579722968024, + 7.01050892693061e-05, + 8.193477229159464e-05, + 0.009439959067106114, + 2.830839327894561e-05, + 0.00013540300672868085, + 0.00011094755414201958, + 0.0037882592550023573, + 8.751376430531743e-05, + 8.046991690297857e-05, + 0.00782914362550076, + 2.3242003711048557e-05, + 3.4677134824006374e-09, + 6.492634734915772e-05, + 7.092762014150933e-08, + 0.00013940450826643473, + 2.7398964806537252e-05, + 6.174032240952402e-08, + 4.1517316058143174e-07, + 5.7250640224978076e-05, + 4.798729591851256e-05, + 2.1404205094684842e-07, + 2.8032026778863344e-07, + 5.7475994530403656e-05, + 5.742437076531531e-05, + 6.192835638460486e-05, + 3.5351194579500076e-06, + 0.0001479121002112239, + 1.0003971464594963, + 3.9536170159753443e-05, + 2.5853406633669654e-06, + 0.0001012477669236068, + 7.933617991373189e-05, + 0.005937531341288544, + 6.116235985298115e-05, + 8.651694171316354e-05, + 1.858511569018207e-05, + 5.597548049290373e-05, + 0.0010902598840878482, + 1.6206885535492838e-05, + 1.0482807165536582e-05, + 0.007111014770507566, + 3.026971897764431e-05, + 9.075276578589366e-05, + 4.7243792305993805e-05, + 8.759244847284295e-06, + 5.157027738322318e-05, + 4.849876254314921e-05, + 2.1787544078622775e-05, + 2.7198580063679282e-05, + 2.8838670323751205e-05, + 0.006256769866490425, + 0.001232839274524128, + 0.009832220847402985, + 9.476836787913726e-06, + 9.194877552631466e-05, + 1.7386720499088466e-06, + 1.1261487041142267e-05, + 2.116693775127853e-05, + 7.623227138481154e-05, + 1.6007448693199368e-06, + 1.974601693940481e-05, + 5.245897082846726e-05, + 0.006796385353731588, + 0.0001594947964237924, + 2.973840254558375e-05, + 7.490029829638944e-05, + 4.036930180264357e-05, + 8.218202439742403e-05, + 2.8154529321024527e-05, + 2.883557709799689e-05, + 0.008534519561254493, + 4.156106397999411e-06, + 3.54518836652093e-05, + 0.006222048667824248, + 7.883599940851821e-05, + 2.2487394622544145e-05, + 2.6445664430825162e-06, + 8.477351939698314e-05, + 1.1478516439581388e-05, + 1.2188625738568068e-05, + 7.040445704723166e-05, + 0.0019808005861819576, + 1.2854505722798077e-05, + 0.0019505472223636333, + 1.1752268666632123e-05, + 9.355601373532127e-05, + 7.849728077354606e-05, + 0.00010936821654083165, + 7.684621219798062e-05, + 5.977129380080876e-05, + 8.077315543870918e-06, + 8.181005804706189e-05, + 2.174789309648852e-05, + 6.305125415772337e-05, + 0.009122020485873628, + 8.784487795116046e-05, + 1.9266161726239038e-05, + 0.009744246327290896, + 2.9295282855615235e-05, + 0.00130153079327133, + 4.5797633600523134e-06, + 0.008592458769033464, + 0.0044026206126353655, + 0.0006133619759453804, + 2.3827168497977226e-05, + 3.783818615351871e-06, + 2.001031923930151e-05, + 1.732762971576925e-05, + 1.0004064404683561, + 1.658640530590938e-05, + 7.405061225080043e-05, + 0.0012335807356279886, + 2.9507190624179216e-05, + 2.9396639749410458e-05, + 2.0225316812531166e-05, + 6.600953573744792e-05, + 3.527685498118427e-05, + 0.0055860723141447684, + 0.0027643037349795144, + 0.004752970738232557, + 0.0024985379607832957, + 3.61809234611927e-05, + 8.001581192602237e-06, + 5.035059539802786e-06, + 3.9934496549270716e-05, + 1.1918029804950755e-06, + 8.844973558735425e-06, + 4.962050411035719e-06, + 9.09074558996317e-06, + 0.003910368997623035, + 1.5765266083114732e-05, + 1.5703286642692057e-05, + 1.3089510001785621e-05, + 3.6875617603695455e-06, + 1.5318526814856903e-05, + 1.6648212270453975e-05, + 0.00188385009334873, + 5.038538789141869e-06, + 4.959806571644058e-05, + 4.573898088787692e-05, + 8.283092032568344e-05, + 4.315960899625176e-05, + 8.80187196272973e-05, + 0.008963041275584496, + 3.5363666992940155e-05, + 3.6960655441931726e-05, + 1.6306202238306393e-05, + 4.2474491256049146e-05, + 7.929394171683288e-05, + 3.4778956437108256e-06, + 3.312989228982466e-06, + 5.328558922832335e-07, + 3.46151188786036e-05, + 7.429189137403037e-07, + 2.8887654452486578e-05, + 0.007699851554496911, + 3.2669094648244773e-06, + 6.865839426972015e-08, + 5.2222019800368575e-05, + 9.250690181223868e-05, + 0.004938488230247744, + 0.002965796072866161, + 0.00915211765251319, + 9.705123470081156e-05, + 4.3871349822661094e-05, + 0.00042286073353053205, + 4.928443982842512e-05, + 2.1655730003934487e-05, + 3.3352789969766985e-05, + 2.2852157316310878e-05, + 4.5523933983688476e-05, + 6.112496302509246e-05, + 1.000272566936319, + 2.9295282855615235e-05, + 3.567549464296331e-05, + 0.011055507216417616, + 8.654641647049102e-05, + 0.005903640664409296, + 0.007621533699389588, + 5.408312218936873e-05, + 1.619573616404499e-05, + 0.004257099225473964, + 3.716813088547636e-05, + 1.7199603304863812e-05, + 1.8428138804039813e-05, + 0.005641913561175485, + 3.6468725047509243e-06, + 1.697154319579523e-05, + 1.300046522527695e-05, + 1.7490310600702375e-05, + 2.691506463774306e-06, + 2.3007962908176834e-05, + 0.002752361059311225, + 2.0337974678940336e-05, + 1.188084764263294e-05, + 8.111616680886158e-06, + 1.1992982759795414e-05, + 6.015624802294293e-05, + 3.5078202872376415e-05, + 2.1613058386334702e-05, + 2.4937042062898712e-05, + 7.636203446290959e-05, + 5.400377972758566e-05, + 0.007938956551945167, + 8.805908936468158e-06, + 0.009083110322041153, + 2.0262792069064637e-05, + 1.0800165987017764e-05, + 2.5324083389253696e-06, + 1.6037235818269438e-05, + 5.73502575314267e-06, + 0.0007179782566983814, + 6.204465674665756e-05, + 8.04680136256436e-05, + 0.0026332132949579883, + 0.0001246807859027139, + 2.0646085382212123e-05, + 3.667290377192227e-05, + 1.9452907879640914e-05, + 6.648775300564829e-05, + 5.467452991247206e-05, + 6.170463670825358e-06, + 1.732762971576925e-05, + 0.002946774207824383, + 0.00010797040109734197, + 6.180610405893971e-05, + 6.203012046578658e-05, + 0.0030345791284893233, + 2.619931980962859e-05, + 1.7279945498281717e-05, + 0.0064067636604403086, + 0.006357808687633092, + 4.7927871872026924e-05, + 0.0002062465091986742, + 7.31414159273588e-05, + 1.017183487279046, + 6.711352737675126e-05, + 5.235179554840961e-05, + 4.764519943351331e-05, + 7.164637249194579e-05, + 8.39792052135796e-05, + 2.9776421787722422e-05, + 6.244920472937696e-05, + 7.774943916630372e-05, + 8.369797878943574e-05, + 0.009287224138628118, + 5.744975875099374e-06, + 9.03558246672859e-06, + 2.162203723537085e-05, + 3.219552204844843e-05, + 9.782597090310911e-05, + 6.554788593807364e-05, + 3.4302692151672156e-05, + 1.300046522527695e-05, + 5.367080479121616e-05, + 4.05511193210967e-05, + 0.007856691498778193, + 5.731589450935227e-05, + 5.747989602628534e-05, + 9.862047675441458e-06, + 8.574514082806994e-05, + 5.184270392431239e-05, + 4.6049172717572536e-05, + 6.901220565399228e-06, + 7.308391734018726e-05, + 5.375160122425016e-05, + 0.005005808894482987, + 1.4016888306636507e-06, + 1.867823167771344e-05, + 0.005161235266164338, + 0.00639840042891731, + 3.25768819028559e-05, + 2.0880117819139736e-05, + 4.744312810238377e-05, + 0.00706018696690996, + 3.2432119128314313e-05, + 4.3330251548595315e-05, + 0.006559693924237348, + 1.824223373856259e-05, + 4.186941554450491e-05, + 5.794297254880646e-05, + 0.0025612490314566227, + 0.004926455754866431, + 1.2234782130969098e-05, + 0.00013540300672868085, + 3.744616336372351e-05, + 1.879420935773223e-05, + 4.296992740599398e-05, + 0.00648503653023617, + 0.006811594638544919, + 4.865829265027054e-05, + 0.00015039691379098406, + 4.5579882391700233e-05, + 0.0058645951237479765, + 0.00012079849373020242, + 1.1440732422000322e-05, + 0.00011931118425226127, + 0.00010310363765821542, + 0.0029571873238747764, + 0.00014836819241966453, + 6.479496401931944e-05, + 0.00013652022364646203, + 0.008272674602401412, + 6.112496302509246e-05, + 0.009744246327290896, + 3.0746562325406976e-05, + 7.131459924188185e-05, + 3.586343427183496e-05, + 1.4573046498807523e-05, + 0.0039026607996137945, + 0.0026200093998360965, + 0.00242858334084194, + 1.0058255821628395, + 8.573630025876962e-06, + 0.002554135913483182, + 0.006161186192549629, + 6.897019142137336e-06, + 7.991859104992195e-05, + 0.002859745735827901, + 9.546069637881966e-05, + 0.005263923874568061, + 0.0057750436745369355, + 5.267454634504788e-05, + 0.004679745180711632, + 5.8729422882028494e-05, + 1.8734155484644436e-06, + 1.2288862401220086e-06, + 3.8744548382065554e-05, + 4.2505389300810915e-05, + 4.001426304671741e-05, + 3.4881950218393824e-05, + 1.9953765773175086e-05, + 9.647701407466116e-06, + 5.757301024859485e-05, + 2.7396178308899984e-05, + 0.0028681574720703117, + 0.004752970738232557, + 4.328259607237442e-05, + 1.4425087088570349e-05, + 3.219552204844843e-05, + 0.006256769866490425, + 1.843783095389692e-05, + 6.757292987282388e-05, + 8.616175865337904e-06, + 3.6468725047509243e-06, + 0.0013013807746215947, + 2.3463588718664166e-05, + 8.484749056658531e-06, + 3.942136473014121e-05, + 6.045509972018361e-05, + 2.170212323715844e-05, + 2.9990147075282934e-05, + 1.656838550283511e-06, + 3.275334088345922e-05, + 7.312414951957388e-06, + 0.013780337834186657, + 0.009295247913139942, + 4.276492816919655e-05, + 9.614526501090822e-05, + 0.013438832548117487, + 5.706019083774347e-05, + 3.9953097404302765e-05, + 7.395084545201742e-05, + 5.6874060280116495e-06, + 0.0014860797174881262, + 5.742099408205895e-06, + 0.005126444542508474, + 0.004525181008797196, + 1.0966824173649002e-05, + 0.00549933348301436, + 1.5106463096119683e-05, + 1.1136795167012167e-05, + 0.0016826044433800413, + 3.8048334218202605e-05, + 4.266113161881524e-05, + 8.61084221273961e-05, + 1.2827787409715243e-05, + 2.957012864087119e-05, + 4.470866250334624e-05, + 0.005304731871977922, + 4.7380954835658765e-05, + 0.009180813294514662, + 0.00010938912433855871, + 4.8878825131751535e-05, + 6.086804239422096e-05, + 5.198791482656931e-05, + 9.330886000894899e-05, + 4.003025947351584e-05, + 8.894990992311741e-05, + 8.490755068004092e-05, + 7.397498922067364e-05, + 1.298044941180189e-05, + 7.923441900497486e-05, + 0.00795786731176502, + 0.00010528753431476505, + 1.0003394409324793, + 0.002066966424496967, + 0.0072466957647136405, + 1.8408154591897332e-05, + 2.6170465216380154e-05, + 7.391753503787828e-07, + 4.862973927123171e-06, + 9.175661661202585e-05, + 2.843055287948848e-06, + 0.010279256328935539, + 4.18806829585507e-06, + 0.0005059685367658173, + 3.133972759601782e-05, + 0.004980246622128062, + 4.442344954711435e-05, + 3.5204792102386216e-05, + 7.438842701197541e-05, + 0.00010228567311313031, + 5.458421368513962e-05, + 3.6380520404962396e-05, + 0.005956877741835263, + 0.0058768241372289, + 3.2394319262609834e-05, + 5.0087594202736606e-05, + 0.0089202536935198, + 0.013438832548117487, + 5.068234755661218e-07, + 2.059942267026535e-05, + 0.004038422827637369, + 8.886247607167789e-05, + 9.548755468020766e-05, + 4.4844266449640813e-05, + 3.3321946258636567e-05, + 4.51632447994695e-05, + 0.009546401607162315, + 0.0011979513772529824, + 0.004448178781097971, + 0.007158975274909028, + 0.003405796470211449, + 7.308391734018726e-05, + 1.5703286642692057e-05, + 0.0013023827143545978, + 1.773236913896812e-05, + 2.2622216737783084e-05, + 1.468252114735999e-06, + 3.503912963572349e-06, + 3.232509725475268e-05, + 0.00010584745468589411, + 4.246587373330859e-07, + 0.0015357985919753874, + 1.1663596453736771e-05, + 4.6510875847825296e-05, + 7.883599940851821e-05, + 4.232256890170172e-05, + 4.157804352074367e-06, + 0.0009434926438126656, + 0.0007991026022771701, + 8.673170287506496e-05, + 0.009377706183599573, + 6.492634734915772e-05, + 0.008851514555513171, + 2.408253652537229e-05, + 3.390535436114262e-05, + 8.500073672303659e-05, + 0.007337281118937193, + 6.841527427324271e-05, + 7.454297128879022e-05, + 4.485651296957946e-05, + 1.817098185835928e-05, + 0.00571553669088225, + 0.0002192081488419424, + 4.880167751546794e-05, + 0.00012386310278921677, + 0.004340989890632332, + 0.008338421645317543, + 2.988522877189406e-05, + 8.163737875101414e-05, + 0.0003744931963655796, + 5.311863651417748e-05, + 1.0006811004413325, + 6.311322749339541e-05, + 0.009423377551926036, + 0.0001351869158332422, + 6.471299638717376e-05, + 4.5559832168017325e-05, + 0.00014728026048875834, + 7.007217650806319e-05, + 0.00013616695276437934, + 0.009827093921226878, + 0.00014087934069183532, + 0.0004466121637889875, + 0.006854405223712914, + 0.0070778397836248255, + 0.007058824446817216, + 0.00640193868537032, + 6.9481289418868506e-06, + 0.0036699814726822077, + 2.147224746167066e-05, + 2.306744948090414e-05, + 1.1862578488334266e-06, + 3.783128411679979e-05, + 2.7943759314982804e-05, + 4.787322589202522e-05, + 0.008560723438005933, + 0.0078036394547676404, + 7.661734569325919e-05, + 1.914398375550642e-05, + 3.717180985853054e-05, + 4.5465306232506115e-05, + 0.00011739049928613754, + 0.008617716809513676, + 4.038446263170618e-05, + 6.052271248082022e-06, + 2.450334734056812e-05, + 0.00549933348301436, + 3.686578049401734e-05, + 1.3500497663962548e-05, + 0.006804287846315139, + 0.003837912559068474, + 0.0001087401656131354, + 6.841599600088951e-05, + 4.862375713081473e-07, + 0.009377706183599573, + 3.4677134824006374e-09, + 8.709392167994599e-08, + 3.5405275164337536e-07, + 0.0058248967139245935, + 7.581259308717127e-08, + 4.985196467268206e-05, + 2.5591472821463486e-05, + 4.3755520141460105e-07, + 5.233154862039399e-06, + 2.628279587583401e-07, + 3.4421275378160735e-07, + 2.6714321060972634e-07, + 0.00012090014934069268, + 4.5873095412197237e-07, + 4.9644642230663515e-06, + 1.000142157056739, + 0.00242858334084194, + 1.754746680391694e-05, + 2.8342207263042518e-05, + 1.5694842719006986e-05, + 1.4115982854095151e-05, + 2.5613491124066854e-05, + 3.8638061642113294e-05, + 7.08690593428671e-05, + 0.005316713458998503, + 2.8923941111746002e-05, + 2.052195184514316e-06, + 0.002235762253920633, + 7.014458098379015e-06, + 7.472068481635205e-05, + 0.009092323764615015, + 0.004215542482180343, + 0.009339513385827183, + 1.473775828964842e-05, + 7.177313382859093e-06, + 3.0086491323618898e-05, + 2.2621518051178686e-05, + 5.598447718045988e-06, + 4.30662229714024e-06, + 6.627270386680282e-07, + 4.744312810238377e-05, + 2.880816747198646e-05, + 5.551330944747475e-05, + 4.3422810041187425e-05, + 0.007696421638836545, + 7.667920282896653e-05, + 5.801413329136704e-05, + 3.5363666992940155e-05, + 0.007710383702448548, + 4.5312749216232344e-05, + 6.902350664223597e-06, + 3.155285473097504e-05, + 4.071855624915881e-06, + 6.0979077600877525e-06, + 4.662078208548067e-06, + 4.604520513321305e-06, + 1.5511247519254373e-08, + 1.0479176239748488e-06, + 6.830114907139503e-06, + 0.0017614905000378658, + 0.00010672287848834117, + 8.100221253346378e-07, + 7.419336729443077e-07, + 3.3991256312993264e-05, + 6.902447524591277e-05, + 0.003839725262471517, + 8.570889656902395e-05, + 2.5997154839160077e-05, + 5.5540199060968216e-05, + 7.308022435673637e-05, + 3.7779296004229136e-05, + 0.005454660455186017, + 3.004152528081633e-05, + 2.1516653637500003e-05, + 6.313932232818006e-05, + 0.003789193622807026, + 2.001031923930151e-05, + 4.812969575941697e-05, + 2.4500541892901417e-05, + 7.790316917247569e-05, + 0.00010630503753370316, + 0.008061790939854345, + 3.0255537649567676e-05, + 1.9955252480012823e-05, + 4.848704502905711e-05, + 0.007315470196481674, + 0.0033140161641720288, + 2.5780883983877218e-05, + 1.0002108841077482, + 7.31414159273588e-05, + 0.0032308706257639114, + 1.836210569087713e-05, + 1.671129286964195e-05, + 2.817754802475255e-05, + 4.231435282329788e-06, + 9.486510994712678e-06, + 2.1903716683254796e-05, + 3.7744090451044085e-05, + 9.682822996583617e-05, + 0.0029512563984702782, + 1.844624633903237e-05, + 3.191294170529035e-05, + 2.2130008087780147e-05, + 9.915672087837691e-05, + 0.003013917957663592, + 0.0027052178017184657, + 0.0026360543980688145, + 4.419688041692284e-05, + 6.204363681200837e-05, + 3.025985047345458e-05, + 8.17597435056736e-06, + 5.9992598886879715e-05, + 3.4302692151672156e-05, + 1.697154319579523e-05, + 0.00669183652199143, + 4.6149482328255726e-05, + 0.006820772970732364, + 3.7378004968560184e-05, + 9.194877552631466e-05, + 0.003967276004683859, + 3.177050433723157e-07, + 3.774635551090802e-05, + 1.0802323681468716e-05, + 3.6872163354419606e-05, + 3.3445602506082165e-05, + 9.176872048322657e-06, + 1.4517033957637429e-05, + 2.3464494097835496e-05, + 0.00654750217444128, + 1.260606554655423e-05, + 4.2157943183771885e-05, + 1.8874859837226256e-05, + 1.78710524516326e-05, + 5.5825868717821875e-05, + 7.073516401505625e-05, + 4.154972671783279e-06, + 0.00788135828673028, + 1.805825071175295e-05, + 0.0089202536935198, + 9.614526501090822e-05, + 0.0034308146917214903, + 9.945503597024794e-06, + 2.7089114924897626e-05, + 0.0021123970544425484, + 0.00011464695819708957, + 4.64572228654459e-05, + 3.3563580092853017e-06, + 6.601542168847671e-05, + 1.9242846360984317e-06, + 0.008570542520500277, + 4.832756745625646e-05, + 8.274536257263668e-06, + 0.00033545871412157813, + 2.0999175882370937e-06, + 4.604520513321305e-06, + 2.1906009920850237e-05, + 5.796526019303194e-07, + 0.0022034474410589774, + 1.7099755476563073e-05, + 3.316459337939621e-05, + 0.003988215269240574, + 0.0001088050593768327, + 0.00011214618521792638, + 0.008601017543635006, + 5.124321109448016e-05, + 0.009603983607945473, + 3.5592858376339366e-07, + 1.0003950600403508, + 5.6847103838554745e-05, + 2.3909045231668042e-05, + 0.00010989645420088088, + 5.9772051130068166e-05, + 6.3632241538920716e-06, + 8.081471592653644e-05, + 4.101264839737831e-06, + 9.10611133788154e-05, + 0.003614653284985154, + 6.865750563308246e-05, + 1.9982365220095112e-05, + 1.2642191068013989e-05, + 6.256499749409017e-05, + 1.972049328233557e-06, + 0.007633076152122106, + 0.008253979436132665, + 0.003520165825018783, + 0.006152628018747152, + 8.949778834480208e-05, + 1.5202867029995339e-05, + 0.009754505241349513, + 1.7920640048420202e-06, + 0.0009155504675766507, + 7.444172154719142e-06, + 1.2505689816741404e-05, + 7.076122568641112e-05, + 1.6821322945941589e-06, + 4.7675626079801785e-05, + 2.5151047401374303e-05, + 0.0029935243072698762, + 0.008441282349888507, + 4.5704631119594805e-05, + 0.006834759289973527, + 2.799583849796062e-05, + 3.312989228982466e-06, + 0.004515126381855252, + 0.000144358736576273, + 2.858263139481979e-05, + 0.00015183555325760058, + 0.011109083184725779, + 6.77279581052288e-05, + 6.601542168847671e-05, + 6.323381054764368e-05, + 4.6510875847825296e-05, + 0.006222048667824248, + 1.4039561271931087e-05, + 6.040661971505374e-05, + 4.907519256652523e-05, + 6.0979077600877525e-06, + 2.5324083389253696e-06, + 7.454698894418567e-06, + 2.416269384841492e-05, + 0.00983724045435927, + 7.060536541393035e-05, + 0.003607489004396031, + 4.722913778170408e-05, + 9.330886000894899e-05, + 4.301334828362342e-05, + 0.00851023050101972, + 1.3244196667398672e-05, + 6.720359856629058e-05, + 1.1792268179702386e-05, + 0.007374988275636387, + 8.391767317401229e-05, + 0.006554729173032643, + 0.00013417932789838304, + 8.688208808112132e-05, + 0.0008191279921094674, + 0.0001715093884257497, + 2.3895854276530894e-05, + 0.0001479121002112239, + 9.760124850673267e-06, + 0.0014282378997911738, + 0.007255646153887324, + 1.0251676266438782e-05, + 0.0018293532128421254, + 0.0015280277596831245, + 1.0376186007173165e-05, + 2.2472137285700316e-05, + 3.207616483694981e-05, + 8.20396676808335e-06, + 3.3593084677221634e-06, + 0.006382219318046553, + 0.00013392696754589646, + 0.0014518138740913999, + 1.0006541024900906, + 4.9644642230663515e-06, + 0.0026200093998360965, + 0.0001739067643966113, + 0.001268052671563556, + 9.414993358493272e-05, + 0.0077137338986100305, + 2.266465386200731e-05, + 8.105068432626227e-05, + 8.804415323161467e-05, + 2.657005871295784e-05, + 0.007887920773598681, + 9.067980198600438e-05, + 0.0023031022140271094, + 0.00010653288579349231, + 0.0001277688390982566, + 0.008749394056026713, + 0.003332199800398498, + 3.191294170529035e-05, + 3.026971897764431e-05, + 2.8897167742560854e-05, + 3.3857206954811586e-06, + 2.7642468420145466e-05, + 0.00888209193214149, + 1.8785954384074086e-05, + 1.958894495909591e-05, + 8.241318856450491e-05, + 3.61809234611927e-05, + 3.3602864974098526e-05, + 5.429085810404545e-05, + 7.694523948548027e-06, + 4.918019805390054e-05, + 8.572392299435928e-05, + 1.778782434313251e-06, + 5.425778203040552e-05, + 7.444172154719142e-06, + 7.312414951957388e-06, + 0.008121860669464572, + 0.0018985266027096914, + 2.9134358931703176e-05, + 8.943649925289279e-06, + 4.0955284985322874e-05, + 0.006488736813887829, + 5.5843212860730985e-06, + 1.3421878168480512e-05, + 4.904713082344558e-05, + 1.7393470899108238e-05, + 0.001604134906301068, + 2.9446476827046725e-05, + 5.8749181656967195e-05, + 8.257332596159574e-05, + 3.122237635000989e-05, + 8.073755821739811e-05, + 0.006330940003646736, + 5.237202499739881e-05, + 5.905432437917108e-05, + 0.006617942237573037, + 3.659235809869866e-05, + 0.00011739049928613754, + 3.559764352524221e-05, + 3.250308511474092e-05, + 0.004509471864731448, + 4.87111811559589e-06, + 0.008550548609811963, + 5.0719985763207966e-05, + 0.0074382588194354445, + 4.134393643718326e-05, + 4.281663812917758e-05, + 0.00906453844049525, + 2.519599844706269e-05, + 0.005053902503785076, + 1.4892552717406243e-05, + 1.2511572762084668e-05, + 2.830839327894561e-05, + 1.185020908107824e-05, + 5.947613597670801e-06, + 1.0839399538239977e-05, + 1.7654607315174462e-05, + 1.3598258892740924e-05, + 0.0020341300219831504, + 0.005453446633799271, + 2.492884242619572e-05, + 1.0003279959391775, + 0.006811594638544919, + 3.3428408975038574e-05, + 0.0022039957819478574, + 2.035577968764197e-05, + 3.652138838893042e-05, + 9.717628586914298e-05, + 0.0009509364771072949, + 4.772181923265292e-06, + 3.7378004968560184e-05, + 1.3839749949607112e-05, + 7.544933136494426e-07, + 7.010848482190836e-05, + 2.1793448813973866e-05, + 8.461744813480758e-05, + 5.214824211776975e-06, + 1.274185590414587e-05, + 3.447538930700454e-05, + 0.0032183609103764335, + 0.003061799067835776, + 1.3151090432536203e-05, + 1.83301846932302e-05, + 9.317462688392536e-06, + 7.809001938097258e-06, + 1.440955553962265e-05, + 0.009223941671165107, + 3.6380520404962396e-05, + 0.009423005118956355, + 0.001935240152718257, + 0.0004904804093198068, + 0.004321927299556481, + 3.683536136168756e-05, + 8.760010546227632e-06, + 3.659235809869866e-05, + 4.5465306232506115e-05, + 5.184270392431239e-05, + 0.00819832382907284, + 8.7746997810561e-06, + 1.6864204928424063e-05, + 3.8498380768415485e-05, + 8.697263095435295e-05, + 1.1762304592131597e-05, + 7.399152158740839e-05, + 3.191972451121407e-06, + 0.003402162384553347, + 2.401893992812954e-05, + 8.138762190459502e-06, + 4.658818043835977e-06, + 2.2680768964021368e-05, + 3.158419269677393e-05, + 1.5060068616501702e-05, + 0.00013853609608595324, + 0.003625097313221236, + 4.0860568906730575e-05, + 3.066706376961309e-05, + 6.861453876372358e-07, + 0.0012873218666964255, + 2.1017098271407778e-05, + 1.000293516157589, + 9.355601373532127e-05, + 6.833509523082159e-06, + 3.993375566796682e-05, + 0.004441591003607541, + 0.009872411943305133, + 0.00010908601690073171, + 9.025925841730478e-06, + 7.921050259260159e-05, + 9.141793619796793e-05, + 2.430199355672523e-05, + 0.012865204471301449, + 4.5377225727068476e-05, + 7.045607431884256e-05, + 7.583882756894263e-05, + 5.032455958925542e-07, + 0.00015500191455285152, + 1.041461905701894e-06, + 1.3190033228713383e-06, + 1.5309273798143577e-06, + 0.009556394617234216, + 0.006037442885632564, + 3.52533981816771e-05, + 1.2358780250946126e-05, + 1.5943467644657593e-05, + 5.5825868717821875e-05, + 3.16864353202332e-06, + 0.007560260915174101, + 0.004634066879474433, + 0.009609472854344313, + 0.0023256807425682856, + 5.6189019332360594e-06, + 0.002767609432052601, + 0.006488736813887829, + 2.8971481713675734e-05, + 0.006548836331007934, + 8.507831038245505e-05, + 0.0033535155434166993, + 0.004967052543479441, + 4.170074180386796e-05, + 0.006691148114714365, + 2.450334734056812e-05, + 1.0966824173649002e-05, + 0.0073262954486466875, + 6.509212224544221e-06, + 0.006384550706521437, + 5.6017542851683475e-05, + 2.058697160405831e-05, + 9.786425522897559e-05, + 4.215782068752736e-06, + 1.867823167771344e-05, + 0.00012212415535175345, + 7.834536780450026e-06, + 6.595216521287041e-05, + 3.611195890619833e-05, + 0.0001071678049589081, + 0.007495164151567807, + 6.279997697755538e-05, + 4.7301757573742176e-05, + 9.250690181223868e-05, + 1.3612134800845368e-05, + 0.004245174591239174, + 8.394452031494062e-05, + 0.003107753790333846, + 0.0048535845820513075, + 2.436312083575389e-05, + 6.304818718883307e-05, + 9.79414383924028e-05, + 8.484984963731137e-06, + 1.000249718175502, + 0.003789193622807026, + 6.170463670825358e-06, + 3.783818615351871e-06, + 5.906509606247966e-06, + 6.224525801469073e-05, + 8.783274600292875e-06, + 0.004466014513292503, + 4.2842658647721135e-05, + 0.002385822926232189, + 2.6816888588111612e-06, + 7.245178783852634e-05, + 5.699201280114511e-06, + 0.0009830902887607762, + 4.504480980288661e-05, + 0.00793893361762072, + 2.888365587897267e-05, + 5.464438004534413e-05, + 9.023068062958051e-05, + 0.008253979436132665, + 8.759244847284295e-06, + 1.7917148373883355e-05, + 8.616175865337904e-06, + 0.006868664937349099, + 0.009223941671165107, + 3.167044894012793e-07, + 1.3509640250550743e-05, + 8.181167154527567e-06, + 1.6002638384314436e-05, + 1.3866946691552715e-05, + 4.51632447994695e-05, + 2.0074075568947277e-05, + 0.004191427400667957, + 0.002767609432052601, + 0.007785646161814149, + 1.8017238244775715e-05, + 7.174832499906487e-06, + 3.9045702490191184e-05, + 8.545533305049899e-07, + 0.00951396970838286, + 5.0719985763207966e-05, + 0.006559693924237348, + 4.580812393541896e-05, + 5.3005380202982966e-05, + 6.124403934534732e-05, + 0.00011641156866472645, + 3.434636208153656e-05, + 2.1162142534132394e-05, + 0.00011225674094685073, + 7.710549309795944e-05, + 0.007773325140821933, + 0.007404914265770819, + 0.00010016745206491854, + 2.0442660856813986e-05, + 9.369088524743714e-05, + 8.449591102227881e-05, + 7.854359390138303e-05, + 0.00011849937708924003, + 0.00014399155572362174, + 6.0430188781166103e-05, + 0.008073456212003685, + 4.129705794276378e-05, + 0.00010527569821340091, + 7.200823939394418e-05, + 4.367459088655561e-05, + 4.832204262125161e-05, + 8.633795911073606e-05, + 0.00013284441629376648, + 1.839704114108649e-06, + 2.3093786328915213e-05, + 1.4040406457210514e-05, + 3.511630656969946e-05, + 6.668280050031122e-05, + 5.2769736697683524e-05, + 1.8417197291495864e-05, + 0.009630677550983137, + 4.931662042727166e-05, + 1.000545246656902, + 2.5780883983877218e-05, + 0.0002062465091986742, + 9.34511827892779e-05, + 5.803877605658419e-05, + 0.00013016863433750942, + 0.0010627994318390286, + 8.315043882107788e-05, + 0.001098848492576027, + 0.009821730370983375, + 5.315905599966685e-05, + 0.00012730643180779922, + 0.008965663068428692, + 0.00932536085802224, + 0.008016194859820336, + 0.008744145541964786, + 0.0037464921901482874, + 8.114762162992688e-06, + 4.4185831029026516e-05, + 9.526712031344487e-05, + 1.8221410812353872e-05, + 6.782242961139645e-05, + 4.215782068752736e-06, + 1.4016888306636507e-06, + 5.038538789141869e-06, + 5.879348156754798e-07, + 2.9258570574108967e-06, + 5.5266816322073946e-06, + 4.712760169925774e-06, + 1.1197116341924697e-05, + 4.840093735853481e-05, + 3.158419269677393e-05, + 3.6195734375041716e-05, + 2.213282547714912e-05, + 4.0947561295588445e-05, + 7.370596526041767e-05, + 1.649098475312688e-06, + 6.264312554818843e-05, + 6.787198893609816e-05, + 7.642510395190615e-05, + 6.902447524591277e-05, + 5.30035956401809e-05, + 7.795414495027033e-05, + 0.0006170670814896797, + 0.0063204791660593125, + 0.004533179197600133, + 4.837751437608723e-05, + 0.00012580821005702604, + 4.722913778170408e-05, + 5.198791482656931e-05, + 0.009622053112821669, + 0.005320131680220553, + 5.4917651460058454e-05, + 0.00010580887260818803, + 0.008806804007942875, + 0.006532895409013626, + 0.007042734309568557, + 1.0003568344545164, + 7.200823939394418e-05, + 6.25004168927728e-06, + 0.005249400737137344, + 7.943201654792854e-05, + 6.915242362438579e-05, + 4.13354242155286e-05, + 8.377027048123183e-05, + 2.1828240989408474e-05, + 7.007475291609435e-05, + 2.0196582070012896e-06, + 3.3007267523658666e-05, + 7.639022655726693e-05, + 0.009326835203001295, + 0.007720895238812851, + 0.0024137781207065954, + 0.004257099225473964, + 0.003514649711063711, + 0.004346782317554877, + 3.5204792102386216e-05, + 0.0039959851162086795, + 1.5005851203904687e-06, + 3.9533904636675386e-05, + 2.282562280992101e-05, + 2.243657506251215e-05, + 1.184780867061854e-05, + 6.139913854674415e-06, + 3.7681435698580956e-06, + 3.729640223912626e-05, + 2.7505844109233254e-05, + 6.085174025597421e-05, + 0.006728550378096911, + 3.745663236051577e-05, + 2.957012864087119e-05, + 1.2839983888251582e-05, + 2.1917380980842736e-05, + 3.3429279893770895e-05, + 4.0935322624666356e-05, + 0.005574292792643197, + 5.5480085827694036e-05, + 2.8118112264122915e-05, + 2.9408081782277706e-06, + 7.642510395190615e-05, + 3.3991256312993264e-05, + 0.008961675208398875, + 0.008814308982101544, + 6.939682639117589e-05, + 5.203493787178862e-05, + 4.860647658428452e-05, + 0.0082483715939574, + 1.384537377720797e-05, + 3.5592858376339366e-07, + 7.443863429482305e-07, + 6.513160904765917e-07, + 4.2093820849666625e-05, + 8.978547674713963e-07, + 1.7334319453500232e-07, + 0.00410196302462687, + 4.808848753479633e-05, + 0.007507237381039352, + 1.380184495252424e-07, + 0.0038280856297285516, + 1.004324795871614, + 2.3895854276530894e-05, + 3.5351194579500076e-06, + 1.8486741044336282e-06, + 7.85697336266132e-06, + 2.2583435590428477e-05, + 5.3988536601202625e-05, + 0.0006679276000648783, + 2.6797437391880606e-05, + 5.88847363590114e-05, + 2.5296822458611236e-05, + 0.00015990344757346706, + 0.003277712058412189, + 8.287239270239654e-05, + 3.7686390290702356e-05, + 0.0031057701555078734, + 4.7874678062921025e-06, + 6.057074090214067e-07, + 1.7916668586350402e-05, + 0.003332199800398498, + 0.003008892442669965, + 0.002307342766061188, + 0.004912962484832755, + 1.2358780250946126e-05, + 2.9711268059919924e-05, + 3.467896560878684e-05, + 7.627186117384875e-05, + 5.913696972297344e-05, + 5.454227235294692e-05, + 6.681348932005854e-06, + 1.2649259146947333e-05, + 1.2460811952974336e-05, + 6.0329364738038516e-05, + 0.0017900443001192285, + 9.35929561527854e-06, + 3.0247199102358532e-05, + 1.0321254222034239e-05, + 9.64121073613786e-06, + 0.01165854614591907, + 0.00012580821005702604, + 6.086804239422096e-05, + 9.903821108325084e-05, + 2.77877047137349e-05, + 6.429821139034277e-05, + 7.16707002124421e-05, + 6.607100977039375e-05, + 0.015956462186832294, + 1.384537377720797e-05, + 0.009603983607945473, + 2.6896745391710108e-05, + 5.2530022158616034e-05, + 0.008723263430352006, + 3.244198568147392e-05, + 7.276064269692673e-05, + 2.7271073892822847e-05, + 3.627360518329618e-05, + 0.003566473707317041, + 3.3352789969766985e-05, + 0.009122020485873628, + 0.00800148732862001, + 0.005835945780210611, + 1.1173546844994064e-05, + 0.0015280277596831245, + 5.648693036805958e-05, + 1.1849582333965748e-05, + 7.326674752573379e-05, + 4.466158367344553e-05, + 5.298779824764253e-05, + 3.224942461389203e-05, + 6.309220182886564e-05, + 4.119423434434955e-05, + 0.007738007485690339, + 3.9709134277977404e-05, + 1.0003232118112266, + 4.931662042727166e-05, + 0.0033140161641720288, + 4.7927871872026924e-05, + 0.006362434526919624, + 3.5125133690867506e-05, + 3.19672703161189e-05, + 4.319694231074623e-05, + 8.09437286214573e-06, + 1.8146882092870154e-05, + 4.816330275016268e-05, + 0.0010867090112958687, + 4.679176487596852e-05, + 0.005713878505717975, + 0.0031057701555078734, + 0.0029241508388424798, + 0.00821535577889686, + 0.0015414752433633417, + 0.0001950264761052023, + 0.005768832749769458, + 0.00391967740274463, + 0.00961631256625307, + 0.007633076152122106, + 4.7243792305993805e-05, + 9.153726814948286e-06, + 2.2727801295909092e-05, + 5.981155540148864e-05, + 4.912466317868146e-05, + 1.70842049509094e-05, + 6.684710209514219e-06, + 5.9992598886879715e-05, + 5.598447718045988e-06, + 6.554788593807364e-05, + 6.182638644992776e-05, + 9.514188887823765e-06, + 0.001604134906301068, + 3.783128411679979e-05, + 1.4633962622208773e-05, + 0.005332022790581705, + 2.245811070471092e-06, + 3.315445346260335e-05, + 0.004483194454930572, + 2.0303929538564436e-05, + 4.0123999081499147e-05, + 1.0025578146460832e-05, + 1.9466631885063608e-05, + 9.364696675739478e-05, + 1.9905781613356547e-05, + 8.954319224316044e-05, + 1.0002417659140435, + 8.449591102227881e-05, + 8.04680136256436e-05, + 0.009104111949848063, + 6.757392944389293e-05, + 0.0018705960191203576, + 2.700232458322728e-05, + 7.979623164228452e-05, + 0.009127873853865254, + 2.2086846522067662e-05, + 7.216524130910202e-05, + 0.0032689230773739766, + 0.00015500191455285152, + 0.007111014770507566, + 0.006765004772106684, + 0.0036400623550257604, + 3.3321946258636567e-05, + 1.0909411956329585e-05, + 0.009964003685006098, + 6.401808159144565e-06, + 6.324948152687383e-08, + 1.6867752071647554e-06, + 5.066528936150447e-07, + 1.6864204928424063e-05, + 1.2098027758146606e-05, + 4.529448782957032e-05, + 3.937530357228339e-05, + 0.003534239376464677, + 0.008572476068270435, + 0.004956907702287139, + 3.499529266183106e-05, + 1.1858073903861733e-05, + 4.5704631119594805e-05, + 0.0014860797174881262, + 8.604060923538484e-06, + 9.073084147842132e-07, + 0.006712215563463177, + 2.7597202625547482e-05, + 1.00702110158417, + 8.954319224316044e-05, + 9.369088524743714e-05, + 6.204465674665756e-05, + 9.824617476956339e-05, + 0.009248274563630471, + 8.669584320980875e-05, + 2.9019803498547727e-05, + 5.688094456474576e-05, + 0.009809863027986832, + 3.689614821820535e-05, + 7.755706793911599e-05, + 0.008749394056026713, + 0.0024756450814178467, + 0.008126126390881718, + 0.004015417380052825, + 4.504480980288661e-05, + 4.419688041692284e-05, + 4.001426304671741e-05, + 2.155358575807791e-05, + 4.673612943620091e-06, + 5.961322642576858e-06, + 5.52110992687459e-06, + 3.557441043217354e-05, + 1.692812113220369e-05, + 4.573845607783466e-06, + 0.004980246622128062, + 1.2513410853218346e-05, + 1.6194195528969006e-06, + 6.360723619574272e-06, + 9.849916266201628e-06, + 3.554312579674117e-05, + 4.3883882401521954e-05, + 4.6148138070912694e-05, + 3.426856622257189e-05, + 5.414460890939888e-06, + 3.269166597623609e-05, + 7.139367545954369e-06, + 4.840093735853481e-05, + 2.2680768964021368e-05, + 3.780064200939412e-05, + 2.610848019012817e-05, + 4.699549064728338e-05, + 1.4090856331832103e-06, + 4.9384061889323554e-05, + 4.3275702448087675e-05, + 3.4778956437108256e-06, + 4.494637145322238e-05, + 3.746647411616235e-05, + 6.294100436684671e-05, + 3.000535237006113e-05, + 8.311017407393698e-05, + 5.5854783266968745e-05, + 0.00010345871344829712, + 3.391891618363114e-05, + 1.7861680053057874e-05, + 8.391767317401229e-05, + 1.1440732422000322e-05, + 1.2886151317740457e-05, + 4.463507283417051e-05, + 0.004820441889805756, + 0.005573949689002543, + 5.50711807066434e-06, + 0.001357161489069189, + 1.0002440682359617, + 8.484984963731137e-06, + 6.313932232818006e-05, + 5.467452991247206e-05, + 2.3827168497977226e-05, + 6.52507212958729e-05, + 5.4768435409716286e-05, + 9.110823057042535e-05, + 0.001402735417636479, + 2.01100155359697e-05, + 3.6438697281287586e-05, + 0.0023218250123088584, + 0.009349294168833915, + 0.003047843274389201, + 0.008788743162951177, + 0.0005948016310838955, + 0.00706549802282827, + 0.0032689230773739766, + 5.032455958925542e-07, + 9.182993285094491e-06, + 1.619573616404499e-05, + 3.335370314286377e-05, + 4.794364658652151e-05, + 7.657450367907001e-07, + 4.706223389482264e-05, + 0.008911991690964146, + 2.411402431329091e-05, + 0.003183520221360109, + 3.3858432172866734e-05, + 0.004030203448740924, + 9.177955235317567e-06, + 5.848653372189761e-07, + 1.2987571936806203e-05, + 1.805825071175295e-05, + 4.276492816919655e-05, + 2.875512039779854e-07, + 4.1856189126207785e-05, + 4.0027338875076087e-05, + 8.198454746167677e-05, + 0.011977395320336965, + 0.0014970770754504084, + 5.5673337197063254e-05, + 1.3460548600472357e-05, + 7.139367545954369e-06, + 1.1197116341924697e-05, + 4.658818043835977e-06, + 0.004865248238712459, + 0.005289247804570505, + 4.994533857957476e-06, + 0.0013328777498254356, + 6.039959268436595e-06, + 2.4324983724006634e-07, + 4.634868129524442e-05, + 3.54518836652093e-05, + 6.065882887747172e-05, + 8.338065908363515e-06, + 3.619066817315635e-05, + 0.007812326963274855, + 0.006243726979236103, + 4.862375713081473e-07, + 8.673170287506496e-05, + 9.945364267061394e-06, + 0.0006052639682745074, + 5.3386122069419955e-05, + 8.657135190825022e-06, + 0.0011849502227732189, + 2.160030838240172e-05, + 4.8675343537910945e-05, + 5.9320029439863275e-05, + 6.783584304793724e-05, + 0.007525119344665386, + 6.162322138123376e-05, + 1.000223159397379, + 0.0038280856297285516, + 0.0001715093884257497, + 6.192835638460486e-05, + 1.3553940587364827e-06, + 5.760504239152818e-06, + 6.303360450230218e-05, + 0.009281254762723639, + 4.00526336990222e-05, + 8.629260269443107e-05, + 5.841394323541241e-07, + 0.008467305956396259, + 1.3467076728030982e-05, + 0.0024031231029667446, + 2.3102054619062538e-05, + 4.262629380572652e-05, + 0.008476403295092551, + 0.003949451860214621, + 9.182993285094491e-06, + 0.0024137781207065954, + 2.888365587897267e-05, + 3.0658884688565634e-05, + 8.114762162992688e-06, + 0.0008438794789498705, + 3.87764533289644e-06, + 1.8884198800659427e-06, + 7.916043971640084e-06, + 5.951938020031008e-06, + 0.006820772970732364, + 9.476836787913726e-06, + 2.5660230268410952e-05, + 3.283564120768238e-05, + 7.617858133867746e-05, + 3.5321432741907855e-05, + 1.8520492490083216e-05, + 7.190953694790406e-05, + 4.431658039795528e-06, + 2.9297849743894987e-05, + 1.5813697966072556e-06, + 7.48601038810743e-05, + 0.0032183609103764335, + 3.133972759601782e-05, + 4.617323056512292e-05, + 0.007984668065463083, + 1.6709407581142358e-05, + 3.9331586555146806e-05, + 3.275334088345922e-05, + 2.8704814649242224e-05, + 0.00012167373322091522, + 4.005987306107562e-05, + 0.0077918063111136705, + 4.7301757573742176e-05, + 5.2222019800368575e-05, + 2.7808250649402162e-05, + 0.00020211630792040222, + 0.00015933951733862196, + 8.181076850756026e-05, + 9.19925473013565e-05, + 4.3880021412216516e-05, + 5.966011299312112e-05, + 6.37028078542803e-05, + 6.681348932005854e-06, + 4.071855624915881e-06, + 1.0800165987017764e-05, + 1.669025577009584e-06, + 9.009488664252652e-05, + 0.00801246907316579, + 5.409762971466342e-06, + 2.9679459951328885e-06, + 6.4177551223725635e-06, + 0.0008118108024197676, + 2.492884242619572e-05, + 7.664256895218439e-05, + 7.641123007827406e-05, + 0.00023047033185757222, + 7.17937085081615e-05, + 0.009891145193876386, + 0.009262863782751712, + 4.6357147705395986e-05, + 1.000428389132395, + 1.7861680053057874e-05, + 0.007374988275636387, + 0.00012079849373020242, + 0.00858142603278076, + 6.871895392907351e-05, + 1.0388433136278484e-05, + 0.008643936765229692, + 5.987655235048369e-05, + 0.009864768684482637, + 0.008111144119919436, +}; + +sparse_int_t A_ri[] = { + + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, +}; + +sparse_int_t A_cp[] = { + + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, +}; + +real_t A_val[] = { + + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, +}; + +real_t g[] = { + + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, +}; + +real_t lb[] = { + + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, +}; + +real_t ub[] = { + + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, +}; + +real_t lbA[] = { + + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, +}; + +real_t ubA[] = { + + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + }; + +long H_nnz = 6874; +long A_nnz = 10; \ No newline at end of file diff --git a/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/trivial_qp_data.hpp b/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/trivial_qp_data.hpp new file mode 100644 index 0000000..738981b --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/generate_sparse_qp/trivial_qp_data.hpp @@ -0,0 +1,828 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \author Andrea Zanelli + * \version 3.2 + * \date 2022 + * + * QP data generated by a Python script for testing purposes. + */ + + +USING_NAMESPACE_QPOASES + +#define NV 100 +#define NC 10 + +const real_t Inf = INFTY; + +sparse_int_t H_ri[] = { + + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, +}; + +sparse_int_t H_cp[] = { + + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, +}; + +real_t H_val[] = { + + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, +}; + +sparse_int_t A_ri[] = { + + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, +}; + +sparse_int_t A_cp[] = { + + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, +}; + +real_t A_val[] = { + + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, +}; + +real_t g[] = { + + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, +}; + +real_t lb[] = { + + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, + -10000000000.0, +}; + +real_t ub[] = { + + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, + 10000000000.0, +}; + +real_t lbA[] = { + + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0, +}; + +real_t ubA[] = { + + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + }; + +long H_nnz = 100; +long A_nnz = 10; \ No newline at end of file diff --git a/locomotion/src/third_party/qpOASES/examples/qrecipe.cpp b/locomotion/src/third_party/qpOASES/examples/qrecipe.cpp new file mode 100644 index 0000000..9327ee1 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/qrecipe.cpp @@ -0,0 +1,118 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/qrecipe.cpp + * \author Andreas Potschka + * \version 3.2 + * \date 2007-2017 + * + * QRECIPE example from the CUTEr test set with sparse matrices. + */ + + + +#include + +#include "qrecipe_data.hpp" + + + +int main( ) +{ + USING_NAMESPACE_QPOASES + + long i; + int_t nWSR; + real_t err, tic, toc; + real_t *x1 = new real_t[180]; + real_t *y1 = new real_t[271]; + real_t *x2 = new real_t[180]; + real_t *y2 = new real_t[271]; + + /* create sparse matrices */ + SymSparseMat *H = new SymSparseMat(180, 180, H_ri, H_cp, H_val); + SparseMatrix *A = new SparseMatrix(91, 180, A_ri, A_cp, A_val); + + H->createDiagInfo(); + + real_t* H_full = H->full(); + real_t* A_full = A->full(); + + SymDenseMat *Hd = new SymDenseMat(180,180,180,H_full); + DenseMatrix *Ad = new DenseMatrix(91,180,180,A_full); + + /* solve with dense matrices */ + nWSR = 1000; + QProblem qrecipeD(180, 91); + tic = getCPUtime(); + qrecipeD.init(Hd, g, Ad, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeD.getPrimalSolution(x1); + qrecipeD.getDualSolution(y1); + + fprintf(stdFile, "Solved dense problem in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* solve with sparse matrices */ + nWSR = 1000; + QProblem qrecipeS(180, 91); + tic = getCPUtime(); + qrecipeS.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeS.getPrimalSolution(x2); + qrecipeS.getDualSolution(y2); + + fprintf(stdFile, "Solved sparse problem in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* check distance of solutions */ + err = 0.0; + for (i = 0; i < 180; i++) + if (getAbs(x1[i] - x2[i]) > err) + err = getAbs(x1[i] - x2[i]); + fprintf(stdFile, "Primal error: %9.2e\n", err); + err = 0.0; + for (i = 0; i < 271; i++) + if (getAbs(y1[i] - y2[i]) > err) + err = getAbs(y1[i] - y2[i]); + fprintf(stdFile, "Dual error: %9.2e (might not be unique)\n", err); + + delete H; + delete A; + delete[] H_full; + delete[] A_full; + delete Hd; + delete Ad; + + delete[] y2; + delete[] x2; + delete[] y1; + delete[] x1; + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/qrecipeSchur.cpp b/locomotion/src/third_party/qpOASES/examples/qrecipeSchur.cpp new file mode 100644 index 0000000..d63b29c --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/qrecipeSchur.cpp @@ -0,0 +1,165 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file examples/qrecipeSchur.cpp + * \author Dennis Janka + * \version 3.2 + * \date 2007-2017 + * + * QRECIPE example from the CUTEr test set with sparse matrices. + * Comparison between nullspace factorization (dense and sparse) and + * Schur complement approach. + */ + + +#include +#include "qrecipe_data.hpp" +// #include "generate_sparse_qp/qp_data.hpp" +// #include "generate_sparse_qp/simple_qp_data.hpp" +// #include "generate_sparse_qp/trivial_qp_data.hpp" + +int main( ) +{ + USING_NAMESPACE_QPOASES + + long i; + int_t nWSR; + real_t errP1, errP2, errP3, errD1, errD2, errD3, tic, toc; + real_t *x1 = new real_t[NV]; + real_t *y1 = new real_t[NV+NC]; + real_t *x2 = new real_t[NV]; + real_t *y2 = new real_t[NV+NC]; + real_t *x3 = new real_t[NV]; + real_t *y3 = new real_t[NV+NC]; + + /* create sparse matrices */ + SymSparseMat *H = new SymSparseMat(NV, NV, H_ri, H_cp, H_val); + SparseMatrix *A = new SparseMatrix(NC, NV, A_ri, A_cp, A_val); + + H->createDiagInfo(); + + real_t* H_full = H->full(); + for (int i = 0; i < NV; i++) + for (int j = 0; j < NV; j++) + printf("H[%i,%i] = %f\n", i, j, H_full[i*NV+j]); + real_t* A_full = A->full(); + + SymDenseMat *Hd = new SymDenseMat(NV, NV, NV, H_full); + DenseMatrix *Ad = new DenseMatrix(NC, NV, NV, A_full); + + /* solve with dense matrices */ + nWSR = 1000; + QProblem qrecipeD(NV, NC); + tic = getCPUtime(); + qrecipeD.init(Hd, g, Ad, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeD.getPrimalSolution(x1); + qrecipeD.getDualSolution(y1); + + fprintf(stdFile, "Solved dense problem in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* solve with sparse matrices (nullspace factorization) */ + nWSR = 1000; + QProblem qrecipeS(NV, NC); + tic = getCPUtime(); + qrecipeS.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeS.getPrimalSolution(x2); + qrecipeS.getDualSolution(y2); + + fprintf(stdFile, "Solved sparse problem in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* solve with sparse matrices (Schur complement) */ + nWSR = 1000; + SQProblemSchur qrecipeSchur(NV, NC); + tic = getCPUtime(); + qrecipeSchur.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeSchur.getPrimalSolution(x3); + qrecipeSchur.getDualSolution(y3); + + fprintf(stdFile, "Solved sparse problem (Schur complement approach) in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* check distance of solutions */ + errP1 = 0.0; + errP2 = 0.0; + errP3 = 0.0; + #ifndef SOLVER_NONE + for (i = 0; i < NV; i++) + { + fprintf(stdFile, "x3[%i]=%f\n", i, x3[i]); + if (getAbs(x1[i] - x2[i]) > errP1) + errP1 = getAbs(x1[i] - x2[i]); + } + for (i = 0; i < NV; i++) + if (getAbs(x1[i] - x3[i]) > errP2) + errP2 = getAbs(x1[i] - x3[i]); + for (i = 0; i < NV; i++) + if (getAbs(x2[i] - x3[i]) > errP3) + errP3 = getAbs(x2[i] - x3[i]); + #endif /* SOLVER_NONE */ + fprintf(stdFile, "Primal error (dense and sparse): %9.2e\n", errP1); + fprintf(stdFile, "Primal error (dense and Schur): %9.2e\n", errP2); + fprintf(stdFile, "Primal error (sparse and Schur): %9.2e\n", errP3); + + errD1 = 0.0; + errD2 = 0.0; + errD3 = 0.0; + for (i = 0; i < NV+NC; i++) + if (getAbs(y1[i] - y2[i]) > errD1) + errD1 = getAbs(y1[i] - y2[i]); + #ifndef SOLVER_NONE + for (i = 0; i < NV+NC; i++) + if (getAbs(y1[i] - y3[i]) > errD2) + errD2 = getAbs(y1[i] - y3[i]); + for (i = 0; i < NV+NC; i++) + if (getAbs(y2[i] - y3[i]) > errD3) + errD3 = getAbs(y2[i] - y3[i]); + #endif /* SOLVER_NONE */ + fprintf(stdFile, "Dual error (dense and sparse): %9.2e (might not be unique)\n", errD1); + fprintf(stdFile, "Dual error (dense and Schur): %9.2e (might not be unique)\n", errD2); + fprintf(stdFile, "Dual error (sparse and Schur): %9.2e (might not be unique)\n", errD3); + + delete H; + delete A; + delete[] H_full; + delete[] A_full; + delete Hd; + delete Ad; + + delete[] y3; + delete[] x3; + delete[] y2; + delete[] x2; + delete[] y1; + delete[] x1; + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/examples/qrecipe_data.hpp b/locomotion/src/third_party/qpOASES/examples/qrecipe_data.hpp new file mode 100644 index 0000000..21a7aaf --- /dev/null +++ b/locomotion/src/third_party/qpOASES/examples/qrecipe_data.hpp @@ -0,0 +1,404 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_qrecipe.cpp + * \author Andreas Potschka + * \version 3.2 + * \date 2007-2017 + * + * QRECIPE example from the CUTEr test set with sparse matrices. + */ + + +USING_NAMESPACE_QPOASES + + +#define NV 180 +#define NC 91 + + +const real_t Inf = INFTY; + +sparse_int_t H_cp[] = { 0, 4, 8, 12, 16, 20, 20, 20, 20, 20, 20, + 24, 28, 32, 36, 40, 40, 40, 40, 40, 40, + 44, 48, 52, 56, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 64, 68, 72, 76, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80 }; + +sparse_int_t H_ri[] = { + 0, 10, 20, 34, 1, 11, 21, 35, 2, 12, 22, 36, 3, 13, 23, 37, 4, 14, 24, 38, + 0, 10, 20, 34, 1, 11, 21, 35, 2, 12, 22, 36, 3, 13, 23, 37, 4, 14, 24, 38, + 0, 10, 20, 34, 1, 11, 21, 35, 2, 12, 22, 36, 3, 13, 23, 37, 4, 14, 24, 38, + 0, 10, 20, 34, 1, 11, 21, 35, 2, 12, 22, 36, 3, 13, 23, 37, 4, 14, 24, 38}; + +real_t H_val[] = {10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, + 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 1, + 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 1, 10, 1, + 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10}; + +sparse_int_t A_cp[] = { + 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, + 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, + 280, 290, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 331, + 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, + 363, 365, 367, 369, 371, 373, 383, 393, 403, 405, 408, 410, 413, 415, 418, + 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, + 450, 452, 454, 456, 458, 460, 462, 472, 482, 492, 494, 497, 499, 502, 504, + 507, 509, 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, + 537, 539, 541, 543, 545, 547, 549, 551, 561, 571, 581, 583, 586, 588, 591, + 593, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, + 610, 611, 612, 613, 614, 615, 616, 617, 618, 628, 638, 648, 650, 653, 655, + 658, 660, 663}; + +sparse_int_t A_ri[] = {0, 14, 35, 36, 71, 72, 85, 86, 87, 88, 1, 14, 35, 36, 71, 72, 85, + 86, 87, 88, 2, 14, 35, 36, 71, 72, 85, 86, 87, 88, 3, 14, 35, 36, 71, 72, + 85, 86, 87, 88, 4, 14, 35, 36, 71, 72, 85, 86, 87, 88, 5, 14, 35, 36, 71, + 72, 85, 86, 87, 88, 6, 14, 35, 36, 71, 72, 85, 86, 87, 88, 7, 14, 35, 36, + 71, 72, 85, 86, 87, 88, 8, 14, 35, 36, 71, 72, 85, 86, 87, 88, 9, 14, 35, + 36, 71, 72, 85, 86, 87, 88, 0, 15, 37, 38, 69, 70, 79, 80, 81, 82, 1, 15, + 37, 38, 69, 70, 79, 80, 81, 82, 2, 15, 37, 38, 69, 70, 79, 80, 81, 82, 3, + 15, 37, 38, 69, 70, 79, 80, 81, 82, 4, 15, 37, 38, 69, 70, 79, 80, 81, 82, + 5, 15, 37, 38, 69, 70, 79, 80, 81, 82, 6, 15, 37, 38, 69, 70, 79, 80, 81, + 82, 7, 15, 37, 38, 69, 70, 79, 80, 81, 82, 8, 15, 37, 38, 69, 70, 79, 80, + 81, 82, 9, 15, 37, 38, 69, 70, 79, 80, 81, 82, 0, 16, 39, 40, 67, 68, 73, + 74, 75, 76, 1, 16, 39, 40, 67, 68, 73, 74, 75, 76, 2, 16, 39, 40, 67, 68, + 73, 74, 75, 76, 3, 16, 39, 40, 67, 68, 73, 74, 75, 76, 4, 16, 39, 40, 67, + 68, 73, 74, 75, 76, 5, 16, 39, 40, 67, 68, 73, 74, 75, 76, 6, 16, 39, 40, + 67, 68, 73, 74, 75, 76, 7, 16, 39, 40, 67, 68, 73, 74, 75, 76, 8, 16, 39, + 40, 67, 68, 73, 74, 75, 76, 9, 16, 39, 40, 67, 68, 73, 74, 75, 76, 10, 11, + 12, 13, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 47, 58, 48, 59, 49, 60, 50, 61, 51, 62, 52, 63, 53, + 64, 54, 65, 55, 66, 46, 56, 45, 57, 47, 58, 48, 59, 49, 60, 50, 61, 51, 62, + 52, 63, 53, 64, 54, 65, 55, 66, 46, 56, 45, 57, 10, 14, 71, 72, 85, 86, 87, + 88, 89, 90, 11, 15, 69, 70, 79, 80, 81, 82, 83, 84, 12, 16, 67, 68, 73, 74, + 75, 76, 77, 78, 35, 90, 36, 89, 90, 37, 84, 38, 83, 84, 39, 78, 40, 77, 78, + 44, 58, 43, 59, 42, 60, 41, 61, 34, 62, 33, 63, 32, 64, 31, 65, 30, 66, 29, + 46, 28, 45, 44, 58, 43, 59, 42, 60, 41, 61, 34, 62, 33, 63, 32, 64, 31, 65, + 30, 66, 29, 46, 28, 45, 10, 14, 71, 72, 85, 86, 87, 88, 89, 90, 11, 15, 69, + 70, 79, 80, 81, 82, 83, 84, 12, 16, 67, 68, 73, 74, 75, 76, 77, 78, 35, 90, + 36, 89, 90, 37, 84, 38, 83, 84, 39, 78, 40, 77, 78, 27, 44, 26, 43, 25, 42, + 24, 41, 23, 34, 22, 33, 21, 32, 20, 31, 19, 30, 18, 29, 17, 28, 27, 44, 26, + 43, 25, 42, 24, 41, 23, 34, 22, 33, 21, 32, 20, 31, 19, 30, 18, 29, 17, 28, + 10, 14, 71, 72, 85, 86, 87, 88, 89, 90, 11, 15, 69, 70, 79, 80, 81, 82, 83, + 84, 12, 16, 67, 68, 73, 74, 75, 76, 77, 78, 35, 90, 36, 89, 90, 37, 84, 38, + 83, 84, 39, 78, 40, 77, 78, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 27, + 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 10, 14, 71, 72, 85, 86, 87, 88, 89, + 90, 11, 15, 69, 70, 79, 80, 81, 82, 83, 84, 12, 16, 67, 68, 73, 74, 75, 76, + 77, 78, 35, 90, 36, 89, 90, 37, 84, 38, 83, 84, 39, 78, 40, 77, 78}; + +real_t A_val[] = { +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.8678200000000004e+01, + 9.3617050000000006e+01, 1.6000000000000000e+01, 8.1999999999999993e+00, + 9.9000000000000000e+01, 8.0000000000000000e+01, 1.2000000000000000e+01, + 9.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.0062830000000005e+01, 9.9224010000000007e+01, 1.0000000000000000e+02, + 2.1100000000000001e+01, 1.0000000000000000e+02, 1.0000000000000000e+02, + 1.1400000000000000e+02, 1.1680000000000000e+02, -1.0000000000000000e+00, + 1.0000000000000000e+00, 7.4697360000000003e+01, 8.3801220000000001e+01, +-8.1999999999999993e+00, 2.0000000000000000e+00, 9.0000000000000000e+01, + 2.3999999999999999e+00, -1.2000000000000000e+01, -1.4800000000000001e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 7.9194209999999998e+01, + 9.0175110000000004e+01, 4.3000000000000000e+01, 8.0000000000000000e+00, + 1.0000000000000000e+02, 9.5000000000000000e+01, 9.0000000000000000e+00, + 2.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, + 7.8568219999999997e+01, 8.5996200000000002e+01, -1.2500000000000000e+01, + 1.0000000000000000e+00, 9.6500000000000000e+01, 4.0000000000000000e+00, +-1.8000000000000000e+01, -2.1899999999999999e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.2922240000000002e+01, 8.6963380000000001e+01, + 6.5000000000000000e+01, 1.2500000000000000e+01, 1.0000000000000000e+02, + 9.8000000000000000e+01, 4.9000000000000000e+01, 3.7000000000000000e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.2592740000000006e+01, + 9.3147599999999997e+01, -1.2000000000000000e+01, 1.0000000000000000e+00, + 9.6500000000000000e+01, 4.0000000000000000e+00, -1.8000000000000000e+01, +-2.1899999999999999e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 7.6506460000000004e+01, 7.8210250000000002e+01, 7.9000000000000000e+01, + 1.2000000000000000e+01, 1.0000000000000000e+02, 9.5000000000000000e+01, + 6.8000000000000000e+01, 6.1000000000000000e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.8357460000000003e+01, 9.4257840000000002e+01, + 1.2500000000000000e+02, 6.1299999999999997e+01, 1.0000000000000000e+02, + 1.0000000000000000e+02, 1.4500000000000000e+02, 1.4500000000000000e+02, +-1.0000000000000000e+00, 1.0000000000000000e+00, 9.0590469999999996e+01, + 1.0582863000000000e+02, 6.2000000000000002e+00, 6.0000000000000000e+00, + 9.7000000000000000e+01, 2.8500000000000000e+01, 4.0000000000000000e+00, + 3.6000000000000001e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.8678200000000004e+01, 9.3617050000000006e+01, 1.6000000000000000e+01, + 8.1999999999999993e+00, 9.9000000000000000e+01, 8.0000000000000000e+01, + 1.2000000000000000e+01, 9.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.0062830000000005e+01, 9.9224010000000007e+01, + 1.0000000000000000e+02, 2.1100000000000001e+01, 1.0000000000000000e+02, + 1.0000000000000000e+02, 1.1400000000000000e+02, 1.1680000000000000e+02, +-1.0000000000000000e+00, 1.0000000000000000e+00, 7.4697360000000003e+01, + 8.3801220000000001e+01, -8.1999999999999993e+00, 2.0000000000000000e+00, + 9.0000000000000000e+01, 2.3999999999999999e+00, -1.2000000000000000e+01, +-1.4800000000000001e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 7.9194209999999998e+01, 9.0175110000000004e+01, 4.3000000000000000e+01, + 8.0000000000000000e+00, 1.0000000000000000e+02, 9.5000000000000000e+01, + 9.0000000000000000e+00, 2.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, 7.8568219999999997e+01, 8.5996200000000002e+01, +-1.2500000000000000e+01, 1.0000000000000000e+00, 9.6500000000000000e+01, + 4.0000000000000000e+00, -1.8000000000000000e+01, -2.1899999999999999e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.2922240000000002e+01, + 8.6963380000000001e+01, 6.5000000000000000e+01, 1.2500000000000000e+01, + 1.0000000000000000e+02, 9.8000000000000000e+01, 4.9000000000000000e+01, + 3.7000000000000000e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.2592740000000006e+01, 9.3147599999999997e+01, -1.2000000000000000e+01, + 1.0000000000000000e+00, 9.6500000000000000e+01, 4.0000000000000000e+00, +-1.8000000000000000e+01, -2.1899999999999999e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 7.6506460000000004e+01, 7.8210250000000002e+01, + 7.9000000000000000e+01, 1.2000000000000000e+01, 1.0000000000000000e+02, + 9.5000000000000000e+01, 6.8000000000000000e+01, 6.1000000000000000e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.8357460000000003e+01, + 9.4257840000000002e+01, 1.2500000000000000e+02, 6.1299999999999997e+01, + 1.0000000000000000e+02, 1.0000000000000000e+02, 1.4500000000000000e+02, + 1.4500000000000000e+02, -1.0000000000000000e+00, 1.0000000000000000e+00, + 9.0590469999999996e+01, 1.0582863000000000e+02, 6.2000000000000002e+00, + 6.0000000000000000e+00, 9.7000000000000000e+01, 2.8500000000000000e+01, + 4.0000000000000000e+00, 3.6000000000000001e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.8678200000000004e+01, 9.3617050000000006e+01, + 1.6000000000000000e+01, 8.1999999999999993e+00, 9.9000000000000000e+01, + 8.0000000000000000e+01, 1.2000000000000000e+01, 9.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.0062830000000005e+01, + 9.9224010000000007e+01, 1.0000000000000000e+02, 2.1100000000000001e+01, + 1.0000000000000000e+02, 1.0000000000000000e+02, 1.1400000000000000e+02, + 1.1680000000000000e+02, -1.0000000000000000e+00, 1.0000000000000000e+00, + 7.4697360000000003e+01, 8.3801220000000001e+01, -8.1999999999999993e+00, + 2.0000000000000000e+00, 9.0000000000000000e+01, 2.3999999999999999e+00, +-1.2000000000000000e+01, -1.4800000000000001e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 7.9194209999999998e+01, 9.0175110000000004e+01, + 4.3000000000000000e+01, 8.0000000000000000e+00, 1.0000000000000000e+02, + 9.5000000000000000e+01, 9.0000000000000000e+00, 2.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, 7.8568219999999997e+01, + 8.5996200000000002e+01, -1.2500000000000000e+01, 1.0000000000000000e+00, + 9.6500000000000000e+01, 4.0000000000000000e+00, -1.8000000000000000e+01, +-2.1899999999999999e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.2922240000000002e+01, 8.6963380000000001e+01, 6.5000000000000000e+01, + 1.2500000000000000e+01, 1.0000000000000000e+02, 9.8000000000000000e+01, + 4.9000000000000000e+01, 3.7000000000000000e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.2592740000000006e+01, 9.3147599999999997e+01, +-1.2000000000000000e+01, 1.0000000000000000e+00, 9.6500000000000000e+01, + 4.0000000000000000e+00, -1.8000000000000000e+01, -2.1899999999999999e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 7.6506460000000004e+01, + 7.8210250000000002e+01, 7.9000000000000000e+01, 1.2000000000000000e+01, + 1.0000000000000000e+02, 9.5000000000000000e+01, 6.8000000000000000e+01, + 6.1000000000000000e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.8357460000000003e+01, 9.4257840000000002e+01, 1.2500000000000000e+02, + 6.1299999999999997e+01, 1.0000000000000000e+02, 1.0000000000000000e+02, + 1.4500000000000000e+02, 1.4500000000000000e+02, -1.0000000000000000e+00, + 1.0000000000000000e+00, 9.0590469999999996e+01, 1.0582863000000000e+02, + 6.2000000000000002e+00, 6.0000000000000000e+00, 9.7000000000000000e+01, + 2.8500000000000000e+01, 4.0000000000000000e+00, 3.6000000000000001e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, -1.2000000000000000e-01, +-3.8000000000000000e-01, -5.0000000000000000e-01, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, +-4.7000000000000000e+01, -8.6999999999999993e+00, -9.0000000000000000e+01, +-5.0000000000000000e+01, -1.0000000000000000e+01, -1.0000000000000000e+01, +-9.3000000000000000e+01, -8.9000000000000000e+01, 1.0000000000000000e+00, +-1.0000000000000000e+00, -4.7000000000000000e+01, -8.6999999999999993e+00, +-9.0000000000000000e+01, -5.0000000000000000e+01, -1.0000000000000000e+01, +-1.0000000000000000e+01, -8.9000000000000000e+01, -8.5000000000000000e+01, + 1.0000000000000000e+00, -1.0000000000000000e+00, -4.7000000000000000e+01, +-8.6999999999999993e+00, -9.0000000000000000e+01, -5.0000000000000000e+01, +-1.0000000000000000e+01, -1.0000000000000000e+01, -9.1000000000000000e+01, +-8.8000000000000000e+01, -1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 5.0000000000000000e-01, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, -4.7000000000000000e+01, +-8.6999999999999993e+00, -9.0000000000000000e+01, -5.0000000000000000e+01, +-1.0000000000000000e+01, -1.0000000000000000e+01, -9.3000000000000000e+01, +-8.9000000000000000e+01, 1.0000000000000000e+00, -1.0000000000000000e+00, +-4.7000000000000000e+01, -8.6999999999999993e+00, -9.0000000000000000e+01, +-5.0000000000000000e+01, -1.0000000000000000e+01, -1.0000000000000000e+01, +-8.9000000000000000e+01, -8.5000000000000000e+01, 1.0000000000000000e+00, +-1.0000000000000000e+00, -4.7000000000000000e+01, -8.6999999999999993e+00, +-9.0000000000000000e+01, -5.0000000000000000e+01, -1.0000000000000000e+01, +-1.0000000000000000e+01, -9.1000000000000000e+01, -8.8000000000000000e+01, +-1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 5.0000000000000000e-01, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, -4.7000000000000000e+01, -8.6999999999999993e+00, +-9.0000000000000000e+01, -5.0000000000000000e+01, -1.0000000000000000e+01, +-1.0000000000000000e+01, -9.3000000000000000e+01, -8.9000000000000000e+01, + 1.0000000000000000e+00, -1.0000000000000000e+00, -4.7000000000000000e+01, +-8.6999999999999993e+00, -9.0000000000000000e+01, -5.0000000000000000e+01, +-1.0000000000000000e+01, -1.0000000000000000e+01, -8.9000000000000000e+01, +-8.5000000000000000e+01, 1.0000000000000000e+00, -1.0000000000000000e+00, +-4.7000000000000000e+01, -8.6999999999999993e+00, -9.0000000000000000e+01, +-5.0000000000000000e+01, -1.0000000000000000e+01, -1.0000000000000000e+01, +-9.1000000000000000e+01, -8.8000000000000000e+01, -1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, -4.7000000000000000e+01, +-8.6999999999999993e+00, -9.0000000000000000e+01, -5.0000000000000000e+01, +-1.0000000000000000e+01, -1.0000000000000000e+01, -9.3000000000000000e+01, +-8.9000000000000000e+01, 1.0000000000000000e+00, -1.0000000000000000e+00, +-4.7000000000000000e+01, -8.6999999999999993e+00, -9.0000000000000000e+01, +-5.0000000000000000e+01, -1.0000000000000000e+01, -1.0000000000000000e+01, +-8.9000000000000000e+01, -8.5000000000000000e+01, 1.0000000000000000e+00, +-1.0000000000000000e+00, -4.7000000000000000e+01, -8.6999999999999993e+00, +-9.0000000000000000e+01, -5.0000000000000000e+01, -1.0000000000000000e+01, +-1.0000000000000000e+01, -9.1000000000000000e+01, -8.8000000000000000e+01, +-1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 5.0000000000000000e-01}; + +real_t g[] = {+0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, -2e+00, -2e+00, -2e+00, -2e+00, -2e+00, -2e+00, -2e+00, + -2e+00, +0e+00, -2e+00, +0e+00, +2e-03, +2e-03, +2e-03, +2e-03, +2e-03, + +2e-03, +1e-03, +2e-03, +2e-03, +2e-03, +0e+00, -2e-03, -2e-03, -2e-03, + -2e-03, -2e-03, -2e-03, -1e-03, -2e-03, -2e-03, -2e-03, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +2e-03, + +2e-03, +2e-03, +2e-03, +2e-03, +2e-03, +1e-03, +2e-03, +2e-03, +2e-03, + +0e+00, -2e-03, -2e-03, -2e-03, -2e-03, -2e-03, -2e-03, -1e-03, -2e-03, + -2e-03, -2e-03, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +2e-03, +2e-03, +2e-03, +2e-03, +2e-03, +2e-03, + +1e-03, +2e-03, +2e-03, +2e-03, +0e+00, -2e-03, -2e-03, -2e-03, -2e-03, + -2e-03, -2e-03, -1e-03, -2e-03, -2e-03, -2e-03, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +1e-01, +1e-01, + +1e-01, +1e-01, +1e-01, +1e-01, +1e-01, +1e-01, +1e-01, +1e-01, +0e+00, + -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, + -1e-01, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00}; + +real_t lb[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -Inf, 0, -Inf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, + 10, 5, 0, 10, 0, 2, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 5, 10, 5, 0, 10, 0, 5, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 10, 5, 0, 10, 0, 5, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +real_t ub[] = {Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, 0, 92, 39, 87, 29, 0, 20, 0, 28, 20, 71, Inf, 130, 45, 53, 55, 75, + 112, 0, 73, 480, 154, 121, 50, 30, 77, 20, 0, 18, 0, 5, 20, 71, Inf, Inf, + Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, 130, 55, 93, 60, 75, 115, 0, 67, + 480, 154, 121, 50, 20, 37, 15, 0, 15, 0, 8, 20, 71, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, Inf, Inf, Inf, 130, 55, 93, 60, 75, 105, 0, 67, 4980, 154, 110, + 50, 20, 37, 15, 0, 25, 0, 8, 20, 71, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, 20, 20, 20, 20, 0, 20, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf}; + +real_t lbA[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -Inf, -Inf, + -Inf, -Inf, -Inf, -Inf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0}; + +real_t ubA[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, Inf, Inf}; + +long H_nnz = (long) sizeof(H_val) / (long) sizeof(real_t); +long A_nnz = (long) sizeof(A_val) / (long) sizeof(real_t); diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/.gitattributes b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/.gitattributes new file mode 100644 index 0000000..ad9fbed --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/.gitattributes @@ -0,0 +1,18 @@ +* text=auto !eol +/INSTALL.MUMPS -text +/LICENSE -text +/ar-lib -text +/coinmumps.pc.in -text +/compile -text +/config.guess -text +/config.h.in -text +/config.sub -text +/configure -text +/depcomp -text +/get.Mumps -text +/install-sh -text +/ltmain.sh -text +/missing -text +/mumps_compat.h.in -text +/mumps_int_def.h.in -text +/mumps_mpi.patch -text diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/.gitignore b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/.gitignore new file mode 100644 index 0000000..ec6b004 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/.gitignore @@ -0,0 +1 @@ +/MUMPS diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/LICENSE b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/LICENSE new file mode 100644 index 0000000..16cc69a --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/LICENSE @@ -0,0 +1,87 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and + +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/Makefile.am b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/Makefile.am new file mode 100644 index 0000000..9924375 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/Makefile.am @@ -0,0 +1,937 @@ +# Copyright (C) 2007-2010 International Business Machines and others. +# All Rights Reserved. +# This file is distributed under the Eclipse Public License. + +lib_LTLIBRARIES = libcoinmumps.la + +BUILT_SOURCES = +libcoinmumps_la_SOURCES = \ + MUMPS/src/ana_AMDMF.F \ + MUMPS/src/ana_blk.F \ + MUMPS/src/ana_blk_m.F \ + MUMPS/src/ana_omp_m.F \ + MUMPS/src/ana_orderings.F \ + MUMPS/src/ana_orderings_wrappers_m.F \ + MUMPS/src/ana_set_ordering.F \ + MUMPS/src/bcast_errors.F \ + MUMPS/src/double_linked_list.F \ + MUMPS/src/estim_flops.F \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.F \ + MUMPS/src/fac_asm_build_sort_index_m.F \ + MUMPS/src/fac_descband_data_m.F \ + MUMPS/src/fac_future_niv2_mod.F \ + MUMPS/src/fac_ibct_data_m.F \ + MUMPS/src/fac_maprow_data_m.F \ + MUMPS/src/front_data_mgt_m.F \ + MUMPS/src/lr_common.F \ + MUMPS/src/mumps_comm_ibcast.F \ + MUMPS/src/mumps_common.c \ + MUMPS/src/mumps_config_file_C.c \ + MUMPS/src/mumps_io_basic.c \ + MUMPS/src/mumps_io.c \ + MUMPS/src/mumps_io_err.c \ + MUMPS/src/mumps_io_thread.c \ + MUMPS/src/mumps_l0_omp_m.F \ + MUMPS/src/mumps_memory_mod.F \ + MUMPS/src/mumps_metis64.c \ + MUMPS/src/mumps_metis.c \ + MUMPS/src/mumps_metis_int.c \ + MUMPS/src/mumps_mpitoomp_m.F \ + MUMPS/src/mumps_numa.c \ + MUMPS/src/mumps_ooc_common.F \ + MUMPS/src/mumps_pord.c \ + MUMPS/src/mumps_print_defined.F \ + MUMPS/src/mumps_save_restore_C.c \ + MUMPS/src/mumps_scotch64.c \ + MUMPS/src/mumps_scotch.c \ + MUMPS/src/mumps_scotch_int.c \ + MUMPS/src/mumps_size.c \ + MUMPS/src/mumps_static_mapping.F \ + MUMPS/src/mumps_thread_affinity.c \ + MUMPS/src/mumps_register_thread.c \ + MUMPS/src/mumps_thread.c \ + MUMPS/src/mumps_type2_blocking.F \ + MUMPS/src/mumps_type_size.F \ + MUMPS/src/mumps_version.F \ + MUMPS/src/omp_tps_common_m.F \ + MUMPS/src/sol_common.F \ + MUMPS/src/tools_common.F \ + MUMPS/libseq/mpi.f \ + MUMPS/libseq/mpic.c \ + MUMPS/libseq/elapse.c + +if MUMPS_DOUBLE +BUILT_SOURCES += dmumps_c.c +libcoinmumps_la_SOURCES += \ + dmumps_c.c \ + MUMPS/src/dana_aux_ELT.F \ + MUMPS/src/dana_aux.F \ + MUMPS/src/dana_aux_par.F \ + MUMPS/src/dana_dist_m.F \ + MUMPS/src/dana_driver.F \ + MUMPS/src/dana_LDLT_preprocess.F \ + MUMPS/src/dana_lr.F \ + MUMPS/src/dana_mtrans.F \ + MUMPS/src/dana_reordertree.F \ + MUMPS/src/darrowheads.F \ + MUMPS/src/dbcast_int.F \ + MUMPS/src/dend_driver.F \ + MUMPS/src/dfac_asm_ELT.F \ + MUMPS/src/dfac_asm.F \ + MUMPS/src/dfac_asm_master_ELT_m.F \ + MUMPS/src/dfac_asm_master_m.F \ + MUMPS/src/dfac_b.F \ + MUMPS/src/dfac_determinant.F \ + MUMPS/src/dfac_distrib_distentry.F \ + MUMPS/src/dfac_distrib_ELT.F \ + MUMPS/src/dfac_driver.F \ + MUMPS/src/dfac_front_aux.F \ + MUMPS/src/dfac_front_LDLT_type1.F \ + MUMPS/src/dfac_front_LDLT_type2.F \ + MUMPS/src/dfac_front_LU_type1.F \ + MUMPS/src/dfac_front_LU_type2.F \ + MUMPS/src/dfac_front_type2_aux.F \ + MUMPS/src/dfac_lastrtnelind.F \ + MUMPS/src/dfac_lr.F \ + MUMPS/src/dfac_mem_alloc_cb.F \ + MUMPS/src/dfac_mem_compress_cb.F \ + MUMPS/src/dfac_mem_dynamic.F \ + MUMPS/src/dfac_mem_free_block_cb.F \ + MUMPS/src/dfac_mem_stack_aux.F \ + MUMPS/src/dfac_mem_stack.F \ + MUMPS/src/dfac_omp_m.F \ + MUMPS/src/dfac_par_m.F \ + MUMPS/src/dfac_process_band.F \ + MUMPS/src/dfac_process_bf.F \ + MUMPS/src/dfac_process_blfac_slave.F \ + MUMPS/src/dfac_process_blocfacto.F \ + MUMPS/src/dfac_process_blocfacto_LDLT.F \ + MUMPS/src/dfac_process_contrib_type1.F \ + MUMPS/src/dfac_process_contrib_type2.F \ + MUMPS/src/dfac_process_contrib_type3.F \ + MUMPS/src/dfac_process_end_facto_slave.F \ + MUMPS/src/dfac_process_maprow.F \ + MUMPS/src/dfac_process_master2.F \ + MUMPS/src/dfac_process_message.F \ + MUMPS/src/dfac_process_root2slave.F \ + MUMPS/src/dfac_process_root2son.F \ + MUMPS/src/dfac_process_rtnelind.F \ + MUMPS/src/dfac_root_parallel.F \ + MUMPS/src/dfac_scalings.F \ + MUMPS/src/dfac_scalings_simScaleAbs.F \ + MUMPS/src/dfac_scalings_simScale_util.F \ + MUMPS/src/dfac_sispointers_m.F \ + MUMPS/src/dfac_sol_l0omp_m.F \ + MUMPS/src/dfac_sol_pool.F \ + MUMPS/src/dfac_type3_symmetrize.F \ + MUMPS/src/dini_defaults.F \ + MUMPS/src/dini_driver.F \ + MUMPS/src/dlr_core.F \ + MUMPS/src/dlr_stats.F \ + MUMPS/src/dlr_type.F \ + MUMPS/src/dmumps_comm_buffer.F \ + MUMPS/src/dmumps_config_file.F \ + MUMPS/src/dmumps_driver.F \ + MUMPS/src/dmumps_f77.F \ + MUMPS/src/dmumps_gpu.c \ + MUMPS/src/dmumps_iXamax.F \ + MUMPS/src/dmumps_load.F \ + MUMPS/src/dmumps_lr_data_m.F \ + MUMPS/src/dmumps_ooc_buffer.F \ + MUMPS/src/dmumps_ooc.F \ + MUMPS/src/dmumps_save_restore.F \ + MUMPS/src/dmumps_save_restore_files.F \ + MUMPS/src/dmumps_sol_es.F \ + MUMPS/src/dmumps_struc_def.F \ + MUMPS/src/domp_tps_m.F \ + MUMPS/src/dooc_panel_piv.F \ + MUMPS/src/drank_revealing.F \ + MUMPS/src/dsol_aux.F \ + MUMPS/src/dsol_bwd_aux.F \ + MUMPS/src/dsol_bwd.F \ + MUMPS/src/dsol_c.F \ + MUMPS/src/dsol_distrhs.F \ + MUMPS/src/dsol_driver.F \ + MUMPS/src/dsol_fwd_aux.F \ + MUMPS/src/dsol_fwd.F \ + MUMPS/src/dsol_lr.F \ + MUMPS/src/dsol_matvec.F \ + MUMPS/src/dsol_omp_m.F \ + MUMPS/src/dsol_root_parallel.F \ + MUMPS/src/dstatic_ptr_m.F \ + MUMPS/src/dtools.F \ + MUMPS/src/dtype3_root.F +endif + +if MUMPS_SINGLE +BUILT_SOURCES += smumps_c.c +libcoinmumps_la_SOURCES += \ + smumps_c.c \ + MUMPS/src/sana_aux_ELT.F \ + MUMPS/src/sana_aux.F \ + MUMPS/src/sana_aux_par.F \ + MUMPS/src/sana_dist_m.F \ + MUMPS/src/sana_driver.F \ + MUMPS/src/sana_LDLT_preprocess.F \ + MUMPS/src/sana_lr.F \ + MUMPS/src/sana_mtrans.F \ + MUMPS/src/sana_reordertree.F \ + MUMPS/src/sarrowheads.F \ + MUMPS/src/sbcast_int.F \ + MUMPS/src/send_driver.F \ + MUMPS/src/sfac_asm_ELT.F \ + MUMPS/src/sfac_asm.F \ + MUMPS/src/sfac_asm_master_ELT_m.F \ + MUMPS/src/sfac_asm_master_m.F \ + MUMPS/src/sfac_b.F \ + MUMPS/src/sfac_determinant.F \ + MUMPS/src/sfac_distrib_distentry.F \ + MUMPS/src/sfac_distrib_ELT.F \ + MUMPS/src/sfac_driver.F \ + MUMPS/src/sfac_front_aux.F \ + MUMPS/src/sfac_front_LDLT_type1.F \ + MUMPS/src/sfac_front_LDLT_type2.F \ + MUMPS/src/sfac_front_LU_type1.F \ + MUMPS/src/sfac_front_LU_type2.F \ + MUMPS/src/sfac_front_type2_aux.F \ + MUMPS/src/sfac_lastrtnelind.F \ + MUMPS/src/sfac_lr.F \ + MUMPS/src/sfac_mem_alloc_cb.F \ + MUMPS/src/sfac_mem_compress_cb.F \ + MUMPS/src/sfac_mem_dynamic.F \ + MUMPS/src/sfac_mem_free_block_cb.F \ + MUMPS/src/sfac_mem_stack_aux.F \ + MUMPS/src/sfac_mem_stack.F \ + MUMPS/src/sfac_omp_m.F \ + MUMPS/src/sfac_par_m.F \ + MUMPS/src/sfac_process_band.F \ + MUMPS/src/sfac_process_bf.F \ + MUMPS/src/sfac_process_blfac_slave.F \ + MUMPS/src/sfac_process_blocfacto.F \ + MUMPS/src/sfac_process_blocfacto_LDLT.F \ + MUMPS/src/sfac_process_contrib_type1.F \ + MUMPS/src/sfac_process_contrib_type2.F \ + MUMPS/src/sfac_process_contrib_type3.F \ + MUMPS/src/sfac_process_end_facto_slave.F \ + MUMPS/src/sfac_process_maprow.F \ + MUMPS/src/sfac_process_master2.F \ + MUMPS/src/sfac_process_message.F \ + MUMPS/src/sfac_process_root2slave.F \ + MUMPS/src/sfac_process_root2son.F \ + MUMPS/src/sfac_process_rtnelind.F \ + MUMPS/src/sfac_root_parallel.F \ + MUMPS/src/sfac_scalings.F \ + MUMPS/src/sfac_scalings_simScaleAbs.F \ + MUMPS/src/sfac_scalings_simScale_util.F \ + MUMPS/src/sfac_sispointers_m.F \ + MUMPS/src/sfac_sol_l0omp_m.F \ + MUMPS/src/sfac_sol_pool.F \ + MUMPS/src/sfac_type3_symmetrize.F \ + MUMPS/src/sini_defaults.F \ + MUMPS/src/sini_driver.F \ + MUMPS/src/slr_core.F \ + MUMPS/src/slr_stats.F \ + MUMPS/src/slr_type.F \ + MUMPS/src/smumps_comm_buffer.F \ + MUMPS/src/smumps_config_file.F \ + MUMPS/src/smumps_driver.F \ + MUMPS/src/smumps_f77.F \ + MUMPS/src/smumps_gpu.c \ + MUMPS/src/smumps_iXamax.F \ + MUMPS/src/smumps_load.F \ + MUMPS/src/smumps_lr_data_m.F \ + MUMPS/src/smumps_ooc_buffer.F \ + MUMPS/src/smumps_ooc.F \ + MUMPS/src/smumps_save_restore.F \ + MUMPS/src/smumps_save_restore_files.F \ + MUMPS/src/smumps_sol_es.F \ + MUMPS/src/smumps_struc_def.F \ + MUMPS/src/somp_tps_m.F \ + MUMPS/src/sooc_panel_piv.F \ + MUMPS/src/srank_revealing.F \ + MUMPS/src/ssol_aux.F \ + MUMPS/src/ssol_bwd_aux.F \ + MUMPS/src/ssol_bwd.F \ + MUMPS/src/ssol_c.F \ + MUMPS/src/ssol_distrhs.F \ + MUMPS/src/ssol_driver.F \ + MUMPS/src/ssol_fwd_aux.F \ + MUMPS/src/ssol_fwd.F \ + MUMPS/src/ssol_lr.F \ + MUMPS/src/ssol_matvec.F \ + MUMPS/src/ssol_omp_m.F \ + MUMPS/src/ssol_root_parallel.F \ + MUMPS/src/sstatic_ptr_m.F \ + MUMPS/src/stools.F \ + MUMPS/src/stype3_root.F +endif + +# this is to compile mumps_c.c once for each precision with different setting for MUMPS_ARITH +dmumps_c.c : $(srcdir)/MUMPS/src/mumps_c.c + echo "#define MUMPS_ARITH MUMPS_ARITH_d" > $@ + cat $< >> $@ + +smumps_c.c : $(srcdir)/MUMPS/src/mumps_c.c + echo "#define MUMPS_ARITH MUMPS_ARITH_s" > $@ + cat $< >> $@ + +libcoinmumps_la_LIBADD = $(MUMPS_LFLAGS) + +AM_CPPFLAGS = -I$(srcdir)/MUMPS/src -I$(srcdir)/MUMPS/libseq -I$(srcdir)/MUMPS/include + +AM_LDFLAGS = $(LT_LDFLAGS) + +# Dependencies between modules: +# i) arithmetic-dependent modules: +MUMPS/src/dana_aux.lo: \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/mumps_static_mapping.lo \ + MUMPS/src/ana_blk_m.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/dana_aux_par.lo: \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/mumps_memory_mod.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/dana_lr.lo: MUMPS/src/dlr_core.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/dfac_asm_master_ELT_m.lo: \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/dfac_mem_dynamic.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo +MUMPS/src/dfac_asm_master_m.lo: \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_asm_build_sort_index_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/dfac_mem_dynamic.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo +MUMPS/src/dfac_b.lo: \ + MUMPS/src/dfac_sispointers_m.lo +MUMPS/src/dfac_front_aux.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dfac_front_LU_type1.lo : \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dfac_front_LU_type2.lo : \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dfac_front_type2_aux.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dfac_front_LDLT_type1.lo : \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dfac_front_LDLT_type2.lo : \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dfac_front_type2_aux.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dfac_front_type2_aux.lo : \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/fac_ibct_data_m.lo +MUMPS/src/dfac_lr.lo: \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dlr_stats.lo +MUMPS/src/dfac_mem_dynamic.lo: \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dstatic_ptr_m.lo +MUMPS/src/dfac_omp_m.lo: \ + MUMPS/src/dfac_asm_master_m.lo \ + MUMPS/src/dfac_asm_master_ELT_m.lo \ + MUMPS/src/dfac_front_LU_type1.lo \ + MUMPS/src/dfac_front_LDLT_type1.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dfac_par_m.lo: \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dfac_asm_master_m.lo \ + MUMPS/src/dfac_asm_master_ELT_m.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dfac_front_LU_type1.lo \ + MUMPS/src/dfac_front_LU_type2.lo \ + MUMPS/src/dfac_front_LDLT_type1.lo \ + MUMPS/src/dfac_front_LDLT_type2.lo \ + MUMPS/src/dfac_mem_dynamic.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dlr_core.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/lr_common.lo +MUMPS/src/dlr_stats.lo: MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dmumps_comm_buffer.lo: \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/fac_ibct_data_m.lo +MUMPS/src/dmumps_config_file.lo: MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dmumps_load.lo: \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/fac_future_niv2_mod.lo +MUMPS/src/dmumps_lr_data_m.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/front_data_mgt_m.lo +MUMPS/src/dmumps_ooc_buffer.lo: MUMPS/src/mumps_ooc_common.lo +MUMPS/src/dmumps_ooc.lo: \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/dmumps_ooc_buffer.lo \ + MUMPS/src/mumps_ooc_common.lo +MUMPS/src/dmumps_sol_es.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_lr_data_m.lo +MUMPS/src/dmumps_save_restore.lo: \ + MUMPS/src/dfac_sol_l0omp_m.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/dmumps_save_restore_files.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/front_data_mgt_m.lo +MUMPS/src/dmumps_save_restore_files.lo : MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dsol_lr.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dmumps_lr_data_m.lo + +MUMPS/src/sana_aux.lo: \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/mumps_static_mapping.lo \ + MUMPS/src/ana_blk_m.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/sana_aux_par.lo: \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/mumps_memory_mod.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/sana_lr.lo: MUMPS/src/slr_core.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/sfac_asm_master_ELT_m.lo: \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/sfac_mem_dynamic.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo +MUMPS/src/sfac_asm_master_m.lo: \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_asm_build_sort_index_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/sfac_mem_dynamic.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo +MUMPS/src/sfac_b.lo: \ + MUMPS/src/sfac_sispointers_m.lo +MUMPS/src/sfac_front_aux.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/sfac_front_LU_type1.lo : \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/sfac_front_LU_type2.lo : \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/sfac_front_type2_aux.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_struc_def.lo +MUMPS/src/sfac_front_LDLT_type1.lo : \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/sfac_front_LDLT_type2.lo : \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/sfac_front_type2_aux.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_struc_def.lo +MUMPS/src/sfac_front_type2_aux.lo : \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/fac_ibct_data_m.lo +MUMPS/src/sfac_lr.lo: \ + MUMPS/src/slr_core.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/slr_stats.lo +MUMPS/src/sfac_mem_dynamic.lo: \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/sstatic_ptr_m.lo +MUMPS/src/sfac_omp_m.lo: \ + MUMPS/src/sfac_asm_master_m.lo \ + MUMPS/src/sfac_asm_master_ELT_m.lo \ + MUMPS/src/sfac_front_LU_type1.lo \ + MUMPS/src/sfac_front_LDLT_type1.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/sfac_par_m.lo: \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/sfac_asm_master_m.lo \ + MUMPS/src/sfac_asm_master_ELT_m.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/sfac_front_LU_type1.lo \ + MUMPS/src/sfac_front_LU_type2.lo \ + MUMPS/src/sfac_front_LDLT_type1.lo \ + MUMPS/src/sfac_front_LDLT_type2.lo \ + MUMPS/src/sfac_mem_dynamic.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/slr_core.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/lr_common.lo +MUMPS/src/slr_stats.lo: MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_struc_def.lo +MUMPS/src/smumps_comm_buffer.lo: \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/fac_ibct_data_m.lo +MUMPS/src/smumps_config_file.lo: MUMPS/src/smumps_struc_def.lo +MUMPS/src/smumps_load.lo: \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/fac_future_niv2_mod.lo +MUMPS/src/smumps_lr_data_m.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/front_data_mgt_m.lo +MUMPS/src/smumps_ooc_buffer.lo: MUMPS/src/mumps_ooc_common.lo +MUMPS/src/smumps_ooc.lo: \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/smumps_ooc_buffer.lo \ + MUMPS/src/mumps_ooc_common.lo +MUMPS/src/smumps_sol_es.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_lr_data_m.lo +MUMPS/src/smumps_save_restore.lo: \ + MUMPS/src/sfac_sol_l0omp_m.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/smumps_save_restore_files.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/front_data_mgt_m.lo +MUMPS/src/smumps_save_restore_files.lo : MUMPS/src/smumps_struc_def.lo +MUMPS/src/ssol_lr.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/smumps_lr_data_m.lo + +# Dependencies between modules: +# ii) arithmetic-independent modules: +MUMPS/src/ana_omp_m.lo: MUMPS/src/double_linked_list.lo +MUMPS/src/fac_asm_build_sort_index_ELT_m.lo: MUMPS/src/omp_tps_common_m.lo +MUMPS/src/fac_asm_build_sort_index_m.lo: MUMPS/src/omp_tps_common_m.lo +MUMPS/src/fac_descband_data_m.lo: MUMPS/src/front_data_mgt_m.lo +MUMPS/src/fac_ibct_data_m.lo: MUMPS/src/front_data_mgt_m.lo +MUMPS/src/fac_maprow_data_m.lo: MUMPS/src/front_data_mgt_m.lo +MUMPS/src/mumps_comm_ibcast.lo: MUMPS/src/fac_future_niv2_mod.lo +MUMPS/src/mumps_static_mapping.lo: MUMPS/src/lr_common.lo + +# iii) compile modules before others +OBJS_COMMON_MOD = \ + MUMPS/src/ana_blk_m.lo \ + MUMPS/src/ana_omp_m.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo \ + MUMPS/src/double_linked_list.lo \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.lo \ + MUMPS/src/fac_asm_build_sort_index_m.lo \ + MUMPS/src/fac_descband_data_m.lo \ + MUMPS/src/fac_future_niv2_mod.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_maprow_data_m.lo \ + MUMPS/src/front_data_mgt_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/mumps_l0_omp_m.lo \ + MUMPS/src/mumps_memory_mod.lo \ + MUMPS/src/mumps_mpitoomp_m.lo \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/mumps_static_mapping.lo \ + MUMPS/src/omp_tps_common_m.lo +OBJS_COMMON_OTHER = \ + MUMPS/src/ana_blk.lo \ + MUMPS/src/ana_orderings.lo \ + MUMPS/src/ana_set_ordering.lo \ + MUMPS/src/ana_AMDMF.lo \ + MUMPS/src/bcast_errors.lo \ + MUMPS/src/estim_flops.lo \ + MUMPS/src/mumps_type_size.lo \ + MUMPS/src/mumps_type2_blocking.lo \ + MUMPS/src/mumps_version.lo \ + MUMPS/src/mumps_print_defined.lo \ + MUMPS/src/mumps_common.lo \ + MUMPS/src/mumps_pord.lo \ + MUMPS/src/mumps_metis.lo \ + MUMPS/src/mumps_metis64.lo \ + MUMPS/src/mumps_metis_int.lo \ + MUMPS/src/mumps_scotch.lo \ + MUMPS/src/mumps_scotch64.lo \ + MUMPS/src/mumps_scotch_int.lo \ + MUMPS/src/mumps_size.lo \ + MUMPS/src/mumps_io.lo \ + MUMPS/src/mumps_io_basic.lo \ + MUMPS/src/mumps_io_thread.lo \ + MUMPS/src/mumps_io_err.lo \ + MUMPS/src/mumps_numa.lo \ + MUMPS/src/mumps_thread.lo \ + MUMPS/src/mumps_save_restore_C.lo \ + MUMPS/src/mumps_config_file_C.lo \ + MUMPS/src/mumps_thread_affinity.lo \ + MUMPS/src/tools_common.lo \ + MUMPS/src/sol_common.lo +DOBJS_MOD = \ + MUMPS/src/dana_aux.lo \ + MUMPS/src/dana_aux_par.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dfac_asm_master_ELT_m.lo \ + MUMPS/src/dfac_asm_master_m.lo \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dfac_front_LU_type1.lo \ + MUMPS/src/dfac_front_LU_type2.lo \ + MUMPS/src/dfac_front_LDLT_type1.lo \ + MUMPS/src/dfac_front_LDLT_type2.lo \ + MUMPS/src/dfac_front_type2_aux.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dfac_mem_dynamic.lo \ + MUMPS/src/dfac_omp_m.lo \ + MUMPS/src/dfac_par_m.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_config_file.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_ooc_buffer.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dmumps_sol_es.lo \ + MUMPS/src/dmumps_save_restore.lo \ + MUMPS/src/dmumps_save_restore_files.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dsol_lr.lo \ + MUMPS/src/dsol_omp_m.lo \ + MUMPS/src/dstatic_ptr_m.lo +DOBJS_OTHER = \ + MUMPS/src/dini_driver.lo \ + MUMPS/src/dana_driver.lo \ + MUMPS/src/dfac_driver.lo \ + MUMPS/src/dsol_driver.lo \ + MUMPS/src/dsol_distrhs.lo \ + MUMPS/src/dend_driver.lo \ + MUMPS/src/dana_aux_ELT.lo \ + MUMPS/src/dana_dist_m.lo \ + MUMPS/src/dana_LDLT_preprocess.lo \ + MUMPS/src/dana_reordertree.lo \ + MUMPS/src/darrowheads.lo \ + MUMPS/src/dbcast_int.lo \ + MUMPS/src/dfac_asm_ELT.lo \ + MUMPS/src/dfac_asm.lo \ + MUMPS/src/dfac_b.lo \ + MUMPS/src/dfac_distrib_distentry.lo \ + MUMPS/src/dfac_distrib_ELT.lo \ + MUMPS/src/dfac_lastrtnelind.lo \ + MUMPS/src/dfac_mem_alloc_cb.lo \ + MUMPS/src/dfac_mem_compress_cb.lo \ + MUMPS/src/dfac_mem_free_block_cb.lo \ + MUMPS/src/dfac_mem_stack_aux.lo \ + MUMPS/src/dfac_mem_stack.lo \ + MUMPS/src/dfac_process_band.lo \ + MUMPS/src/dfac_process_blfac_slave.lo \ + MUMPS/src/dfac_process_blocfacto_LDLT.lo \ + MUMPS/src/dfac_process_blocfacto.lo \ + MUMPS/src/dfac_process_bf.lo \ + MUMPS/src/dfac_process_end_facto_slave.lo \ + MUMPS/src/dfac_process_contrib_type1.lo \ + MUMPS/src/dfac_process_contrib_type2.lo \ + MUMPS/src/dfac_process_contrib_type3.lo \ + MUMPS/src/dfac_process_maprow.lo \ + MUMPS/src/dfac_process_master2.lo \ + MUMPS/src/dfac_process_message.lo \ + MUMPS/src/dfac_process_root2slave.lo \ + MUMPS/src/dfac_process_root2son.lo \ + MUMPS/src/dfac_process_rtnelind.lo \ + MUMPS/src/dfac_root_parallel.lo \ + MUMPS/src/dfac_scalings.lo \ + MUMPS/src/dfac_determinant.lo \ + MUMPS/src/dfac_scalings_simScaleAbs.lo \ + MUMPS/src/dfac_scalings_simScale_util.lo \ + MUMPS/src/dfac_sol_pool.lo \ + MUMPS/src/dfac_type3_symmetrize.lo \ + MUMPS/src/dini_defaults.lo \ + MUMPS/src/dmumps_c.lo \ + MUMPS/src/dmumps_driver.lo \ + MUMPS/src/dmumps_f77.lo \ + MUMPS/src/dmumps_gpu.lo \ + MUMPS/src/dmumps_iXamax.lo \ + MUMPS/src/dana_mtrans.lo \ + MUMPS/src/dooc_panel_piv.lo \ + MUMPS/src/drank_revealing.lo \ + MUMPS/src/dsol_aux.lo \ + MUMPS/src/dsol_bwd_aux.lo \ + MUMPS/src/dsol_bwd.lo \ + MUMPS/src/dsol_c.lo \ + MUMPS/src/dsol_fwd_aux.lo \ + MUMPS/src/dsol_fwd.lo \ + MUMPS/src/dsol_matvec.lo \ + MUMPS/src/dsol_root_parallel.lo \ + MUMPS/src/dtools.lo \ + MUMPS/src/dtype3_root.lo +SOBJS_MOD = \ + MUMPS/src/sana_aux.lo \ + MUMPS/src/sana_aux_par.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/sfac_asm_master_ELT_m.lo \ + MUMPS/src/sfac_asm_master_m.lo \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/sfac_front_LU_type1.lo \ + MUMPS/src/sfac_front_LU_type2.lo \ + MUMPS/src/sfac_front_LDLT_type1.lo \ + MUMPS/src/sfac_front_LDLT_type2.lo \ + MUMPS/src/sfac_front_type2_aux.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/sfac_mem_dynamic.lo \ + MUMPS/src/sfac_omp_m.lo \ + MUMPS/src/sfac_par_m.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_config_file.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_ooc_buffer.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/smumps_sol_es.lo \ + MUMPS/src/smumps_save_restore.lo \ + MUMPS/src/smumps_save_restore_files.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/ssol_lr.lo \ + MUMPS/src/ssol_omp_m.lo \ + MUMPS/src/sstatic_ptr_m.lo +SOBJS_OTHER = \ + MUMPS/src/sini_driver.lo \ + MUMPS/src/sana_driver.lo \ + MUMPS/src/sfac_driver.lo \ + MUMPS/src/ssol_driver.lo \ + MUMPS/src/ssol_distrhs.lo \ + MUMPS/src/send_driver.lo \ + MUMPS/src/sana_aux_ELT.lo \ + MUMPS/src/sana_dist_m.lo \ + MUMPS/src/sana_LDLT_preprocess.lo \ + MUMPS/src/sana_reordertree.lo \ + MUMPS/src/sarrowheads.lo \ + MUMPS/src/sbcast_int.lo \ + MUMPS/src/sfac_asm_ELT.lo \ + MUMPS/src/sfac_asm.lo \ + MUMPS/src/sfac_b.lo \ + MUMPS/src/sfac_distrib_distentry.lo \ + MUMPS/src/sfac_distrib_ELT.lo \ + MUMPS/src/sfac_lastrtnelind.lo \ + MUMPS/src/sfac_mem_alloc_cb.lo \ + MUMPS/src/sfac_mem_compress_cb.lo \ + MUMPS/src/sfac_mem_free_block_cb.lo \ + MUMPS/src/sfac_mem_stack_aux.lo \ + MUMPS/src/sfac_mem_stack.lo \ + MUMPS/src/sfac_process_band.lo \ + MUMPS/src/sfac_process_blfac_slave.lo \ + MUMPS/src/sfac_process_blocfacto_LDLT.lo \ + MUMPS/src/sfac_process_blocfacto.lo \ + MUMPS/src/sfac_process_bf.lo \ + MUMPS/src/sfac_process_end_facto_slave.lo \ + MUMPS/src/sfac_process_contrib_type1.lo \ + MUMPS/src/sfac_process_contrib_type2.lo \ + MUMPS/src/sfac_process_contrib_type3.lo \ + MUMPS/src/sfac_process_maprow.lo \ + MUMPS/src/sfac_process_master2.lo \ + MUMPS/src/sfac_process_message.lo \ + MUMPS/src/sfac_process_root2slave.lo \ + MUMPS/src/sfac_process_root2son.lo \ + MUMPS/src/sfac_process_rtnelind.lo \ + MUMPS/src/sfac_root_parallel.lo \ + MUMPS/src/sfac_scalings.lo \ + MUMPS/src/sfac_determinant.lo \ + MUMPS/src/sfac_scalings_simScaleAbs.lo \ + MUMPS/src/sfac_scalings_simScale_util.lo \ + MUMPS/src/sfac_sol_pool.lo \ + MUMPS/src/sfac_type3_symmetrize.lo \ + MUMPS/src/sini_defaults.lo \ + MUMPS/src/smumps_c.lo \ + MUMPS/src/smumps_driver.lo \ + MUMPS/src/smumps_f77.lo \ + MUMPS/src/smumps_gpu.lo \ + MUMPS/src/smumps_iXamax.lo \ + MUMPS/src/sana_mtrans.lo \ + MUMPS/src/sooc_panel_piv.lo \ + MUMPS/src/srank_revealing.lo \ + MUMPS/src/ssol_aux.lo \ + MUMPS/src/ssol_bwd_aux.lo \ + MUMPS/src/ssol_bwd.lo \ + MUMPS/src/ssol_c.lo \ + MUMPS/src/ssol_fwd_aux.lo \ + MUMPS/src/ssol_fwd.lo \ + MUMPS/src/ssol_matvec.lo \ + MUMPS/src/ssol_root_parallel.lo \ + MUMPS/src/stools.lo \ + MUMPS/src/stype3_root.lo + +$(OBJS_COMMON_OTHER) : $(OBJS_COMMON_MOD) +if MUMPS_DOUBLE +$(DOBJS_OTHER) : $(OBJS_COMMON_MOD) $(DOBJS_MOD) +endif +if MUMPS_SINGLE +$(SOBJS_OTHER) : $(OBJS_COMMON_MOD) $(SOBJS_MOD) +endif + +# Module files that need to be deleted +CLEANFILES = *.mod + +AM_CFLAGS = $(MY_DEFS) $(MUMPS_CFLAGS) +FCFLAGS += $(MY_FDEFS) + +# automake thinks that the .F files are F77, not F95, and requires F77 to be set +# set it to FC, and same for FFLAGS +F77 = $(FC) +FFLAGS = $(FCFLAGS) + +thirdpartyincludedir = $(includedir)/coin-or/mumps +thirdpartyinclude_HEADERS = \ + MUMPS/include/mumps_c_types.h \ + MUMPS/libseq/mumps_mpi.h \ + mumps_compat.h \ + mumps_int_def.h + +if MUMPS_DOUBLE +thirdpartyinclude_HEADERS += MUMPS/include/dmumps_c.h +endif +if MUMPS_SINGLE +thirdpartyinclude_HEADERS += MUMPS/include/smumps_c.h +endif + +pkgconfiglibdir = $(libdir)/pkgconfig +pkgconfiglib_DATA = coinmumps.pc + +test: + @echo "No test available for Mumps." diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/Makefile.in b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/Makefile.in new file mode 100644 index 0000000..6c14340 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/Makefile.in @@ -0,0 +1,2521 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright (C) 2007-2010 International Business Machines and others. +# All Rights Reserved. +# This file is distributed under the Eclipse Public License. + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@MUMPS_DOUBLE_TRUE@am__append_1 = dmumps_c.c +@MUMPS_DOUBLE_TRUE@am__append_2 = \ +@MUMPS_DOUBLE_TRUE@ dmumps_c.c \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_aux_ELT.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_aux.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_aux_par.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_dist_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_driver.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_LDLT_preprocess.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_lr.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_mtrans.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_reordertree.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/darrowheads.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dbcast_int.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dend_driver.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_asm_ELT.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_asm.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_asm_master_ELT_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_asm_master_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_b.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_determinant.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_distrib_distentry.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_distrib_ELT.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_driver.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_aux.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_LDLT_type1.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_LDLT_type2.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_LU_type1.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_LU_type2.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_type2_aux.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_lastrtnelind.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_lr.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_alloc_cb.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_compress_cb.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_dynamic.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_free_block_cb.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_stack_aux.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_stack.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_omp_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_par_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_band.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_bf.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_blfac_slave.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_blocfacto.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_blocfacto_LDLT.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_contrib_type1.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_contrib_type2.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_contrib_type3.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_end_facto_slave.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_maprow.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_master2.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_message.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_root2slave.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_root2son.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_rtnelind.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_root_parallel.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_scalings.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_scalings_simScaleAbs.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_scalings_simScale_util.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_sispointers_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_sol_l0omp_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_sol_pool.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_type3_symmetrize.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dini_defaults.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dini_driver.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dlr_core.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dlr_stats.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dlr_type.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_comm_buffer.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_config_file.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_driver.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_f77.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_gpu.c \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_iXamax.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_load.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_lr_data_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_ooc_buffer.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_ooc.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_save_restore.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_save_restore_files.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_sol_es.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_struc_def.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/domp_tps_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dooc_panel_piv.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/drank_revealing.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_aux.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_bwd_aux.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_bwd.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_c.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_distrhs.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_driver.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_fwd_aux.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_fwd.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_lr.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_matvec.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_omp_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_root_parallel.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dstatic_ptr_m.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dtools.F \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dtype3_root.F + +@MUMPS_SINGLE_TRUE@am__append_3 = smumps_c.c +@MUMPS_SINGLE_TRUE@am__append_4 = \ +@MUMPS_SINGLE_TRUE@ smumps_c.c \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_aux_ELT.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_aux.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_aux_par.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_dist_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_driver.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_LDLT_preprocess.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_lr.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_mtrans.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_reordertree.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sarrowheads.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sbcast_int.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/send_driver.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_asm_ELT.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_asm.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_asm_master_ELT_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_asm_master_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_b.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_determinant.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_distrib_distentry.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_distrib_ELT.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_driver.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_aux.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_LDLT_type1.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_LDLT_type2.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_LU_type1.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_LU_type2.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_type2_aux.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_lastrtnelind.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_lr.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_alloc_cb.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_compress_cb.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_dynamic.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_free_block_cb.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_stack_aux.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_stack.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_omp_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_par_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_band.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_bf.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_blfac_slave.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_blocfacto.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_blocfacto_LDLT.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_contrib_type1.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_contrib_type2.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_contrib_type3.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_end_facto_slave.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_maprow.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_master2.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_message.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_root2slave.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_root2son.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_rtnelind.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_root_parallel.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_scalings.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_scalings_simScaleAbs.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_scalings_simScale_util.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_sispointers_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_sol_l0omp_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_sol_pool.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_type3_symmetrize.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sini_defaults.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sini_driver.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/slr_core.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/slr_stats.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/slr_type.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_comm_buffer.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_config_file.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_driver.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_f77.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_gpu.c \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_iXamax.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_load.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_lr_data_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_ooc_buffer.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_ooc.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_save_restore.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_save_restore_files.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_sol_es.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_struc_def.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/somp_tps_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sooc_panel_piv.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/srank_revealing.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_aux.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_bwd_aux.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_bwd.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_c.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_distrhs.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_driver.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_fwd_aux.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_fwd.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_lr.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_matvec.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_omp_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_root_parallel.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sstatic_ptr_m.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/stools.F \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/stype3_root.F + +@MUMPS_DOUBLE_TRUE@am__append_5 = MUMPS/include/dmumps_c.h +@MUMPS_SINGLE_TRUE@am__append_6 = MUMPS/include/smumps_c.h +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__thirdpartyinclude_HEADERS_DIST) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h mumps_compat.h mumps_int_def.h +CONFIG_CLEAN_FILES = coinmumps.pc +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfiglibdir)" \ + "$(DESTDIR)$(thirdpartyincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libcoinmumps_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__dirstamp = $(am__leading_dot)dirstamp +@MUMPS_DOUBLE_TRUE@am__objects_1 = dmumps_c.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_aux_ELT.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_aux.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_aux_par.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_dist_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_driver.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_LDLT_preprocess.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_lr.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_mtrans.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dana_reordertree.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/darrowheads.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dbcast_int.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dend_driver.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_asm_ELT.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_asm.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_asm_master_ELT_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_asm_master_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_b.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_determinant.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_distrib_distentry.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_distrib_ELT.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_driver.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_aux.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_LDLT_type1.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_LDLT_type2.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_LU_type1.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_LU_type2.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_front_type2_aux.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_lastrtnelind.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_lr.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_alloc_cb.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_compress_cb.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_dynamic.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_free_block_cb.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_stack_aux.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_mem_stack.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_omp_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_par_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_band.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_bf.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_blfac_slave.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_blocfacto.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_blocfacto_LDLT.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_contrib_type1.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_contrib_type2.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_contrib_type3.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_end_facto_slave.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_maprow.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_master2.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_message.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_root2slave.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_root2son.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_process_rtnelind.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_root_parallel.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_scalings.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_scalings_simScaleAbs.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_scalings_simScale_util.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_sispointers_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_sol_l0omp_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_sol_pool.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dfac_type3_symmetrize.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dini_defaults.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dini_driver.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dlr_core.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dlr_stats.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dlr_type.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_comm_buffer.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_config_file.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_driver.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_f77.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_gpu.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_iXamax.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_load.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_lr_data_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_ooc_buffer.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_ooc.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_save_restore.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_save_restore_files.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_sol_es.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dmumps_struc_def.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/domp_tps_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dooc_panel_piv.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/drank_revealing.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_aux.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_bwd_aux.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_bwd.lo MUMPS/src/dsol_c.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_distrhs.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_driver.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_fwd_aux.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_fwd.lo MUMPS/src/dsol_lr.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_matvec.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_omp_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dsol_root_parallel.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dstatic_ptr_m.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dtools.lo \ +@MUMPS_DOUBLE_TRUE@ MUMPS/src/dtype3_root.lo +@MUMPS_SINGLE_TRUE@am__objects_2 = smumps_c.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_aux_ELT.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_aux.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_aux_par.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_dist_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_driver.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_LDLT_preprocess.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_lr.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_mtrans.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sana_reordertree.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sarrowheads.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sbcast_int.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/send_driver.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_asm_ELT.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_asm.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_asm_master_ELT_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_asm_master_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_b.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_determinant.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_distrib_distentry.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_distrib_ELT.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_driver.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_aux.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_LDLT_type1.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_LDLT_type2.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_LU_type1.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_LU_type2.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_front_type2_aux.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_lastrtnelind.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_lr.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_alloc_cb.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_compress_cb.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_dynamic.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_free_block_cb.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_stack_aux.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_mem_stack.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_omp_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_par_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_band.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_bf.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_blfac_slave.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_blocfacto.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_blocfacto_LDLT.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_contrib_type1.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_contrib_type2.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_contrib_type3.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_end_facto_slave.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_maprow.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_master2.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_message.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_root2slave.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_root2son.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_process_rtnelind.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_root_parallel.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_scalings.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_scalings_simScaleAbs.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_scalings_simScale_util.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_sispointers_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_sol_l0omp_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_sol_pool.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sfac_type3_symmetrize.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sini_defaults.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sini_driver.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/slr_core.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/slr_stats.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/slr_type.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_comm_buffer.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_config_file.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_driver.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_f77.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_gpu.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_iXamax.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_load.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_lr_data_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_ooc_buffer.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_ooc.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_save_restore.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_save_restore_files.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_sol_es.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/smumps_struc_def.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/somp_tps_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sooc_panel_piv.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/srank_revealing.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_aux.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_bwd_aux.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_bwd.lo MUMPS/src/ssol_c.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_distrhs.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_driver.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_fwd_aux.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_fwd.lo MUMPS/src/ssol_lr.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_matvec.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_omp_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/ssol_root_parallel.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/sstatic_ptr_m.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/stools.lo \ +@MUMPS_SINGLE_TRUE@ MUMPS/src/stype3_root.lo +am_libcoinmumps_la_OBJECTS = MUMPS/src/ana_AMDMF.lo \ + MUMPS/src/ana_blk.lo MUMPS/src/ana_blk_m.lo \ + MUMPS/src/ana_omp_m.lo MUMPS/src/ana_orderings.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo \ + MUMPS/src/ana_set_ordering.lo MUMPS/src/bcast_errors.lo \ + MUMPS/src/double_linked_list.lo MUMPS/src/estim_flops.lo \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.lo \ + MUMPS/src/fac_asm_build_sort_index_m.lo \ + MUMPS/src/fac_descband_data_m.lo \ + MUMPS/src/fac_future_niv2_mod.lo MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_maprow_data_m.lo MUMPS/src/front_data_mgt_m.lo \ + MUMPS/src/lr_common.lo MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/mumps_common.lo MUMPS/src/mumps_config_file_C.lo \ + MUMPS/src/mumps_io_basic.lo MUMPS/src/mumps_io.lo \ + MUMPS/src/mumps_io_err.lo MUMPS/src/mumps_io_thread.lo \ + MUMPS/src/mumps_l0_omp_m.lo MUMPS/src/mumps_memory_mod.lo \ + MUMPS/src/mumps_metis64.lo MUMPS/src/mumps_metis.lo \ + MUMPS/src/mumps_metis_int.lo MUMPS/src/mumps_mpitoomp_m.lo \ + MUMPS/src/mumps_numa.lo MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/mumps_pord.lo MUMPS/src/mumps_print_defined.lo \ + MUMPS/src/mumps_save_restore_C.lo MUMPS/src/mumps_scotch64.lo \ + MUMPS/src/mumps_scotch.lo MUMPS/src/mumps_scotch_int.lo \ + MUMPS/src/mumps_size.lo MUMPS/src/mumps_static_mapping.lo \ + MUMPS/src/mumps_thread_affinity.lo \ + MUMPS/src/mumps_register_thread.lo MUMPS/src/mumps_thread.lo \ + MUMPS/src/mumps_type2_blocking.lo MUMPS/src/mumps_type_size.lo \ + MUMPS/src/mumps_version.lo MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/sol_common.lo MUMPS/src/tools_common.lo \ + MUMPS/libseq/mpi.lo MUMPS/libseq/mpic.lo \ + MUMPS/libseq/elapse.lo $(am__objects_1) $(am__objects_2) +libcoinmumps_la_OBJECTS = $(am_libcoinmumps_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/dmumps_c.Plo \ + ./$(DEPDIR)/smumps_c.Plo MUMPS/libseq/$(DEPDIR)/elapse.Plo \ + MUMPS/libseq/$(DEPDIR)/mpic.Plo \ + MUMPS/src/$(DEPDIR)/dmumps_gpu.Plo \ + MUMPS/src/$(DEPDIR)/mumps_common.Plo \ + MUMPS/src/$(DEPDIR)/mumps_config_file_C.Plo \ + MUMPS/src/$(DEPDIR)/mumps_io.Plo \ + MUMPS/src/$(DEPDIR)/mumps_io_basic.Plo \ + MUMPS/src/$(DEPDIR)/mumps_io_err.Plo \ + MUMPS/src/$(DEPDIR)/mumps_io_thread.Plo \ + MUMPS/src/$(DEPDIR)/mumps_metis.Plo \ + MUMPS/src/$(DEPDIR)/mumps_metis64.Plo \ + MUMPS/src/$(DEPDIR)/mumps_metis_int.Plo \ + MUMPS/src/$(DEPDIR)/mumps_numa.Plo \ + MUMPS/src/$(DEPDIR)/mumps_pord.Plo \ + MUMPS/src/$(DEPDIR)/mumps_register_thread.Plo \ + MUMPS/src/$(DEPDIR)/mumps_save_restore_C.Plo \ + MUMPS/src/$(DEPDIR)/mumps_scotch.Plo \ + MUMPS/src/$(DEPDIR)/mumps_scotch64.Plo \ + MUMPS/src/$(DEPDIR)/mumps_scotch_int.Plo \ + MUMPS/src/$(DEPDIR)/mumps_size.Plo \ + MUMPS/src/$(DEPDIR)/mumps_thread.Plo \ + MUMPS/src/$(DEPDIR)/mumps_thread_affinity.Plo \ + MUMPS/src/$(DEPDIR)/smumps_gpu.Plo +am__mv = mv -f +PPF77COMPILE = $(F77) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_FFLAGS) $(FFLAGS) +LTPPF77COMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(F77) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_FFLAGS) $(FFLAGS) +AM_V_PPF77 = $(am__v_PPF77_@AM_V@) +am__v_PPF77_ = $(am__v_PPF77_@AM_DEFAULT_V@) +am__v_PPF77_0 = @echo " PPF77 " $@; +am__v_PPF77_1 = +F77LD = $(F77) +F77LINK = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(F77LD) $(AM_FFLAGS) $(FFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_F77LD = $(am__v_F77LD_@AM_V@) +am__v_F77LD_ = $(am__v_F77LD_@AM_DEFAULT_V@) +am__v_F77LD_0 = @echo " F77LD " $@; +am__v_F77LD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +F77COMPILE = $(F77) $(AM_FFLAGS) $(FFLAGS) +LTF77COMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) +AM_V_F77 = $(am__v_F77_@AM_V@) +am__v_F77_ = $(am__v_F77_@AM_DEFAULT_V@) +am__v_F77_0 = @echo " F77 " $@; +am__v_F77_1 = +SOURCES = $(libcoinmumps_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(pkgconfiglib_DATA) +am__thirdpartyinclude_HEADERS_DIST = MUMPS/include/mumps_c_types.h \ + MUMPS/libseq/mumps_mpi.h mumps_compat.h mumps_int_def.h \ + MUMPS/include/dmumps_c.h MUMPS/include/smumps_c.h +HEADERS = $(thirdpartyinclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config.h.in mumps_compat.h.in mumps_int_def.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope +ACLOCAL = @ACLOCAL@ +ADD_CFLAGS = @ADD_CFLAGS@ +ADD_FCFLAGS = @ADD_FCFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COIN_PKG_CONFIG_PATH = @COIN_PKG_CONFIG_PATH@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FC = @FC@ +FCFLAGS = @FCFLAGS@ $(MY_FDEFS) +FCLIBS = @FCLIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_LDFLAGS = @LT_LDFLAGS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +METISCHECK_LFLAGS = @METISCHECK_LFLAGS@ +MKDIR_P = @MKDIR_P@ +MUMPS_CFLAGS = @MUMPS_CFLAGS@ +MUMPS_CFLAGS_NOPC = @MUMPS_CFLAGS_NOPC@ +MUMPS_LFLAGS = @MUMPS_LFLAGS@ +MUMPS_LFLAGS_NOPC = @MUMPS_LFLAGS_NOPC@ +MUMPS_PCFILES = @MUMPS_PCFILES@ +MY_DEFS = @MY_DEFS@ +MY_FDEFS = @MY_FDEFS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENMP_FCFLAGS = @OPENMP_FCFLAGS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_FC = @ac_ct_FC@ +ac_ct_PKG_CONFIG = @ac_ct_PKG_CONFIG@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +lib_LTLIBRARIES = libcoinmumps.la +BUILT_SOURCES = $(am__append_1) $(am__append_3) +libcoinmumps_la_SOURCES = MUMPS/src/ana_AMDMF.F MUMPS/src/ana_blk.F \ + MUMPS/src/ana_blk_m.F MUMPS/src/ana_omp_m.F \ + MUMPS/src/ana_orderings.F MUMPS/src/ana_orderings_wrappers_m.F \ + MUMPS/src/ana_set_ordering.F MUMPS/src/bcast_errors.F \ + MUMPS/src/double_linked_list.F MUMPS/src/estim_flops.F \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.F \ + MUMPS/src/fac_asm_build_sort_index_m.F \ + MUMPS/src/fac_descband_data_m.F \ + MUMPS/src/fac_future_niv2_mod.F MUMPS/src/fac_ibct_data_m.F \ + MUMPS/src/fac_maprow_data_m.F MUMPS/src/front_data_mgt_m.F \ + MUMPS/src/lr_common.F MUMPS/src/mumps_comm_ibcast.F \ + MUMPS/src/mumps_common.c MUMPS/src/mumps_config_file_C.c \ + MUMPS/src/mumps_io_basic.c MUMPS/src/mumps_io.c \ + MUMPS/src/mumps_io_err.c MUMPS/src/mumps_io_thread.c \ + MUMPS/src/mumps_l0_omp_m.F MUMPS/src/mumps_memory_mod.F \ + MUMPS/src/mumps_metis64.c MUMPS/src/mumps_metis.c \ + MUMPS/src/mumps_metis_int.c MUMPS/src/mumps_mpitoomp_m.F \ + MUMPS/src/mumps_numa.c MUMPS/src/mumps_ooc_common.F \ + MUMPS/src/mumps_pord.c MUMPS/src/mumps_print_defined.F \ + MUMPS/src/mumps_save_restore_C.c MUMPS/src/mumps_scotch64.c \ + MUMPS/src/mumps_scotch.c MUMPS/src/mumps_scotch_int.c \ + MUMPS/src/mumps_size.c MUMPS/src/mumps_static_mapping.F \ + MUMPS/src/mumps_thread_affinity.c \ + MUMPS/src/mumps_register_thread.c MUMPS/src/mumps_thread.c \ + MUMPS/src/mumps_type2_blocking.F MUMPS/src/mumps_type_size.F \ + MUMPS/src/mumps_version.F MUMPS/src/omp_tps_common_m.F \ + MUMPS/src/sol_common.F MUMPS/src/tools_common.F \ + MUMPS/libseq/mpi.f MUMPS/libseq/mpic.c MUMPS/libseq/elapse.c \ + $(am__append_2) $(am__append_4) +libcoinmumps_la_LIBADD = $(MUMPS_LFLAGS) +AM_CPPFLAGS = -I$(srcdir)/MUMPS/src -I$(srcdir)/MUMPS/libseq -I$(srcdir)/MUMPS/include +AM_LDFLAGS = $(LT_LDFLAGS) + +# iii) compile modules before others +OBJS_COMMON_MOD = \ + MUMPS/src/ana_blk_m.lo \ + MUMPS/src/ana_omp_m.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo \ + MUMPS/src/double_linked_list.lo \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.lo \ + MUMPS/src/fac_asm_build_sort_index_m.lo \ + MUMPS/src/fac_descband_data_m.lo \ + MUMPS/src/fac_future_niv2_mod.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_maprow_data_m.lo \ + MUMPS/src/front_data_mgt_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/mumps_l0_omp_m.lo \ + MUMPS/src/mumps_memory_mod.lo \ + MUMPS/src/mumps_mpitoomp_m.lo \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/mumps_static_mapping.lo \ + MUMPS/src/omp_tps_common_m.lo + +OBJS_COMMON_OTHER = \ + MUMPS/src/ana_blk.lo \ + MUMPS/src/ana_orderings.lo \ + MUMPS/src/ana_set_ordering.lo \ + MUMPS/src/ana_AMDMF.lo \ + MUMPS/src/bcast_errors.lo \ + MUMPS/src/estim_flops.lo \ + MUMPS/src/mumps_type_size.lo \ + MUMPS/src/mumps_type2_blocking.lo \ + MUMPS/src/mumps_version.lo \ + MUMPS/src/mumps_print_defined.lo \ + MUMPS/src/mumps_common.lo \ + MUMPS/src/mumps_pord.lo \ + MUMPS/src/mumps_metis.lo \ + MUMPS/src/mumps_metis64.lo \ + MUMPS/src/mumps_metis_int.lo \ + MUMPS/src/mumps_scotch.lo \ + MUMPS/src/mumps_scotch64.lo \ + MUMPS/src/mumps_scotch_int.lo \ + MUMPS/src/mumps_size.lo \ + MUMPS/src/mumps_io.lo \ + MUMPS/src/mumps_io_basic.lo \ + MUMPS/src/mumps_io_thread.lo \ + MUMPS/src/mumps_io_err.lo \ + MUMPS/src/mumps_numa.lo \ + MUMPS/src/mumps_thread.lo \ + MUMPS/src/mumps_save_restore_C.lo \ + MUMPS/src/mumps_config_file_C.lo \ + MUMPS/src/mumps_thread_affinity.lo \ + MUMPS/src/tools_common.lo \ + MUMPS/src/sol_common.lo + +DOBJS_MOD = \ + MUMPS/src/dana_aux.lo \ + MUMPS/src/dana_aux_par.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dfac_asm_master_ELT_m.lo \ + MUMPS/src/dfac_asm_master_m.lo \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dfac_front_LU_type1.lo \ + MUMPS/src/dfac_front_LU_type2.lo \ + MUMPS/src/dfac_front_LDLT_type1.lo \ + MUMPS/src/dfac_front_LDLT_type2.lo \ + MUMPS/src/dfac_front_type2_aux.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dfac_mem_dynamic.lo \ + MUMPS/src/dfac_omp_m.lo \ + MUMPS/src/dfac_par_m.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_config_file.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_ooc_buffer.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dmumps_sol_es.lo \ + MUMPS/src/dmumps_save_restore.lo \ + MUMPS/src/dmumps_save_restore_files.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dsol_lr.lo \ + MUMPS/src/dsol_omp_m.lo \ + MUMPS/src/dstatic_ptr_m.lo + +DOBJS_OTHER = \ + MUMPS/src/dini_driver.lo \ + MUMPS/src/dana_driver.lo \ + MUMPS/src/dfac_driver.lo \ + MUMPS/src/dsol_driver.lo \ + MUMPS/src/dsol_distrhs.lo \ + MUMPS/src/dend_driver.lo \ + MUMPS/src/dana_aux_ELT.lo \ + MUMPS/src/dana_dist_m.lo \ + MUMPS/src/dana_LDLT_preprocess.lo \ + MUMPS/src/dana_reordertree.lo \ + MUMPS/src/darrowheads.lo \ + MUMPS/src/dbcast_int.lo \ + MUMPS/src/dfac_asm_ELT.lo \ + MUMPS/src/dfac_asm.lo \ + MUMPS/src/dfac_b.lo \ + MUMPS/src/dfac_distrib_distentry.lo \ + MUMPS/src/dfac_distrib_ELT.lo \ + MUMPS/src/dfac_lastrtnelind.lo \ + MUMPS/src/dfac_mem_alloc_cb.lo \ + MUMPS/src/dfac_mem_compress_cb.lo \ + MUMPS/src/dfac_mem_free_block_cb.lo \ + MUMPS/src/dfac_mem_stack_aux.lo \ + MUMPS/src/dfac_mem_stack.lo \ + MUMPS/src/dfac_process_band.lo \ + MUMPS/src/dfac_process_blfac_slave.lo \ + MUMPS/src/dfac_process_blocfacto_LDLT.lo \ + MUMPS/src/dfac_process_blocfacto.lo \ + MUMPS/src/dfac_process_bf.lo \ + MUMPS/src/dfac_process_end_facto_slave.lo \ + MUMPS/src/dfac_process_contrib_type1.lo \ + MUMPS/src/dfac_process_contrib_type2.lo \ + MUMPS/src/dfac_process_contrib_type3.lo \ + MUMPS/src/dfac_process_maprow.lo \ + MUMPS/src/dfac_process_master2.lo \ + MUMPS/src/dfac_process_message.lo \ + MUMPS/src/dfac_process_root2slave.lo \ + MUMPS/src/dfac_process_root2son.lo \ + MUMPS/src/dfac_process_rtnelind.lo \ + MUMPS/src/dfac_root_parallel.lo \ + MUMPS/src/dfac_scalings.lo \ + MUMPS/src/dfac_determinant.lo \ + MUMPS/src/dfac_scalings_simScaleAbs.lo \ + MUMPS/src/dfac_scalings_simScale_util.lo \ + MUMPS/src/dfac_sol_pool.lo \ + MUMPS/src/dfac_type3_symmetrize.lo \ + MUMPS/src/dini_defaults.lo \ + MUMPS/src/dmumps_c.lo \ + MUMPS/src/dmumps_driver.lo \ + MUMPS/src/dmumps_f77.lo \ + MUMPS/src/dmumps_gpu.lo \ + MUMPS/src/dmumps_iXamax.lo \ + MUMPS/src/dana_mtrans.lo \ + MUMPS/src/dooc_panel_piv.lo \ + MUMPS/src/drank_revealing.lo \ + MUMPS/src/dsol_aux.lo \ + MUMPS/src/dsol_bwd_aux.lo \ + MUMPS/src/dsol_bwd.lo \ + MUMPS/src/dsol_c.lo \ + MUMPS/src/dsol_fwd_aux.lo \ + MUMPS/src/dsol_fwd.lo \ + MUMPS/src/dsol_matvec.lo \ + MUMPS/src/dsol_root_parallel.lo \ + MUMPS/src/dtools.lo \ + MUMPS/src/dtype3_root.lo + +SOBJS_MOD = \ + MUMPS/src/sana_aux.lo \ + MUMPS/src/sana_aux_par.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/sfac_asm_master_ELT_m.lo \ + MUMPS/src/sfac_asm_master_m.lo \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/sfac_front_LU_type1.lo \ + MUMPS/src/sfac_front_LU_type2.lo \ + MUMPS/src/sfac_front_LDLT_type1.lo \ + MUMPS/src/sfac_front_LDLT_type2.lo \ + MUMPS/src/sfac_front_type2_aux.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/sfac_mem_dynamic.lo \ + MUMPS/src/sfac_omp_m.lo \ + MUMPS/src/sfac_par_m.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_config_file.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_ooc_buffer.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/smumps_sol_es.lo \ + MUMPS/src/smumps_save_restore.lo \ + MUMPS/src/smumps_save_restore_files.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/ssol_lr.lo \ + MUMPS/src/ssol_omp_m.lo \ + MUMPS/src/sstatic_ptr_m.lo + +SOBJS_OTHER = \ + MUMPS/src/sini_driver.lo \ + MUMPS/src/sana_driver.lo \ + MUMPS/src/sfac_driver.lo \ + MUMPS/src/ssol_driver.lo \ + MUMPS/src/ssol_distrhs.lo \ + MUMPS/src/send_driver.lo \ + MUMPS/src/sana_aux_ELT.lo \ + MUMPS/src/sana_dist_m.lo \ + MUMPS/src/sana_LDLT_preprocess.lo \ + MUMPS/src/sana_reordertree.lo \ + MUMPS/src/sarrowheads.lo \ + MUMPS/src/sbcast_int.lo \ + MUMPS/src/sfac_asm_ELT.lo \ + MUMPS/src/sfac_asm.lo \ + MUMPS/src/sfac_b.lo \ + MUMPS/src/sfac_distrib_distentry.lo \ + MUMPS/src/sfac_distrib_ELT.lo \ + MUMPS/src/sfac_lastrtnelind.lo \ + MUMPS/src/sfac_mem_alloc_cb.lo \ + MUMPS/src/sfac_mem_compress_cb.lo \ + MUMPS/src/sfac_mem_free_block_cb.lo \ + MUMPS/src/sfac_mem_stack_aux.lo \ + MUMPS/src/sfac_mem_stack.lo \ + MUMPS/src/sfac_process_band.lo \ + MUMPS/src/sfac_process_blfac_slave.lo \ + MUMPS/src/sfac_process_blocfacto_LDLT.lo \ + MUMPS/src/sfac_process_blocfacto.lo \ + MUMPS/src/sfac_process_bf.lo \ + MUMPS/src/sfac_process_end_facto_slave.lo \ + MUMPS/src/sfac_process_contrib_type1.lo \ + MUMPS/src/sfac_process_contrib_type2.lo \ + MUMPS/src/sfac_process_contrib_type3.lo \ + MUMPS/src/sfac_process_maprow.lo \ + MUMPS/src/sfac_process_master2.lo \ + MUMPS/src/sfac_process_message.lo \ + MUMPS/src/sfac_process_root2slave.lo \ + MUMPS/src/sfac_process_root2son.lo \ + MUMPS/src/sfac_process_rtnelind.lo \ + MUMPS/src/sfac_root_parallel.lo \ + MUMPS/src/sfac_scalings.lo \ + MUMPS/src/sfac_determinant.lo \ + MUMPS/src/sfac_scalings_simScaleAbs.lo \ + MUMPS/src/sfac_scalings_simScale_util.lo \ + MUMPS/src/sfac_sol_pool.lo \ + MUMPS/src/sfac_type3_symmetrize.lo \ + MUMPS/src/sini_defaults.lo \ + MUMPS/src/smumps_c.lo \ + MUMPS/src/smumps_driver.lo \ + MUMPS/src/smumps_f77.lo \ + MUMPS/src/smumps_gpu.lo \ + MUMPS/src/smumps_iXamax.lo \ + MUMPS/src/sana_mtrans.lo \ + MUMPS/src/sooc_panel_piv.lo \ + MUMPS/src/srank_revealing.lo \ + MUMPS/src/ssol_aux.lo \ + MUMPS/src/ssol_bwd_aux.lo \ + MUMPS/src/ssol_bwd.lo \ + MUMPS/src/ssol_c.lo \ + MUMPS/src/ssol_fwd_aux.lo \ + MUMPS/src/ssol_fwd.lo \ + MUMPS/src/ssol_matvec.lo \ + MUMPS/src/ssol_root_parallel.lo \ + MUMPS/src/stools.lo \ + MUMPS/src/stype3_root.lo + + +# Module files that need to be deleted +CLEANFILES = *.mod +AM_CFLAGS = $(MY_DEFS) $(MUMPS_CFLAGS) + +# automake thinks that the .F files are F77, not F95, and requires F77 to be set +# set it to FC, and same for FFLAGS +F77 = $(FC) +FFLAGS = $(FCFLAGS) +thirdpartyincludedir = $(includedir)/coin-or/mumps +thirdpartyinclude_HEADERS = MUMPS/include/mumps_c_types.h \ + MUMPS/libseq/mumps_mpi.h mumps_compat.h mumps_int_def.h \ + $(am__append_5) $(am__append_6) +pkgconfiglibdir = $(libdir)/pkgconfig +pkgconfiglib_DATA = coinmumps.pc +all: $(BUILT_SOURCES) config.h mumps_compat.h mumps_int_def.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .F .c .f .lo .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +mumps_compat.h: stamp-h2 + @test -f $@ || rm -f stamp-h2 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h2 + +stamp-h2: $(srcdir)/mumps_compat.h.in $(top_builddir)/config.status + @rm -f stamp-h2 + cd $(top_builddir) && $(SHELL) ./config.status mumps_compat.h + +mumps_int_def.h: stamp-h3 + @test -f $@ || rm -f stamp-h3 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h3 + +stamp-h3: $(srcdir)/mumps_int_def.h.in $(top_builddir)/config.status + @rm -f stamp-h3 + cd $(top_builddir) && $(SHELL) ./config.status mumps_int_def.h + +distclean-hdr: + -rm -f config.h stamp-h1 mumps_compat.h stamp-h2 mumps_int_def.h stamp-h3 +coinmumps.pc: $(top_builddir)/config.status $(srcdir)/coinmumps.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +MUMPS/src/$(am__dirstamp): + @$(MKDIR_P) MUMPS/src + @: > MUMPS/src/$(am__dirstamp) +MUMPS/src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) MUMPS/src/$(DEPDIR) + @: > MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ana_AMDMF.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ana_blk.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ana_blk_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ana_omp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ana_orderings.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ana_orderings_wrappers_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ana_set_ordering.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/bcast_errors.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/double_linked_list.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/estim_flops.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/fac_asm_build_sort_index_ELT_m.lo: \ + MUMPS/src/$(am__dirstamp) MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/fac_asm_build_sort_index_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/fac_descband_data_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/fac_future_niv2_mod.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/fac_ibct_data_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/fac_maprow_data_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/front_data_mgt_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/lr_common.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_comm_ibcast.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_common.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_config_file_C.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_io_basic.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_io.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_io_err.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_io_thread.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_l0_omp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_memory_mod.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_metis64.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_metis.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_metis_int.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_mpitoomp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_numa.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_ooc_common.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_pord.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_print_defined.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_save_restore_C.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_scotch64.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_scotch.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_scotch_int.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_size.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_static_mapping.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_thread_affinity.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_register_thread.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_thread.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_type2_blocking.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_type_size.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/mumps_version.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/omp_tps_common_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sol_common.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/tools_common.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/libseq/$(am__dirstamp): + @$(MKDIR_P) MUMPS/libseq + @: > MUMPS/libseq/$(am__dirstamp) +MUMPS/libseq/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) MUMPS/libseq/$(DEPDIR) + @: > MUMPS/libseq/$(DEPDIR)/$(am__dirstamp) +MUMPS/libseq/mpi.lo: MUMPS/libseq/$(am__dirstamp) \ + MUMPS/libseq/$(DEPDIR)/$(am__dirstamp) +MUMPS/libseq/mpic.lo: MUMPS/libseq/$(am__dirstamp) \ + MUMPS/libseq/$(DEPDIR)/$(am__dirstamp) +MUMPS/libseq/elapse.lo: MUMPS/libseq/$(am__dirstamp) \ + MUMPS/libseq/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_aux_ELT.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_aux_par.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_dist_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_LDLT_preprocess.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_lr.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_mtrans.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dana_reordertree.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/darrowheads.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dbcast_int.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dend_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_asm_ELT.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_asm.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_asm_master_ELT_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_asm_master_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_b.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_determinant.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_distrib_distentry.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_distrib_ELT.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_front_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_front_LDLT_type1.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_front_LDLT_type2.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_front_LU_type1.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_front_LU_type2.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_front_type2_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_lastrtnelind.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_lr.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_mem_alloc_cb.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_mem_compress_cb.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_mem_dynamic.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_mem_free_block_cb.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_mem_stack_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_mem_stack.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_omp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_par_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_band.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_bf.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_blfac_slave.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_blocfacto.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_blocfacto_LDLT.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_contrib_type1.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_contrib_type2.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_contrib_type3.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_end_facto_slave.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_maprow.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_master2.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_message.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_root2slave.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_root2son.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_process_rtnelind.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_root_parallel.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_scalings.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_scalings_simScaleAbs.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_scalings_simScale_util.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_sispointers_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_sol_l0omp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_sol_pool.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dfac_type3_symmetrize.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dini_defaults.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dini_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dlr_core.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dlr_stats.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dlr_type.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_comm_buffer.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_config_file.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_f77.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_gpu.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_iXamax.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_load.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_lr_data_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_ooc_buffer.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_ooc.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_save_restore.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_save_restore_files.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_sol_es.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dmumps_struc_def.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/domp_tps_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dooc_panel_piv.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/drank_revealing.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_bwd_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_bwd.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_c.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_distrhs.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_fwd_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_fwd.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_lr.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_matvec.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_omp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dsol_root_parallel.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dstatic_ptr_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dtools.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/dtype3_root.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_aux_ELT.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_aux_par.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_dist_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_LDLT_preprocess.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_lr.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_mtrans.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sana_reordertree.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sarrowheads.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sbcast_int.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/send_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_asm_ELT.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_asm.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_asm_master_ELT_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_asm_master_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_b.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_determinant.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_distrib_distentry.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_distrib_ELT.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_front_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_front_LDLT_type1.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_front_LDLT_type2.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_front_LU_type1.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_front_LU_type2.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_front_type2_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_lastrtnelind.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_lr.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_mem_alloc_cb.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_mem_compress_cb.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_mem_dynamic.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_mem_free_block_cb.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_mem_stack_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_mem_stack.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_omp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_par_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_band.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_bf.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_blfac_slave.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_blocfacto.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_blocfacto_LDLT.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_contrib_type1.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_contrib_type2.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_contrib_type3.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_end_facto_slave.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_maprow.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_master2.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_message.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_root2slave.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_root2son.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_process_rtnelind.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_root_parallel.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_scalings.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_scalings_simScaleAbs.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_scalings_simScale_util.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_sispointers_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_sol_l0omp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_sol_pool.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sfac_type3_symmetrize.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sini_defaults.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sini_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/slr_core.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/slr_stats.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/slr_type.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_comm_buffer.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_config_file.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_f77.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_gpu.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_iXamax.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_load.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_lr_data_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_ooc_buffer.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_ooc.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_save_restore.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_save_restore_files.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_sol_es.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/smumps_struc_def.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/somp_tps_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sooc_panel_piv.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/srank_revealing.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_bwd_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_bwd.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_c.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_distrhs.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_driver.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_fwd_aux.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_fwd.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_lr.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_matvec.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_omp_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/ssol_root_parallel.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/sstatic_ptr_m.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/stools.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) +MUMPS/src/stype3_root.lo: MUMPS/src/$(am__dirstamp) \ + MUMPS/src/$(DEPDIR)/$(am__dirstamp) + +libcoinmumps.la: $(libcoinmumps_la_OBJECTS) $(libcoinmumps_la_DEPENDENCIES) $(EXTRA_libcoinmumps_la_DEPENDENCIES) + $(AM_V_F77LD)$(F77LINK) -rpath $(libdir) $(libcoinmumps_la_OBJECTS) $(libcoinmumps_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f MUMPS/libseq/*.$(OBJEXT) + -rm -f MUMPS/libseq/*.lo + -rm -f MUMPS/src/*.$(OBJEXT) + -rm -f MUMPS/src/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmumps_c.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smumps_c.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/libseq/$(DEPDIR)/elapse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/libseq/$(DEPDIR)/mpic.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/dmumps_gpu.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_common.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_config_file_C.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_io_basic.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_io_err.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_io_thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_metis.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_metis64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_metis_int.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_numa.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_pord.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_register_thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_save_restore_C.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_scotch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_scotch64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_scotch_int.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_size.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/mumps_thread_affinity.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@MUMPS/src/$(DEPDIR)/smumps_gpu.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.F.o: + $(AM_V_PPF77)$(PPF77COMPILE) -c -o $@ $< + +.F.obj: + $(AM_V_PPF77)$(PPF77COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.F.lo: + $(AM_V_PPF77)$(LTPPF77COMPILE) -c -o $@ $< +.F.f: + $(F77COMPILE) -F $< + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +.f.o: + $(AM_V_F77)$(F77COMPILE) -c -o $@ $< + +.f.obj: + $(AM_V_F77)$(F77COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.f.lo: + $(AM_V_F77)$(LTF77COMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf MUMPS/libseq/.libs MUMPS/libseq/_libs + -rm -rf MUMPS/src/.libs MUMPS/src/_libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfiglibDATA: $(pkgconfiglib_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfiglib_DATA)'; test -n "$(pkgconfiglibdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfiglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfiglibdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfiglibdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfiglibdir)" || exit $$?; \ + done + +uninstall-pkgconfiglibDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfiglib_DATA)'; test -n "$(pkgconfiglibdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfiglibdir)'; $(am__uninstall_files_from_dir) +install-thirdpartyincludeHEADERS: $(thirdpartyinclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(thirdpartyinclude_HEADERS)'; test -n "$(thirdpartyincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(thirdpartyincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(thirdpartyincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(thirdpartyincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(thirdpartyincludedir)" || exit $$?; \ + done + +uninstall-thirdpartyincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(thirdpartyinclude_HEADERS)'; test -n "$(thirdpartyincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(thirdpartyincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) config.h \ + mumps_compat.h mumps_int_def.h +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfiglibdir)" "$(DESTDIR)$(thirdpartyincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f MUMPS/libseq/$(DEPDIR)/$(am__dirstamp) + -rm -f MUMPS/libseq/$(am__dirstamp) + -rm -f MUMPS/src/$(DEPDIR)/$(am__dirstamp) + -rm -f MUMPS/src/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f ./$(DEPDIR)/dmumps_c.Plo + -rm -f ./$(DEPDIR)/smumps_c.Plo + -rm -f MUMPS/libseq/$(DEPDIR)/elapse.Plo + -rm -f MUMPS/libseq/$(DEPDIR)/mpic.Plo + -rm -f MUMPS/src/$(DEPDIR)/dmumps_gpu.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_common.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_config_file_C.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_io.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_io_basic.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_io_err.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_io_thread.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_metis.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_metis64.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_metis_int.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_numa.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_pord.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_register_thread.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_save_restore_C.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_scotch.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_scotch64.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_scotch_int.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_size.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_thread.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_thread_affinity.Plo + -rm -f MUMPS/src/$(DEPDIR)/smumps_gpu.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pkgconfiglibDATA \ + install-thirdpartyincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f ./$(DEPDIR)/dmumps_c.Plo + -rm -f ./$(DEPDIR)/smumps_c.Plo + -rm -f MUMPS/libseq/$(DEPDIR)/elapse.Plo + -rm -f MUMPS/libseq/$(DEPDIR)/mpic.Plo + -rm -f MUMPS/src/$(DEPDIR)/dmumps_gpu.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_common.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_config_file_C.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_io.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_io_basic.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_io_err.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_io_thread.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_metis.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_metis64.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_metis_int.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_numa.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_pord.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_register_thread.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_save_restore_C.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_scotch.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_scotch64.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_scotch_int.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_size.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_thread.Plo + -rm -f MUMPS/src/$(DEPDIR)/mumps_thread_affinity.Plo + -rm -f MUMPS/src/$(DEPDIR)/smumps_gpu.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfiglibDATA \ + uninstall-thirdpartyincludeHEADERS + +.MAKE: all check install install-am install-exec install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles am--refresh check \ + check-am clean clean-cscope clean-generic clean-libLTLIBRARIES \ + clean-libtool cscope cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-pkgconfiglibDATA install-ps install-ps-am \ + install-strip install-thirdpartyincludeHEADERS installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \ + uninstall-pkgconfiglibDATA uninstall-thirdpartyincludeHEADERS + +.PRECIOUS: Makefile + + +# this is to compile mumps_c.c once for each precision with different setting for MUMPS_ARITH +dmumps_c.c : $(srcdir)/MUMPS/src/mumps_c.c + echo "#define MUMPS_ARITH MUMPS_ARITH_d" > $@ + cat $< >> $@ + +smumps_c.c : $(srcdir)/MUMPS/src/mumps_c.c + echo "#define MUMPS_ARITH MUMPS_ARITH_s" > $@ + cat $< >> $@ + +# Dependencies between modules: +# i) arithmetic-dependent modules: +MUMPS/src/dana_aux.lo: \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/mumps_static_mapping.lo \ + MUMPS/src/ana_blk_m.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/dana_aux_par.lo: \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/mumps_memory_mod.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/dana_lr.lo: MUMPS/src/dlr_core.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/dfac_asm_master_ELT_m.lo: \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/dfac_mem_dynamic.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo +MUMPS/src/dfac_asm_master_m.lo: \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_asm_build_sort_index_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/dfac_mem_dynamic.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo +MUMPS/src/dfac_b.lo: \ + MUMPS/src/dfac_sispointers_m.lo +MUMPS/src/dfac_front_aux.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dfac_front_LU_type1.lo : \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dfac_front_LU_type2.lo : \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dfac_front_type2_aux.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dfac_front_LDLT_type1.lo : \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dfac_front_LDLT_type2.lo : \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dfac_front_type2_aux.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dfac_lr.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dana_lr.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dfac_front_type2_aux.lo : \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/dfac_front_aux.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/fac_ibct_data_m.lo +MUMPS/src/dfac_lr.lo: \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dlr_stats.lo +MUMPS/src/dfac_mem_dynamic.lo: \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dstatic_ptr_m.lo +MUMPS/src/dfac_omp_m.lo: \ + MUMPS/src/dfac_asm_master_m.lo \ + MUMPS/src/dfac_asm_master_ELT_m.lo \ + MUMPS/src/dfac_front_LU_type1.lo \ + MUMPS/src/dfac_front_LDLT_type1.lo \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dfac_par_m.lo: \ + MUMPS/src/dmumps_load.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/dfac_asm_master_m.lo \ + MUMPS/src/dfac_asm_master_ELT_m.lo \ + MUMPS/src/domp_tps_m.lo \ + MUMPS/src/dfac_front_LU_type1.lo \ + MUMPS/src/dfac_front_LU_type2.lo \ + MUMPS/src/dfac_front_LDLT_type1.lo \ + MUMPS/src/dfac_front_LDLT_type2.lo \ + MUMPS/src/dfac_mem_dynamic.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/dlr_core.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/lr_common.lo +MUMPS/src/dlr_stats.lo: MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dmumps_comm_buffer.lo: \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_core.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/fac_ibct_data_m.lo +MUMPS/src/dmumps_config_file.lo: MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dmumps_load.lo: \ + MUMPS/src/dmumps_comm_buffer.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/fac_future_niv2_mod.lo +MUMPS/src/dmumps_lr_data_m.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/front_data_mgt_m.lo +MUMPS/src/dmumps_ooc_buffer.lo: MUMPS/src/mumps_ooc_common.lo +MUMPS/src/dmumps_ooc.lo: \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/dmumps_ooc_buffer.lo \ + MUMPS/src/mumps_ooc_common.lo +MUMPS/src/dmumps_sol_es.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dmumps_lr_data_m.lo +MUMPS/src/dmumps_save_restore.lo: \ + MUMPS/src/dfac_sol_l0omp_m.lo \ + MUMPS/src/dmumps_struc_def.lo \ + MUMPS/src/dmumps_save_restore_files.lo \ + MUMPS/src/dmumps_lr_data_m.lo \ + MUMPS/src/dmumps_ooc.lo \ + MUMPS/src/front_data_mgt_m.lo +MUMPS/src/dmumps_save_restore_files.lo : MUMPS/src/dmumps_struc_def.lo +MUMPS/src/dsol_lr.lo: \ + MUMPS/src/dlr_type.lo \ + MUMPS/src/dlr_stats.lo \ + MUMPS/src/dmumps_lr_data_m.lo + +MUMPS/src/sana_aux.lo: \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/mumps_static_mapping.lo \ + MUMPS/src/ana_blk_m.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/sana_aux_par.lo: \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/mumps_memory_mod.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/sana_lr.lo: MUMPS/src/slr_core.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/ana_orderings_wrappers_m.lo +MUMPS/src/sfac_asm_master_ELT_m.lo: \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_asm_build_sort_index_ELT_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/sfac_mem_dynamic.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo +MUMPS/src/sfac_asm_master_m.lo: \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/fac_ibct_data_m.lo \ + MUMPS/src/fac_asm_build_sort_index_m.lo \ + MUMPS/src/lr_common.lo \ + MUMPS/src/sfac_mem_dynamic.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo +MUMPS/src/sfac_b.lo: \ + MUMPS/src/sfac_sispointers_m.lo +MUMPS/src/sfac_front_aux.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/sfac_front_LU_type1.lo : \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/sfac_front_LU_type2.lo : \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/sfac_front_type2_aux.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_struc_def.lo +MUMPS/src/sfac_front_LDLT_type1.lo : \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/sfac_front_LDLT_type2.lo : \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/sfac_front_type2_aux.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/sfac_lr.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/sana_lr.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_struc_def.lo +MUMPS/src/sfac_front_type2_aux.lo : \ + MUMPS/src/mumps_ooc_common.lo \ + MUMPS/src/sfac_front_aux.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/fac_ibct_data_m.lo +MUMPS/src/sfac_lr.lo: \ + MUMPS/src/slr_core.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/slr_stats.lo +MUMPS/src/sfac_mem_dynamic.lo: \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/sstatic_ptr_m.lo +MUMPS/src/sfac_omp_m.lo: \ + MUMPS/src/sfac_asm_master_m.lo \ + MUMPS/src/sfac_asm_master_ELT_m.lo \ + MUMPS/src/sfac_front_LU_type1.lo \ + MUMPS/src/sfac_front_LDLT_type1.lo \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/sfac_par_m.lo: \ + MUMPS/src/smumps_load.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/sfac_asm_master_m.lo \ + MUMPS/src/sfac_asm_master_ELT_m.lo \ + MUMPS/src/somp_tps_m.lo \ + MUMPS/src/sfac_front_LU_type1.lo \ + MUMPS/src/sfac_front_LU_type2.lo \ + MUMPS/src/sfac_front_LDLT_type1.lo \ + MUMPS/src/sfac_front_LDLT_type2.lo \ + MUMPS/src/sfac_mem_dynamic.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/omp_tps_common_m.lo \ + MUMPS/src/mumps_l0_omp_m.lo +MUMPS/src/slr_core.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/lr_common.lo +MUMPS/src/slr_stats.lo: MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_struc_def.lo +MUMPS/src/smumps_comm_buffer.lo: \ + MUMPS/src/mumps_comm_ibcast.lo \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_core.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/fac_ibct_data_m.lo +MUMPS/src/smumps_config_file.lo: MUMPS/src/smumps_struc_def.lo +MUMPS/src/smumps_load.lo: \ + MUMPS/src/smumps_comm_buffer.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/fac_future_niv2_mod.lo +MUMPS/src/smumps_lr_data_m.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/front_data_mgt_m.lo +MUMPS/src/smumps_ooc_buffer.lo: MUMPS/src/mumps_ooc_common.lo +MUMPS/src/smumps_ooc.lo: \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/smumps_ooc_buffer.lo \ + MUMPS/src/mumps_ooc_common.lo +MUMPS/src/smumps_sol_es.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/smumps_lr_data_m.lo +MUMPS/src/smumps_save_restore.lo: \ + MUMPS/src/sfac_sol_l0omp_m.lo \ + MUMPS/src/smumps_struc_def.lo \ + MUMPS/src/smumps_save_restore_files.lo \ + MUMPS/src/smumps_lr_data_m.lo \ + MUMPS/src/smumps_ooc.lo \ + MUMPS/src/front_data_mgt_m.lo +MUMPS/src/smumps_save_restore_files.lo : MUMPS/src/smumps_struc_def.lo +MUMPS/src/ssol_lr.lo: \ + MUMPS/src/slr_type.lo \ + MUMPS/src/slr_stats.lo \ + MUMPS/src/smumps_lr_data_m.lo + +# Dependencies between modules: +# ii) arithmetic-independent modules: +MUMPS/src/ana_omp_m.lo: MUMPS/src/double_linked_list.lo +MUMPS/src/fac_asm_build_sort_index_ELT_m.lo: MUMPS/src/omp_tps_common_m.lo +MUMPS/src/fac_asm_build_sort_index_m.lo: MUMPS/src/omp_tps_common_m.lo +MUMPS/src/fac_descband_data_m.lo: MUMPS/src/front_data_mgt_m.lo +MUMPS/src/fac_ibct_data_m.lo: MUMPS/src/front_data_mgt_m.lo +MUMPS/src/fac_maprow_data_m.lo: MUMPS/src/front_data_mgt_m.lo +MUMPS/src/mumps_comm_ibcast.lo: MUMPS/src/fac_future_niv2_mod.lo +MUMPS/src/mumps_static_mapping.lo: MUMPS/src/lr_common.lo + +$(OBJS_COMMON_OTHER) : $(OBJS_COMMON_MOD) +@MUMPS_DOUBLE_TRUE@$(DOBJS_OTHER) : $(OBJS_COMMON_MOD) $(DOBJS_MOD) +@MUMPS_SINGLE_TRUE@$(SOBJS_OTHER) : $(OBJS_COMMON_MOD) $(SOBJS_MOD) + +test: + @echo "No test available for Mumps." + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/README.md b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/README.md new file mode 100644 index 0000000..15df514 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/README.md @@ -0,0 +1,76 @@ +# ThirdParty-Mumps + +This is an autotools-based build system to build and install +[MUltifrontal Massively Parallel sparse direct Solver](http://mumps.enseeiht.fr/) (MUMPS). +This installation of MUMPS is used by some other COIN-OR projects. + +This version of ThirdParty-Mumps retrieves and builds MUMPS 5.5.0. + +## Dependencies + +- MUMPS source requires a Fortran 90 compiler. + +- MUMPS requires LAPACK to be available. `configure` will look for a Lapack + installation, but if that does not succeed, the flags to link with Lapack + should be specified with the `--with-lapack-lflags` argument of `configure`. + +- MUMPS can make use of METIS. `configure` will look for a METIS library and + header, but if that does not succeed, the arguments `--with-metis-lflags` + and `--with-metis-cflags` can be specified for `configure`. + + Both Metis 4 and Metis 5 can be used with ThirdParty-Mumps. + +## Installation steps + +1. Obtain the MUMPS source code. + + ********************************************************************** + Note: It is YOUR RESPONSIBILITY to ensure that you are entitled to + download and use this third party package. + ********************************************************************** + + The shell script `get.Mumps` can be used to automatically download and + extract the correct version of the MUMPS source code. The script will + first try to download from from https://coin-or-tools.github.io/ThirdParty-Mumps. + If this fails, it will attempt to download from the MUMPS website: http://mumps.enseeiht.fr/ + + The script requires wget, curl, or fetch to be available on the system + and in the shells search path (`$PATH`). + +2. Run `./configure`. Use `./configure --help` to see available options. + If using GFortran 10, add `ADD_FCFLAGS=-fallow-argument-mismatch` to + your configure call (see above) + +3. Run `make` to build the MUMPS library. + +4. Run `make install` to install the MUMPS library and header files. + +## NOTE for GFortran users + +MUMPS source does not compile out of the box when using GFortran 10, probably +due to some incompatibilities between assumed Fortran language standards, +see also [issue #4](https://github.com/coin-or-tools/ThirdParty-Mumps/issues/4). + +As a workaround, `configure` adds `-std=legacy` to the Fortran compiler flags +if `$FC` matches `*gfortran*`. + +## Single-precision codes + +This buildsystem can also build a single-precision version of MUMPS. +To do so, use the configure option `--with-precision=single`. + +It is also possible to build both single- and double-precision variants +of MUMPS into the same library by using `--with-precision=all`. + +## 64-bit integers + +This buildsystem can be instructed to change the integer type of MUMPS to +have a size of 64-bit by using the configure option `--with-intsize=64`. +This defines `MUMPS_INTSIZE64` instead of `MUMPS_INTSIZE32` in +`mumps_int_def.h` and instructs the Fortran compiler to use 8-byte integers. +The latter requires that the Fortran compiler is either GNU Fortran or +Intel Fortran. + +When MUMPS uses 64-bit integers, also Lapack and METIS need to use 64-bit +integers. For METIS, this means that `IDXTYPEWIDTH` needs to be set to 8 +instead of 4. diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/coinmumps.pc.in b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/coinmumps.pc.in new file mode 100644 index 0000000..8dabcf5 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/coinmumps.pc.in @@ -0,0 +1,15 @@ +@COIN_RELOCATABLE_FALSE@prefix=@prefix@ +@COIN_RELOCATABLE_TRUE@prefix=${pcfiledir}/../.. +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/coin-or/mumps + +Name: Mumps +Description: Multifrontal Massively Parallel sparse direct Solver +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Cflags: -I${includedir} +@COIN_STATIC_BUILD_FALSE@Libs: -L${libdir} -lcoinmumps +@COIN_STATIC_BUILD_FALSE@Requires.private: @MUMPS_PCFILES@ +@COIN_STATIC_BUILD_TRUE@Libs: -L${libdir} -lcoinmumps @MUMPS_LFLAGS_NOPC@ +@COIN_STATIC_BUILD_TRUE@Requires: @MUMPS_PCFILES@ diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/compile b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/compile new file mode 100755 index 0000000..209573f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/compile @@ -0,0 +1,384 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/* | msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + outfile= + implib= + linking=1 + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + outfile="$file" + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + outfile="$file" + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + case "$flag" in -IMPLIB:*) implib=${flag#-IMPLIB:} ;; esac + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -std=*) + set x "$@" -std:"${1#-std=}" + shift + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + -c) + linking=0 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + # remove old $implib, so we can distinguish between generated and not-generated implib below + if test -n "$implib" && test -f "$implib" ; then rm "$implib" ; fi + + # add path to MSVC link in front on PATH if we seem to link (check isn't so accurate, but some false-positives shouldn't matter) + # compiler will call the link it finds in the PATH, and we don't want it to use MSYS' /bin/link + # we assume that MSVC link is in same directory as cl and that cl is found in PATH + if test "$linking" = 1 && comppath=`which cl 2>/dev/null` ; then + comppath=`dirname "$comppath"` + #echo "Adding $comppath to front of PATH" + PATH="$comppath:$PATH" + fi + + #echo "compile: $@ $linker_opts" + "$@" $linker_opts || exit $? + + # if -implib got lost or ignored, then the lib should be named ${outfile/.dll/.lib} and we rename that file + if test -n "$implib" && test ! -f "$implib" ; then + echo "compile: mv ${outfile/.dll/.lib} $implib" + mv "${outfile/.dll/.lib}" "$implib" + fi + + exit 0 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe | \ + ifort | *[/\\]ifort | ifort.exe | *[/\\]ifort.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.guess b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.guess new file mode 100755 index 0000000..0fc11ed --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.guess @@ -0,0 +1,1686 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2020 Free Software Foundation, Inc. + +timestamp='2020-11-07' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=$(echo "$0" | sed -e 's,.*/,,') + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2020 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown +UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown +UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown +UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + #include + #ifdef __DEFINED_va_list + LIBC=musl + #else + LIBC=gnu + #endif + #endif + EOF + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')" + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)) + case "$UNAME_MACHINE_ARCH" in + aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,') + endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p') + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi-}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//') + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//') + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}') + ;; + *5.*) + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}') + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1) + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "$( (/bin/universe) 2>/dev/null)" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case $(/usr/bin/uname -p) in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" + exit ;; + sun4*:SunOS:*:*) + case "$(/usr/bin/arch -k)" in + Series*|S4*) + UNAME_RELEASE=$(uname -v) + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null) + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case "$(/bin/arch)" in + sun3) + echo m68k-sun-sunos"$UNAME_RELEASE" + ;; + sun4) + echo sparc-sun-sunos"$UNAME_RELEASE" + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') && + SYSTEM_NAME=$("$dummy" "$dummyarg") && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=$(/usr/bin/uname -p) + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + echo m88k-dg-dgux"$UNAME_RELEASE" + else + echo m88k-dg-dguxbcs"$UNAME_RELEASE" + fi + else + echo i586-dg-dgux"$UNAME_RELEASE" + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')" + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=$(/usr/bin/oslevel) + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }') + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/) + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null) + sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null) + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy") + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/') + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/') + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=$(uname -p) + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf + fi + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=$(/usr/bin/uname -p) + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-pc-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" + exit ;; + *:GNU:*:*) + # the GNU system + echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC" + exit ;; + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi + fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//') + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case $(/bin/uname -X | grep "^Machine") in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=$(sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //')) + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=$( (uname -p) 2>/dev/null) + echo "$UNAME_MACHINE"-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + echo mips-nec-sysv"$UNAME_RELEASE" + else + echo mips-unknown-sysv"$UNAME_RELEASE" + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=$(uname -p) + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=$(uname -p) + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + # shellcheck disable=SC2154 + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=$( (uname -p) 2>/dev/null) + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; +esac + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null); + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null || echo unknown) +uname -r = $( (uname -r) 2>/dev/null || echo unknown) +uname -s = $( (uname -s) 2>/dev/null || echo unknown) +uname -v = $( (uname -v) 2>/dev/null || echo unknown) + +/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null) +/bin/uname -X = $( (/bin/uname -X) 2>/dev/null) + +hostinfo = $( (hostinfo) 2>/dev/null) +/bin/universe = $( (/bin/universe) 2>/dev/null) +/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null) +/bin/arch = $( (/bin/arch) 2>/dev/null) +/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null) +/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null) + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.h.in b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.h.in new file mode 100644 index 0000000..5c28d48 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.h.in @@ -0,0 +1,112 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to dummy `main' function (if any) required to link to the Fortran + libraries. */ +#undef FC_DUMMY_MAIN + +/* Define if F77 and FC dummy `main' functions are identical. */ +#undef FC_DUMMY_MAIN_EQ_F77 + +/* Define to a macro mangling the given C identifier (in lower and upper + case), which must not contain underscores, for linking with Fortran. */ +#undef FC_FUNC + +/* As FC_FUNC, but for C identifiers containing underscores. */ +#undef FC_FUNC_ + +/* Define to 1 if your Fortran compiler doesn't accept -c and -o together. */ +#undef FC_NO_MINUS_C_MINUS_O + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Library Visibility Attribute */ +#undef MUMPS_CALL + +/* Library Visibility Attribute */ +#undef MUMPS_EXPORT + +/* Define if MUMPS integers have a size of 32-bit */ +#undef MUMPS_INTSIZE32 + +/* Define if MUMPS integers have a size of 64-bit */ +#undef MUMPS_INTSIZE64 + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#undef STDC_HEADERS + +/* Define to 1 if the LAPACK package is available */ +#undef THIRDPARTYMUMPS_HAS_LAPACK + +/* Define to 1 if the Metis package is available */ +#undef THIRDPARTYMUMPS_HAS_METIS + +/* Define to a macro mangling the given C identifier (in lower and upper + case). */ +#undef THIRDPARTYMUMPS_LAPACK_FUNC + +/* As THIRDPARTYMUMPS_LAPACK_FUNC, but for C identifiers containing + underscores. */ +#undef THIRDPARTYMUMPS_LAPACK_FUNC_ + +/* Version number of project */ +#undef THIRDPARTYMUMPS_VERSION + +/* Major version number of project. */ +#undef THIRDPARTYMUMPS_VERSION_MAJOR + +/* Minor version number of project. */ +#undef THIRDPARTYMUMPS_VERSION_MINOR + +/* Release version number of project. */ +#undef THIRDPARTYMUMPS_VERSION_RELEASE diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.sub b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.sub new file mode 100755 index 0000000..c874b7a --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/config.sub @@ -0,0 +1,1853 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2020 Free Software Foundation, Inc. + +timestamp='2020-11-07' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=$(echo "$0" | sed -e 's,.*/,,') + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2020 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=$(echo "$basic_machine" | sed 's/-.*//') + ;; + + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x$basic_os != x +then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|') + ;; + os2-emx) + kernel=os2 + os=$(echo $basic_os | sed -e 's|os2-emx|emx|') + ;; + nto-qnx*) + kernel=nto + os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|') + ;; + *-*) + # shellcheck disable=SC2162 + IFS="-" read kernel os <&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor-${kernel:+$kernel-}$os" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/configure b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/configure new file mode 100755 index 0000000..fbedee9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/configure @@ -0,0 +1,21824 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.71 for ThirdPartyMumps 3.0.3. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +# +# +# Copyright 2007-2009 International Business Machines and others. +# All Rights Reserved. +# This file is part of the open source package Coin which is distributed +# under the Eclipse Public License. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else $as_nop + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="as_nop=: +if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else \$as_nop + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : + +else \$as_nop + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null +then : + as_have_required=yes +else $as_nop + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : + +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$as_shell as_have_required=yes + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : + break 2 +fi +fi + done;; + esac + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi +fi + + + if test "x$CONFIG_SHELL" != x +then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." + else + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and +$0: https://github.com/coin-or-tools/ThirdParty-Mumps/issues/new +$0: about your system, including any error possibly output +$0: before this message. Then install a modern shell, or +$0: manually run the script under such a shell if you do +$0: have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else $as_nop + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else $as_nop + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='ThirdPartyMumps' +PACKAGE_TARNAME='thirdpartymumps' +PACKAGE_VERSION='3.0.3' +PACKAGE_STRING='ThirdPartyMumps 3.0.3' +PACKAGE_BUGREPORT='https://github.com/coin-or-tools/ThirdParty-Mumps/issues/new' +PACKAGE_URL='https://github.com/coin-or-tools/ThirdParty-Mumps' + +ac_unique_file="MUMPS/src/mumps_common.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_header_c_list= +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +MUMPS_CFLAGS_NOPC +MUMPS_LFLAGS_NOPC +MY_FDEFS +COIN_HAS_METIS_FALSE +COIN_HAS_METIS_TRUE +MUMPS_CFLAGS +METISCHECK_LFLAGS +COIN_HAS_LAPACK_FALSE +COIN_HAS_LAPACK_TRUE +COIN_PKG_CONFIG_PATH +COIN_HAS_PKGCONFIG_FALSE +COIN_HAS_PKGCONFIG_TRUE +ac_ct_PKG_CONFIG +PKG_CONFIG +MUMPS_PCFILES +MUMPS_LFLAGS +OPENMP_FCFLAGS +MUMPS_DOUBLE_FALSE +MUMPS_DOUBLE_TRUE +MUMPS_SINGLE_FALSE +MUMPS_SINGLE_TRUE +MY_DEFS +FCLIBS +COIN_STATIC_BUILD_FALSE +COIN_STATIC_BUILD_TRUE +LT_LDFLAGS +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +LIBTOOL +OBJDUMP +DLLTOOL +AS +ac_ct_AR +AR +ADD_FCFLAGS +ac_ct_FC +FCFLAGS +FC +ADD_CFLAGS +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +COIN_RELOCATABLE_FALSE +COIN_RELOCATABLE_TRUE +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +host_os +host_vendor +host_cpu +host +CC +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL +am__quote' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_msvc +enable_debug +enable_silent_rules +enable_maintainer_mode +enable_relocatable +enable_dependency_tracking +enable_static +with_pic +enable_shared +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +with_precision +with_intsize +enable_pthread_mumps +enable_openmp +with_lapack +with_lapack_lflags +with_metis +with_metis_lflags +with_metis_cflags +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +ADD_CFLAGS +FC +FCFLAGS +ADD_FCFLAGS +LT_SYS_LIBRARY_PATH +LT_LDFLAGS +PKG_CONFIG' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures ThirdPartyMumps 3.0.3 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/thirdpartymumps] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ThirdPartyMumps 3.0.3:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-msvc look for and allow only Intel/Microsoft compilers on + MinGW/MSys/Cygwin + --enable-debug build debugging symbols and turn off compiler + optimization + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-relocatable whether prefix in installed .pc files should be + setup relative to pcfiledir + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-static[=PKGS] build static libraries [default=no] + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-pthread-mumps disable use of pthread library + --disable-openmp do not use OpenMP + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-precision floating-point precision to build: single, double + (default), or all + --with-intsize integer size in bits to use: 32 or 64 + --without-lapack Do not use lapack. If an argument is given to + --with-lapack, then 'yes' is equivalent + to --with-lapack, 'no' is equivalent to + --without-lapack and any other argument is applied + as for --with-lapack-lflags. + --with-lapack-lflags Linker flags for lapack appropriate for your + environment. (Most often, -l specs for libraries.) + --without-metis Do not use Metis. If an argument is given to + --with-metis, then 'yes' is equivalent + to --with-metis, 'no' is equivalent to + --without-metis and any other argument is applied as + for --with-metis-lflags. + --with-metis-lflags Linker flags for Metis appropriate for your + environment. (Most often, -l specs for libraries.) + --with-metis-cflags Compiler flags for Metis appropriate for your + environment. (Most often, -I specs for header file + directories.) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + ADD_CFLAGS Additional C compiler options (if not overwriting CFLAGS) + FC Fortran compiler command + FCFLAGS Fortran compiler flags + ADD_FCFLAGS Additional Fortran compiler options (if not overwriting FCFLAGS) + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + LT_LDFLAGS Flags passed to libtool when building libraries or executables + that are installed + PKG_CONFIG path to pkg-config utility + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +ThirdPartyMumps home page: . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ThirdPartyMumps configure 3.0.3 +generated by GNU Autoconf 2.71 + +Copyright (C) 2021 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. + + +Copyright 2007-2009 International Business Machines and others. +All Rights Reserved. +This file is part of the open source package Coin which is distributed +under the Eclipse Public License. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_fc_try_compile LINENO +# --------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_fc_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_fc_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_fc_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. */ + +#include +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main (void) +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_fc_try_link LINENO +# ------------------------ +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_fc_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_fc_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_fc_try_link +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ThirdPartyMumps $as_me 3.0.3, which was +generated by GNU Autoconf 2.71. Invocation command line was + + $ $0$ac_configure_args_raw + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" + # Save into config.log some information that might help in debugging. + { + echo + + printf "%s\n" "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + printf "%s\n" "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + printf "%s\n" "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + printf "%s\n" "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +printf "%s\n" "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + ac_site_files="$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" +else + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" +fi + +for ac_site_file in $ac_site_files +do + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Test code for whether the C compiler supports C89 (global declarations) +ac_c_conftest_c89_globals=' +/* Does the compiler advertise C89 conformance? + Do not test the value of __STDC__, because some compilers set it to 0 + while being otherwise adequately conformant. */ +#if !defined __STDC__ +# error "Compiler does not advertise C89 conformance" +#endif + +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ +struct buf { int x; }; +struct buf * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not \xHH hex character constants. + These do not provoke an error unfortunately, instead are silently treated + as an "x". The following induces an error, until -std is added to get + proper ANSI mode. Curiously \x00 != x always comes out true, for an + array size at least. It is necessary to write \x00 == 0 to get something + that is true only with -std. */ +int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) '\''x'\'' +int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), + int, int);' + +# Test code for whether the C compiler supports C89 (body of main). +ac_c_conftest_c89_main=' +ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); +' + +# Test code for whether the C compiler supports C99 (global declarations) +ac_c_conftest_c99_globals=' +// Does the compiler advertise C99 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# error "Compiler does not advertise C99 conformance" +#endif + +#include +extern int puts (const char *); +extern int printf (const char *, ...); +extern int dprintf (int, const char *, ...); +extern void *malloc (size_t); + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +// dprintf is used instead of fprintf to avoid needing to declare +// FILE and stderr. +#define debug(...) dprintf (2, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + #error "your preprocessor is broken" +#endif +#if BIG_OK +#else + #error "your preprocessor is broken" +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case '\''s'\'': // string + str = va_arg (args_copy, const char *); + break; + case '\''d'\'': // int + number = va_arg (args_copy, int); + break; + case '\''f'\'': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +} +' + +# Test code for whether the C compiler supports C99 (body of main). +ac_c_conftest_c99_main=' + // Check bool. + _Bool success = false; + success |= (argc != 0); + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[0] = argv[0][0]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' + || dynamic_array[ni.number - 1] != 543); +' + +# Test code for whether the C compiler supports C11 (global declarations) +ac_c_conftest_c11_globals=' +// Does the compiler advertise C11 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L +# error "Compiler does not advertise C11 conformance" +#endif + +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +' + +# Test code for whether the C compiler supports C11 (body of main). +ac_c_conftest_c11_main=' + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); + v1.i = 2; + v1.w.k = 5; + ok |= v1.i != 5; +' + +# Test code for whether the C compiler supports C11 (complete). +ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} +${ac_c_conftest_c11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + ${ac_c_conftest_c11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C99 (complete). +ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (complete). +ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + return ok; +} +" + +as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" +as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" +as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" +as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" +as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" +as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" +as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" +as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" +as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" + +# Auxiliary files required by this configure script. +ac_aux_files="ltmain.sh ar-lib compile missing install-sh config.guess config.sub" + +# Locations in which to look for auxiliary files. +ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." + +# Search for a directory containing all of the required auxiliary files, +# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. +# If we don't find one directory that contains all the files we need, +# we report the set of missing files from the *first* directory in +# $ac_aux_dir_candidates and give up. +ac_missing_aux_files="" +ac_first_candidate=: +printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in $ac_aux_dir_candidates +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + + printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 + ac_aux_dir_found=yes + ac_install_sh= + for ac_aux in $ac_aux_files + do + # As a special case, if "install-sh" is required, that requirement + # can be satisfied by any of "install-sh", "install.sh", or "shtool", + # and $ac_install_sh is set appropriately for whichever one is found. + if test x"$ac_aux" = x"install-sh" + then + if test -f "${as_dir}install-sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 + ac_install_sh="${as_dir}install-sh -c" + elif test -f "${as_dir}install.sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 + ac_install_sh="${as_dir}install.sh -c" + elif test -f "${as_dir}shtool"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 + ac_install_sh="${as_dir}shtool install -c" + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} install-sh" + else + break + fi + fi + else + if test -f "${as_dir}${ac_aux}"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" + else + break + fi + fi + fi + done + if test "$ac_aux_dir_found" = yes; then + ac_aux_dir="$as_dir" + break + fi + ac_first_candidate=false + + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +fi + + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +if test -f "${ac_aux_dir}config.guess"; then + ac_config_guess="$SHELL ${ac_aux_dir}config.guess" +fi +if test -f "${ac_aux_dir}config.sub"; then + ac_config_sub="$SHELL ${ac_aux_dir}config.sub" +fi +if test -f "$ac_aux_dir/configure"; then + ac_configure="$SHELL ${ac_aux_dir}configure" +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + +# List one file in the package so that the configure script can test +# whether the package is actually there + + + + + + # Make sure we can run config.sub. +$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +printf %s "checking build system type... " >&6; } +if test ${ac_cv_build+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +printf "%s\n" "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + + + + + # Check whether --enable-msvc was given. +if test ${enable_msvc+y} +then : + enableval=$enable_msvc; enable_msvc=$enableval +else $as_nop + enable_msvc=no + case $build in + *-mingw* | *-cygwin* | *-msys* ) + for ac_prog in gcc clang icl cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC" && break +done + + case "$CC" in *cl ) enable_msvc=yes ;; esac + ;; + esac +fi + + + + + + # Check whether --enable-debug was given. +if test ${enable_debug+y} +then : + enableval=$enable_debug; enable_debug=$enableval +else $as_nop + enable_debug=no +fi + + + + + + + + if test "$enable_debug" = yes ; then + if test "$enable_msvc" = yes ; then + : ${FFLAGS:="-nologo -fpp -Z7 -MDd $ADD_FFLAGS"} + : ${FCFLAGS:="-nologo -fpp -Z7 -MDd $ADD_FCFLAGS"} + : ${CFLAGS:="-nologo -Z7 -MDd $ADD_CFLAGS"} + : ${CXXFLAGS:="-nologo -EHs -Z7 -MDd -Zc:__cplusplus $ADD_CXXFLAGS"} + else + : ${FFLAGS:="-g $ADD_FFLAGS"} + : ${FCFLAGS:="-g $ADD_FCFLAGS"} + : ${CFLAGS:="-g $ADD_CFLAGS"} + : ${CXXFLAGS:="-g $ADD_CXXFLAGS"} + fi + else + if test "$enable_msvc" = yes ; then + : ${FFLAGS:="-nologo -fpp -O2 -MD $ADD_FFLAGS"} + : ${FCFLAGS:="-nologo -fpp -O2 -MD $ADD_FCFLAGS"} + : ${CFLAGS:="-nologo -DNDEBUG -O2 -MD $ADD_CFLAGS"} + : ${CXXFLAGS:="-nologo -EHs -DNDEBUG -O2 -MD -Zc:__cplusplus $ADD_CXXFLAGS"} + else + : ${FFLAGS:="-O2 $ADD_FFLAGS"} + : ${FCFLAGS:="-O2 $ADD_FCFLAGS"} + : ${CFLAGS:="-O2 -DNDEBUG $ADD_CFLAGS"} + : ${CXXFLAGS:="-O2 -DNDEBUG $ADD_CXXFLAGS"} + fi + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +printf %s "checking host system type... " >&6; } +if test ${ac_cv_host+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +printf "%s\n" "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +am__api_version='1.16' + + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test ${ac_cv_path_install+y}; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +printf %s "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` + + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + + + if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 +printf %s "checking for a race-free mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test ${ac_cv_path_mkdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue + case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir ('*'coreutils) '* | \ + 'BusyBox '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test ${ac_cv_path_mkdir+y}; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +printf "%s\n" "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval test \${ac_cv_prog_make_${ac_make}_set+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + SET_MAKE= +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + + + + + + + + + + +printf "%s\n" "#define THIRDPARTYMUMPS_VERSION \"3.0.3\"" >>confdefs.h + + +printf "%s\n" "#define THIRDPARTYMUMPS_VERSION_MAJOR 3" >>confdefs.h + + +printf "%s\n" "#define THIRDPARTYMUMPS_VERSION_MINOR 0" >>confdefs.h + + +printf "%s\n" "#define THIRDPARTYMUMPS_VERSION_RELEASE 3" >>confdefs.h + + + + + + + + + + + # libtool has some magic for host_os and build_os being mingw, but doesn't know about msys + if test $host_os = msys ; then + host_os=mingw + host=`echo $host | sed -e 's/msys/mingw/'` + fi + + if test $build_os = msys ; then + build_os=mingw + build=`echo $build | sed -e 's/msys/mingw/'` + fi + + # Check whether --enable-silent-rules was given. +if test ${enable_silent_rules+y} +then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +printf %s "checking whether $am_make supports nested variables... " >&6; } +if test ${am_cv_make_support_nested_variables+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if printf "%s\n" 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test ${enable_maintainer_mode+y} +then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else $as_nop + USE_MAINTAINER_MODE=no +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +printf "%s\n" "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + + if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='thirdpartymumps' + VERSION='3.0.3' + + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + + # Figure out the path where libraries are installed. + # Unless the user specifies --prefix, prefix is set to NONE until the + # end of configuration, at which point it will be set to $ac_default_prefix. + # Unless the user specifies --exec-prefix, exec-prefix is set to NONE until + # the end of configuration, at which point it's set to '${prefix}'. + # Sheesh. So do the expansion, then back it out. + save_prefix=$prefix + save_exec_prefix=$exec_prefix + if test "x$prefix" = xNONE ; then + prefix=$ac_default_prefix + fi + if test "x$exec_prefix" = xNONE ; then + exec_prefix=$prefix + fi + expanded_libdir=$libdir + while expr "$expanded_libdir" : '.*$.*' >/dev/null 2>&1 ; do + eval expanded_libdir=$expanded_libdir + done + prefix=$save_prefix + exec_prefix=$save_exec_prefix + + # Check whether --enable-relocatable was given. +if test ${enable_relocatable+y} +then : + enableval=$enable_relocatable; coin_enable_relocatable=$enableval +else $as_nop + coin_enable_relocatable=no +fi + + if test $coin_enable_relocatable = yes; then + COIN_RELOCATABLE_TRUE= + COIN_RELOCATABLE_FALSE='#' +else + COIN_RELOCATABLE_TRUE='#' + COIN_RELOCATABLE_FALSE= +fi + + + +############################################################################# +# Standard build tool stuff # +############################################################################# + +# Get the name of the C compiler and appropriate compiler options + + + + + + + + + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +printf "%s\n" "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test ${enable_dependency_tracking+y} +then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + + + + + if test $enable_msvc = yes ; then + for ac_prog in icl cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC" && break +done + + if test -n "$CC" ; then + CC="$am_aux_dir/compile $CC" + ac_cv_prog_CC="$CC" + LD="$CC" + : ${AR:=lib} + else + as_fn_error $? "Neither MS nor Intel C compiler found in PATH and CC is unset." "$LINENO" 5 + fi + fi + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in gcc clang cc icc icl cl cc xlc xlc_r pgcc + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in gcc clang cc icc icl cl cc xlc xlc_r pgcc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion -version; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else $as_nop + ac_file='' +fi +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +printf "%s\n" "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +printf "%s\n" "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +printf "%s\n" "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+y} +ac_save_CFLAGS=$CFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +else $as_nop + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c11=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c89_program +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +printf %s "checking whether $CC understands -c and -o together... " >&6; } +if test ${am_cv_prog_cc_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_CC_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + + + +# Get the name of the Fortran compiler and appropriate compiler options + + + + # If enable-msvc, then test for Intel Fortran compiler for Windows + # explicitly and add compile-wrapper, because the compile-wrapper works + # around issues when having the wrong link.exe in the PATH first. + if test $enable_msvc = yes ; then + for ac_prog in ifort +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$FC"; then + ac_cv_prog_FC="$FC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_FC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +FC=$ac_cv_prog_FC +if test -n "$FC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FC" >&5 +printf "%s\n" "$FC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$FC" && break +done + + if test -n "$FC" ; then + FC="$am_aux_dir/compile $FC" + fi + fi + + # if not msvc-enabled, then look for some Fortran compiler and check whether it works + # if FC is set, then this only checks whether it works + if test $enable_msvc = no || test -n "$FC" ; then + ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in gfortran ifort g95 f95 f90 pgf90 ifc frt xlf_r fl32 + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$FC"; then + ac_cv_prog_FC="$FC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_FC="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +FC=$ac_cv_prog_FC +if test -n "$FC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FC" >&5 +printf "%s\n" "$FC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$FC" && break + done +fi +if test -z "$FC"; then + ac_ct_FC=$FC + for ac_prog in gfortran ifort g95 f95 f90 pgf90 ifc frt xlf_r fl32 +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_FC"; then + ac_cv_prog_ac_ct_FC="$ac_ct_FC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_FC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_FC=$ac_cv_prog_ac_ct_FC +if test -n "$ac_ct_FC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FC" >&5 +printf "%s\n" "$ac_ct_FC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_FC" && break +done + + if test "x$ac_ct_FC" = x; then + FC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + FC=$ac_ct_FC + fi +fi + + +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Fortran compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done +rm -f a.out + +# If we don't use `.F' as extension, the preprocessor is not run on the +# input file. (Note that this only needs to work for GNU compilers.) +ac_save_ext=$ac_ext +ac_ext=F +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU Fortran" >&5 +printf %s "checking whether the compiler supports GNU Fortran... " >&6; } +if test ${ac_cv_fc_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat > conftest.$ac_ext <<_ACEOF + program main +#ifndef __GNUC__ + choke me +#endif + + end +_ACEOF +if ac_fn_fc_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_fc_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_fc_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_fc_compiler_gnu + +ac_ext=$ac_save_ext +ac_test_FCFLAGS=${FCFLAGS+y} +ac_save_FCFLAGS=$FCFLAGS +FCFLAGS= +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $FC accepts -g" >&5 +printf %s "checking whether $FC accepts -g... " >&6; } +if test ${ac_cv_prog_fc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + FCFLAGS=-g +cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +if ac_fn_fc_try_compile "$LINENO" +then : + ac_cv_prog_fc_g=yes +else $as_nop + ac_cv_prog_fc_g=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_fc_g" >&5 +printf "%s\n" "$ac_cv_prog_fc_g" >&6; } +if test $ac_test_FCFLAGS; then + FCFLAGS=$ac_save_FCFLAGS +elif test $ac_cv_prog_fc_g = yes; then + if test "x$ac_cv_fc_compiler_gnu" = xyes; then + FCFLAGS="-g -O2" + else + FCFLAGS="-g" + fi +else + if test "x$ac_cv_fc_compiler_gnu" = xyes; then + FCFLAGS="-O2" + else + FCFLAGS= + fi +fi + +if test $ac_compiler_gnu = yes; then + GFC=yes +else + GFC= +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + fi + + # check whether compile script should be used to wrap around Fortran compiler + if test -n "$FC" ; then + ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $FC understands -c and -o together" >&5 +printf %s "checking whether $FC understands -c and -o together... " >&6; } +if test ${ac_cv_prog_fc_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +# We test twice because some compilers refuse to overwrite an existing +# `.o' file with `-o', although they will create one. +ac_try='$FC $FCFLAGS -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + ac_cv_prog_fc_c_o=yes +else + ac_cv_prog_fc_c_o=no +fi +rm -rf conftest* +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_fc_c_o" >&5 +printf "%s\n" "$ac_cv_prog_fc_c_o" >&6; } +if test $ac_cv_prog_fc_c_o = no; then + +printf "%s\n" "#define FC_NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test $ac_cv_prog_fc_c_o = no ; then + FC="$am_aux_dir/compile $FC" + fi + fi + + + +if test -z "$FC" ; then + as_fn_error $? "No Fortran 90 compiler found. Try setting environment variable FC." "$LINENO" 5 +fi + +# Initialize libtool + +case `pwd` in + *\ * | *\ *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +printf %s "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +printf "%s\n" "printf" >&6; } ;; + print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +printf "%s\n" "print -r" >&6; } ;; + *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +printf "%s\n" "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +printf %s "checking for egrep... " >&6; } +if test ${ac_cv_path_EGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in egrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +printf "%s\n" "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +printf %s "checking for fgrep... " >&6; } +if test ${ac_cv_path_FGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in fgrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +printf "%s\n" "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test ${with_gnu_ld+y} +then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else $as_nop + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +printf %s "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +printf %s "checking for non-GNU ld... " >&6; } +fi +if test ${lt_cv_path_LD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +printf "%s\n" "$LD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +printf %s "checking if the linker ($LD) is GNU ld... " >&6; } +if test ${lt_cv_prog_gnu_ld+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test ${lt_cv_path_NM+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +printf "%s\n" "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DUMPBIN+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +printf "%s\n" "$DUMPBIN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DUMPBIN+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +printf "%s\n" "$ac_ct_DUMPBIN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +printf %s "checking the name lister ($NM) interface... " >&6; } +if test ${lt_cv_nm_interface+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +printf "%s\n" "$lt_cv_nm_interface" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +printf %s "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +printf "%s\n" "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +printf %s "checking the maximum length of command line arguments... " >&6; } +if test ${lt_cv_sys_max_cmd_len+y} +then : + printf %s "(cached) " >&6 +else $as_nop + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +printf %s "checking how to convert $build file names to $host format... " >&6; } +if test ${lt_cv_to_host_file_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +printf %s "checking how to convert $build file names to toolchain format... " >&6; } +if test ${lt_cv_to_tool_file_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +printf %s "checking for $LD option to reload object files... " >&6; } +if test ${lt_cv_ld_reload_flag+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_reload_flag='-r' +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +printf "%s\n" "$OBJDUMP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +printf "%s\n" "$ac_ct_OBJDUMP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +printf %s "checking how to recognize dependent libraries... " >&6; } +if test ${lt_cv_deplibs_check_method+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +printf "%s\n" "$DLLTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +printf "%s\n" "$ac_ct_DLLTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +printf %s "checking how to associate runtime and link libraries... " >&6; } +if test ${lt_cv_sharedlib_from_linklib_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +printf "%s\n" "$AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +printf "%s\n" "$ac_ct_AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +printf %s "checking for archiver @FILE support... " >&6; } +if test ${lt_cv_ar_at_file+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +printf "%s\n" "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +printf "%s\n" "$RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +printf "%s\n" "$ac_ct_RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +printf %s "checking command to parse $NM output from $compiler object... " >&6; } +if test ${lt_cv_sys_global_symbol_pipe+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +printf "%s\n" "failed" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +printf "%s\n" "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +printf %s "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test ${with_sysroot+y} +then : + withval=$with_sysroot; +else $as_nop + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +printf "%s\n" "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +printf "%s\n" "${lt_sysroot:-no}" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +printf %s "checking for a working dd... " >&6; } +if test ${ac_cv_path_lt_DD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in dd + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +printf "%s\n" "$ac_cv_path_lt_DD" >&6; } + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +printf %s "checking how to truncate binary pipes... " >&6; } +if test ${lt_cv_truncate_bin+y} +then : + printf %s "(cached) " >&6 +else $as_nop + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +printf "%s\n" "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test ${enable_libtool_lock+y} +then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +printf %s "checking whether the C compiler needs -belf... " >&6; } +if test ${lt_cv_cc_needs_belf+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_cc_needs_belf=yes +else $as_nop + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_MANIFEST_TOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +printf "%s\n" "$MANIFEST_TOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if test ${lt_cv_path_mainfest_tool+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DSYMUTIL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +printf "%s\n" "$DSYMUTIL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_NMEDIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +printf "%s\n" "$NMEDIT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_NMEDIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +printf "%s\n" "$ac_ct_NMEDIT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_LIPO+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +printf "%s\n" "$LIPO" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_LIPO+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +printf "%s\n" "$ac_ct_LIPO" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +printf "%s\n" "$OTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +printf "%s\n" "$ac_ct_OTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OTOOL64+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +printf "%s\n" "$OTOOL64" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OTOOL64+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +printf "%s\n" "$ac_ct_OTOOL64" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +printf %s "checking for -single_module linker flag... " >&6; } +if test ${lt_cv_apple_cc_single_mod+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +printf %s "checking for -exported_symbols_list linker flag... " >&6; } +if test ${lt_cv_ld_exported_symbols_list+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_ld_exported_symbols_list=yes +else $as_nop + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +printf %s "checking for -force_load linker flag... " >&6; } +if test ${lt_cv_ld_force_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +printf "%s\n" "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +ac_header= ac_cache= +for ac_item in $ac_header_c_list +do + if test $ac_cache; then + ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" + if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then + printf "%s\n" "#define $ac_item 1" >> confdefs.h + fi + ac_header= ac_cache= + elif test $ac_header; then + ac_cache=$ac_item + else + ac_header=$ac_item + fi +done + + + + + + + + +if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes +then : + +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes +then : + printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h + +fi + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + if test -n "$ac_tool_prefix"; then + for ac_prog in ar lib "link -lib" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +printf "%s\n" "$AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar lib "link -lib" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +printf "%s\n" "$ac_ct_AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 +printf %s "checking the archiver ($AR) interface... " >&6; } +if test ${am_cv_ar_interface+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + am_cv_ar_interface=ar + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int some_variable = 0; +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 +printf "%s\n" "$am_cv_ar_interface" >&6; } + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + as_fn_error $? "could not determine $AR interface" "$LINENO" 5 + ;; +esac + + + + + + +# Set options +# Check whether --enable-static was given. +if test ${enable_static+y} +then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_static=no +fi + + + + + + + + +# Check whether --with-pic was given. +if test ${with_pic+y} +then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + pic_mode=yes +fi + + + + + + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AS+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="${ac_tool_prefix}as" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +printf "%s\n" "$AS" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AS+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AS="as" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +printf "%s\n" "$ac_ct_AS" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +printf "%s\n" "$DLLTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +printf "%s\n" "$ac_ct_DLLTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +printf "%s\n" "$OBJDUMP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +printf "%s\n" "$ac_ct_OBJDUMP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + enable_dlopen=no + + + + # Check whether --enable-shared was given. +if test ${enable_shared+y} +then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_shared=yes +fi + + + + + + + + + + + + # Check whether --enable-fast-install was given. +if test ${enable_fast_install+y} +then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +printf %s "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test ${with_aix_soname+y} +then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else $as_nop + if test ${lt_cv_with_aix_soname+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +printf "%s\n" "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +printf %s "checking for objdir... " >&6; } +if test ${lt_cv_objdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +printf "%s\n" "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +printf %s "checking for ${ac_tool_prefix}file... " >&6; } +if test ${lt_cv_path_MAGIC_CMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +printf "%s\n" "$MAGIC_CMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +printf %s "checking for file... " >&6; } +if test ${lt_cv_path_MAGIC_CMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +printf "%s\n" "$MAGIC_CMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test ${lt_cv_prog_compiler_rtti_exceptions+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +printf %s "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +printf "%s\n" "$hard_links" >&6; } + if test no = "$hard_links"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath_+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath_+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++ or Intel C++/Fortran Compiler. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl* | icl*| ifort*) + # Native MSVC or ICC or IFORT + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC and ICC and IFORT wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +printf %s "checking if $CC understands -b... " >&6; } +if test ${lt_cv_prog_compiler__b+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if test ${lt_cv_irix_exported_symbol+y} +then : + printf %s "(cached) " >&6 +else $as_nop + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_irix_exported_symbol=yes +else $as_nop + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +printf "%s\n" "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +printf %s "checking whether -lc should be explicitly linked in... " >&6; } +if test ${lt_cv_archive_cmds_need_lc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +printf %s "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl* | *,icl* | *,ifort*) + # Native MSVC or ICC or IFORT + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if test ${lt_cv_shlibpath_overrides_runpath+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null +then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +printf %s "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +printf "%s\n" "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dl_dlopen=yes +else $as_nop + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else $as_nop + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes +then : + lt_cv_dlopen=shl_load +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +printf %s "checking for shl_load in -ldld... " >&6; } +if test ${ac_cv_lib_dld_shl_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main (void) +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dld_shl_load=yes +else $as_nop + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes +then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else $as_nop + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes +then : + lt_cv_dlopen=dlopen +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dl_dlopen=yes +else $as_nop + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +printf %s "checking for dlopen in -lsvld... " >&6; } +if test ${ac_cv_lib_svld_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_svld_dlopen=yes +else $as_nop + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +printf %s "checking for dld_link in -ldld... " >&6; } +if test ${ac_cv_lib_dld_dld_link+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main (void) +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dld_dld_link=yes +else $as_nop + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes +then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +printf %s "checking whether a program can dlopen itself... " >&6; } +if test ${lt_cv_dlopen_self+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +printf "%s\n" "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +printf %s "checking whether a statically linked program can dlopen itself... " >&6; } +if test ${lt_cv_dlopen_self_static+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +printf %s "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +printf %s "checking if libtool supports shared libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +printf "%s\n" "$can_build_shared" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +printf %s "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +printf "%s\n" "$enable_shared" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +printf %s "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +printf "%s\n" "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + + + + + ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu + + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +archive_cmds_need_lc_FC=no +allow_undefined_flag_FC= +always_export_symbols_FC=no +archive_expsym_cmds_FC= +export_dynamic_flag_spec_FC= +hardcode_direct_FC=no +hardcode_direct_absolute_FC=no +hardcode_libdir_flag_spec_FC= +hardcode_libdir_separator_FC= +hardcode_minus_L_FC=no +hardcode_automatic_FC=no +inherit_rpath_FC=no +module_cmds_FC= +module_expsym_cmds_FC= +link_all_deplibs_FC=unknown +old_archive_cmds_FC=$old_archive_cmds +reload_flag_FC=$reload_flag +reload_cmds_FC=$reload_cmds +no_undefined_flag_FC= +whole_archive_flag_spec_FC= +enable_shared_with_static_runtimes_FC=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +objext_FC=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + compiler_FC=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +printf %s "checking if libtool supports shared libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +printf "%s\n" "$can_build_shared" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +printf %s "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +printf "%s\n" "$enable_shared" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +printf %s "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +printf "%s\n" "$enable_static" >&6; } + + GCC_FC=$ac_cv_fc_compiler_gnu + LD_FC=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_FC= +postdep_objects_FC= +predeps_FC= +postdeps_FC= +compiler_lib_search_path_FC= + +cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_FC"; then + compiler_lib_search_path_FC=$prev$p + else + compiler_lib_search_path_FC="${compiler_lib_search_path_FC} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_FC"; then + postdeps_FC=$prev$p + else + postdeps_FC="${postdeps_FC} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_FC"; then + predep_objects_FC=$p + else + predep_objects_FC="$predep_objects_FC $p" + fi + else + if test -z "$postdep_objects_FC"; then + postdep_objects_FC=$p + else + postdep_objects_FC="$postdep_objects_FC $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling FC test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken + + +case " $postdeps_FC " in +*" -lc "*) archive_cmds_need_lc_FC=no ;; +esac + compiler_lib_search_dirs_FC= +if test -n "${compiler_lib_search_path_FC}"; then + compiler_lib_search_dirs_FC=`echo " ${compiler_lib_search_path_FC}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_FC= +lt_prog_compiler_pic_FC= +lt_prog_compiler_static_FC= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_static_FC='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_FC='-Bstatic' + fi + lt_prog_compiler_pic_FC='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_FC='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_FC='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_FC='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_FC='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_FC='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_FC= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_FC='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_FC=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_FC='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_FC=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic_FC='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl_FC='-Xlinker ' + if test -n "$lt_prog_compiler_pic_FC"; then + lt_prog_compiler_pic_FC="-Xcompiler $lt_prog_compiler_pic_FC" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_FC='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_FC='-Bstatic' + else + lt_prog_compiler_static_FC='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_FC='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl_FC='-Wl,-Wl,,' + lt_prog_compiler_pic_FC='-PIC' + lt_prog_compiler_static_FC='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_FC='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_FC='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_FC='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_FC='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_FC='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_FC='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_FC='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-KPIC' + lt_prog_compiler_static_FC='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-fPIC' + lt_prog_compiler_static_FC='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='--shared' + lt_prog_compiler_static_FC='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl_FC='-Wl,-Wl,,' + lt_prog_compiler_pic_FC='-PIC' + lt_prog_compiler_static_FC='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-fPIC' + lt_prog_compiler_static_FC='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-fpic' + lt_prog_compiler_static_FC='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_FC='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_FC='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-qpic' + lt_prog_compiler_static_FC='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic_FC='-KPIC' + lt_prog_compiler_static_FC='-Bstatic' + lt_prog_compiler_wl_FC='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic_FC='-KPIC' + lt_prog_compiler_static_FC='-Bstatic' + lt_prog_compiler_wl_FC='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic_FC='-KPIC' + lt_prog_compiler_static_FC='-Bstatic' + lt_prog_compiler_wl_FC='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-fPIC' + lt_prog_compiler_static_FC='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-fpic' + lt_prog_compiler_static_FC='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic_FC='-KPIC' + lt_prog_compiler_static_FC='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_FC='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_FC='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_FC='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static_FC='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_FC='-KPIC' + lt_prog_compiler_static_FC='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl_FC='-Qoption ld ';; + *) + lt_prog_compiler_wl_FC='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_FC='-Qoption ld ' + lt_prog_compiler_pic_FC='-PIC' + lt_prog_compiler_static_FC='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-KPIC' + lt_prog_compiler_static_FC='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_FC='-Kconform_pic' + lt_prog_compiler_static_FC='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_pic_FC='-KPIC' + lt_prog_compiler_static_FC='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_FC='-Wl,' + lt_prog_compiler_can_build_shared_FC=no + ;; + + uts4*) + lt_prog_compiler_pic_FC='-pic' + lt_prog_compiler_static_FC='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_FC=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_FC= + ;; + *) + lt_prog_compiler_pic_FC="$lt_prog_compiler_pic_FC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_FC=$lt_prog_compiler_pic_FC +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_FC" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_FC" >&6; } +lt_prog_compiler_pic_FC=$lt_cv_prog_compiler_pic_FC + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_FC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_FC works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_FC works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works_FC=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_FC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_FC=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_FC" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works_FC" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_FC"; then + case $lt_prog_compiler_pic_FC in + "" | " "*) ;; + *) lt_prog_compiler_pic_FC=" $lt_prog_compiler_pic_FC" ;; + esac +else + lt_prog_compiler_pic_FC= + lt_prog_compiler_can_build_shared_FC=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_FC eval lt_tmp_static_flag=\"$lt_prog_compiler_static_FC\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works_FC=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_FC=yes + fi + else + lt_cv_prog_compiler_static_works_FC=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_FC" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works_FC" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_FC"; then + : +else + lt_prog_compiler_static_FC= +fi + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o_FC=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_FC=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_FC" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o_FC" >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o_FC=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_FC=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_FC" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o_FC" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_FC" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +printf %s "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +printf "%s\n" "$hard_links" >&6; } + if test no = "$hard_links"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag_FC= + always_export_symbols_FC=no + archive_cmds_FC= + archive_expsym_cmds_FC= + compiler_needs_object_FC=no + enable_shared_with_static_runtimes_FC=no + export_dynamic_flag_spec_FC= + export_symbols_cmds_FC='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic_FC=no + hardcode_direct_FC=no + hardcode_direct_absolute_FC=no + hardcode_libdir_flag_spec_FC= + hardcode_libdir_separator_FC= + hardcode_minus_L_FC=no + hardcode_shlibpath_var_FC=unsupported + inherit_rpath_FC=no + link_all_deplibs_FC=unknown + module_cmds_FC= + module_expsym_cmds_FC= + old_archive_from_new_cmds_FC= + old_archive_from_expsyms_cmds_FC= + thread_safe_flag_spec_FC= + whole_archive_flag_spec_FC= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_FC= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms_FC='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_FC=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_FC='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_FC='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_FC=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_FC= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs_FC=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_FC='' + ;; + m68k) + archive_cmds_FC='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_FC='-L$libdir' + hardcode_minus_L_FC=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_FC=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_FC='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_FC=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, FC) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_FC='-L$libdir' + export_dynamic_flag_spec_FC='$wl--export-all-symbols' + allow_undefined_flag_FC=unsupported + always_export_symbols_FC=no + enable_shared_with_static_runtimes_FC=yes + export_symbols_cmds_FC='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_FC='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_FC='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_FC=no + fi + ;; + + haiku*) + archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_FC=yes + ;; + + os2*) + hardcode_libdir_flag_spec_FC='-L$libdir' + hardcode_minus_L_FC=yes + allow_undefined_flag_FC=unsupported + shrext_cmds=.dll + archive_cmds_FC='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_FC='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_FC='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_FC=yes + ;; + + interix[3-9]*) + hardcode_direct_FC=no + hardcode_shlibpath_var_FC=no + hardcode_libdir_flag_spec_FC='$wl-rpath,$libdir' + export_dynamic_flag_spec_FC='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_FC='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_FC='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec_FC='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec_FC= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec_FC='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_FC=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec_FC='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_FC=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds_FC='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_FC='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec_FC='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec_FC='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec_FC='$wl-rpath $wl$libdir' + archive_cmds_FC='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_FC='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs_FC=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_FC='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs_FC=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_FC=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_FC=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_FC='$wl-rpath $wl$libdir' + archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_FC=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_FC='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_FC=yes + hardcode_shlibpath_var_FC=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_FC=no + fi + ;; + esac + + if test no = "$ld_shlibs_FC"; then + runpath_var= + hardcode_libdir_flag_spec_FC= + export_dynamic_flag_spec_FC= + whole_archive_flag_spec_FC= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_FC=unsupported + always_export_symbols_FC=yes + archive_expsym_cmds_FC='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_FC=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_FC=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_FC='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_FC='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_FC='' + hardcode_direct_FC=yes + hardcode_direct_absolute_FC=yes + hardcode_libdir_separator_FC=':' + link_all_deplibs_FC=yes + file_list_spec_FC='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_FC=no + hardcode_direct_absolute_FC=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_FC=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_FC=yes + hardcode_libdir_flag_spec_FC='-L$libdir' + hardcode_libdir_separator_FC= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_FC='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_FC=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_FC='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath__FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +if ac_fn_fc_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__FC=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__FC"; then + lt_cv_aix_libpath__FC=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__FC"; then + lt_cv_aix_libpath__FC=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__FC +fi + + hardcode_libdir_flag_spec_FC='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_FC='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_FC='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_FC="-z nodefs" + archive_expsym_cmds_FC="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath__FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +if ac_fn_fc_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__FC=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__FC"; then + lt_cv_aix_libpath__FC=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__FC"; then + lt_cv_aix_libpath__FC=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__FC +fi + + hardcode_libdir_flag_spec_FC='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_FC=' $wl-bernotok' + allow_undefined_flag_FC=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_FC='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_FC='$convenience' + fi + archive_cmds_need_lc_FC=yes + archive_expsym_cmds_FC='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_FC="$archive_expsym_cmds_FC"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_FC="$archive_expsym_cmds_FC"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_FC="$archive_expsym_cmds_FC"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_FC="$archive_expsym_cmds_FC"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_FC='' + ;; + m68k) + archive_cmds_FC='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_FC='-L$libdir' + hardcode_minus_L_FC=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec_FC=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++ or Intel C++/Fortran Compiler. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl* | icl*| ifort*) + # Native MSVC or ICC or IFORT + hardcode_libdir_flag_spec_FC=' ' + allow_undefined_flag_FC=unsupported + always_export_symbols_FC=yes + file_list_spec_FC='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_FC='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_FC='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, FC)='true' + enable_shared_with_static_runtimes_FC=yes + exclude_expsyms_FC='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds_FC='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds_FC='chmod 644 $oldlib' + postlink_cmds_FC='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC and ICC and IFORT wrapper + hardcode_libdir_flag_spec_FC=' ' + allow_undefined_flag_FC=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_FC='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds_FC='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_FC='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes_FC=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc_FC=no + hardcode_direct_FC=no + hardcode_automatic_FC=yes + hardcode_shlibpath_var_FC=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_FC='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + compiler_needs_object_FC=yes + else + whole_archive_flag_spec_FC='' + fi + link_all_deplibs_FC=yes + allow_undefined_flag_FC=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_FC="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_FC="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs_FC=no + fi + + ;; + + dgux*) + archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_FC='-L$libdir' + hardcode_shlibpath_var_FC=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_FC='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_FC='-R$libdir' + hardcode_direct_FC=yes + hardcode_shlibpath_var_FC=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds_FC='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_FC=yes + hardcode_minus_L_FC=yes + hardcode_shlibpath_var_FC=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds_FC='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_FC='-R$libdir' + hardcode_direct_FC=yes + hardcode_shlibpath_var_FC=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds_FC='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds_FC='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_FC='$wl+b $wl$libdir' + hardcode_libdir_separator_FC=: + hardcode_direct_FC=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_FC=yes + export_dynamic_flag_spec_FC='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds_FC='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_FC='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_FC='$wl+b $wl$libdir' + hardcode_libdir_separator_FC=: + hardcode_direct_FC=yes + hardcode_direct_absolute_FC=yes + export_dynamic_flag_spec_FC='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_FC=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_FC='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_FC='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_FC='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_FC='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_FC='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_FC='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_FC='$wl+b $wl$libdir' + hardcode_libdir_separator_FC=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_FC=no + hardcode_shlibpath_var_FC=no + ;; + *) + hardcode_direct_FC=yes + hardcode_direct_absolute_FC=yes + export_dynamic_flag_spec_FC='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_FC=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if test ${lt_cv_irix_exported_symbol+y} +then : + printf %s "(cached) " >&6 +else $as_nop + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat > conftest.$ac_ext <<_ACEOF + + subroutine foo + end +_ACEOF +if ac_fn_fc_try_link "$LINENO" +then : + lt_cv_irix_exported_symbol=yes +else $as_nop + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + else + archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc_FC='no' + hardcode_libdir_flag_spec_FC='$wl-rpath $wl$libdir' + hardcode_libdir_separator_FC=: + inherit_rpath_FC=yes + link_all_deplibs_FC=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs_FC=yes + archive_cmds_FC='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_FC='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_FC='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_FC='-R$libdir' + hardcode_direct_FC=yes + hardcode_shlibpath_var_FC=no + ;; + + newsos6) + archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_FC=yes + hardcode_libdir_flag_spec_FC='$wl-rpath $wl$libdir' + hardcode_libdir_separator_FC=: + hardcode_shlibpath_var_FC=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_FC=yes + hardcode_shlibpath_var_FC=no + hardcode_direct_absolute_FC=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds_FC='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_FC='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_FC='$wl-rpath,$libdir' + export_dynamic_flag_spec_FC='$wl-E' + else + archive_cmds_FC='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_FC='$wl-rpath,$libdir' + fi + else + ld_shlibs_FC=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec_FC='-L$libdir' + hardcode_minus_L_FC=yes + allow_undefined_flag_FC=unsupported + shrext_cmds=.dll + archive_cmds_FC='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_FC='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_FC='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_FC=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag_FC=' $wl-expect_unresolved $wl\*' + archive_cmds_FC='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag_FC=' -expect_unresolved \*' + archive_cmds_FC='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc_FC='no' + hardcode_libdir_flag_spec_FC='$wl-rpath $wl$libdir' + hardcode_libdir_separator_FC=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag_FC=' $wl-expect_unresolved $wl\*' + archive_cmds_FC='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_FC='$wl-rpath $wl$libdir' + else + allow_undefined_flag_FC=' -expect_unresolved \*' + archive_cmds_FC='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_FC='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_FC='-rpath $libdir' + fi + archive_cmds_need_lc_FC='no' + hardcode_libdir_separator_FC=: + ;; + + solaris*) + no_undefined_flag_FC=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds_FC='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_FC='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds_FC='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_FC='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds_FC='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_FC='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec_FC='-R$libdir' + hardcode_shlibpath_var_FC=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec_FC='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec_FC='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs_FC=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_FC='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_FC='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_FC='-L$libdir' + hardcode_direct_FC=yes + hardcode_minus_L_FC=yes + hardcode_shlibpath_var_FC=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_FC=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_FC='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_FC='$CC -r -o $output$reload_objs' + hardcode_direct_FC=no + ;; + motorola) + archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_FC=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_FC=no + ;; + + sysv4.3*) + archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_FC=no + export_dynamic_flag_spec_FC='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_FC=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_FC=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_FC='$wl-z,text' + archive_cmds_need_lc_FC=no + hardcode_shlibpath_var_FC=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds_FC='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_FC='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_FC='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_FC='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_FC='$wl-z,text' + allow_undefined_flag_FC='$wl-z,nodefs' + archive_cmds_need_lc_FC=no + hardcode_shlibpath_var_FC=no + hardcode_libdir_flag_spec_FC='$wl-R,$libdir' + hardcode_libdir_separator_FC=':' + link_all_deplibs_FC=yes + export_dynamic_flag_spec_FC='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds_FC='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_FC='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_FC='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_FC='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_FC='-L$libdir' + hardcode_shlibpath_var_FC=no + ;; + + *) + ld_shlibs_FC=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec_FC='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_FC" >&5 +printf "%s\n" "$ld_shlibs_FC" >&6; } +test no = "$ld_shlibs_FC" && can_build_shared=no + +with_gnu_ld_FC=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_FC" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_FC=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_FC in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +printf %s "checking whether -lc should be explicitly linked in... " >&6; } +if test ${lt_cv_archive_cmds_need_lc_FC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_FC + pic_flag=$lt_prog_compiler_pic_FC + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_FC + allow_undefined_flag_FC= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_FC 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_FC 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_FC=no + else + lt_cv_archive_cmds_need_lc_FC=yes + fi + allow_undefined_flag_FC=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_FC" >&5 +printf "%s\n" "$lt_cv_archive_cmds_need_lc_FC" >&6; } + archive_cmds_need_lc_FC=$lt_cv_archive_cmds_need_lc_FC + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +printf %s "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl* | *,icl* | *,ifort*) + # Native MSVC or ICC or IFORT + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_FC='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if test ${lt_cv_shlibpath_overrides_runpath+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_FC\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_FC\"" + cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +if ac_fn_fc_try_link "$LINENO" +then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null +then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +printf %s "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_FC= +if test -n "$hardcode_libdir_flag_spec_FC" || + test -n "$runpath_var_FC" || + test yes = "$hardcode_automatic_FC"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_FC" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, FC)" && + test no != "$hardcode_minus_L_FC"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_FC=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_FC=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_FC=unsupported +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_FC" >&5 +printf "%s\n" "$hardcode_action_FC" >&6; } + +if test relink = "$hardcode_action_FC" || + test yes = "$inherit_rpath_FC"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + case "$am_cv_ar_interface" in + lib ) + ac_config_commands="$ac_config_commands libtoolclpatch" + + ;; + * ) + case $build in + *-mingw* ) + ac_config_commands="$ac_config_commands libtoolmingwpatch" + + ;; + esac + ;; + esac + + + + LT_LDFLAGS="$LT_LDFLAGS -version-number 3:0:3" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: libtool version info: -version-number 3:0:3" >&5 +printf "%s\n" "$as_me: libtool version info: -version-number 3:0:3" >&6;} + + + LT_LDFLAGS="$LT_LDFLAGS -no-undefined" + + if test "$enable_shared" = no; then + COIN_STATIC_BUILD_TRUE= + COIN_STATIC_BUILD_FALSE='#' +else + COIN_STATIC_BUILD_TRUE='#' + COIN_STATIC_BUILD_FALSE= +fi + + + +# Figure out name mangling that Fortran objects will have and translate +# them to what MUMPS wants, this also includes AC_FC_LIBRARY_LDFLAGS +ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to get verbose linking output from $FC" >&5 +printf %s "checking how to get verbose linking output from $FC... " >&6; } +if test ${ac_cv_prog_fc_v+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +if ac_fn_fc_try_compile "$LINENO" +then : + ac_cv_prog_fc_v= +# Try some options frequently used verbose output +for ac_verb in -v -verbose --verbose -V -\#\#\#; do + cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF + +# Compile and link our simple test program by passing a flag (argument +# 1 to this macro) to the Fortran compiler in order to get +# "verbose" output that we can then parse for the Fortran linker +# flags. +ac_save_FCFLAGS=$FCFLAGS +FCFLAGS="$FCFLAGS $ac_verb" +eval "set x $ac_link" +shift +printf "%s\n" "$as_me:${as_lineno-$LINENO}: $*" >&5 +# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH, +# LIBRARY_PATH; skip all such settings. +ac_fc_v_output=`eval $ac_link 5>&1 2>&1 | + sed '/^Driving:/d; /^Configured with:/d; + '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"` +printf "%s\n" "$ac_fc_v_output" >&5 +FCFLAGS=$ac_save_FCFLAGS + +rm -rf conftest* + +# On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where +# /foo, /bar, and /baz are search directories for the Fortran linker. +# Here, we change these into -L/foo -L/bar -L/baz (and put it first): +ac_fc_v_output="`echo $ac_fc_v_output | + grep 'LPATH is:' | + sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_fc_v_output" + +# FIXME: we keep getting bitten by quoted arguments; a more general fix +# that detects unbalanced quotes in FLIBS should be implemented +# and (ugh) tested at some point. +case $ac_fc_v_output in + # With xlf replace commas with spaces, + # and remove "-link" and closing parenthesis. + *xlfentry*) + ac_fc_v_output=`echo $ac_fc_v_output | + sed ' + s/,/ /g + s/ -link / /g + s/) *$// + ' + ` ;; + + # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted + # $LIBS confuse us, and the libraries appear later in the output anyway). + *mGLOB_options_string*) + ac_fc_v_output=`echo $ac_fc_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;; + + # Portland Group compiler has singly- or doubly-quoted -cmdline argument + # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4. + # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2". + *-cmdline\ * | *-ignore\ * | *-def\ *) + ac_fc_v_output=`echo $ac_fc_v_output | sed "\ + s/-cmdline *'[^']*'/ /g; s/-cmdline *\"[^\"]*\"/ /g + s/-ignore *'[^']*'/ /g; s/-ignore *\"[^\"]*\"/ /g + s/-def *'[^']*'/ /g; s/-def *\"[^\"]*\"/ /g"` ;; + + # If we are using fort77 (the f2c wrapper) then filter output and delete quotes. + *fort77*f2c*gcc*) + ac_fc_v_output=`echo "$ac_fc_v_output" | sed -n ' + /:[ ]\+Running[ ]\{1,\}"gcc"/{ + /"-c"/d + /[.]c"*/d + s/^.*"gcc"/"gcc"/ + s/"//gp + }'` ;; + + # If we are using Cray Fortran then delete quotes. + *cft90*) + ac_fc_v_output=`echo $ac_fc_v_output | sed 's/"//g'` ;; +esac + + + # look for -l* and *.a constructs in the output + for ac_arg in $ac_fc_v_output; do + case $ac_arg in + [\\/]*.a | ?:[\\/]*.a | -[lLRu]*) + ac_cv_prog_fc_v=$ac_verb + break 2 ;; + esac + done +done +if test -z "$ac_cv_prog_fc_v"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine how to obtain linking information from $FC" >&5 +printf "%s\n" "$as_me: WARNING: cannot determine how to obtain linking information from $FC" >&2;} +fi +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: compilation failed" >&5 +printf "%s\n" "$as_me: WARNING: compilation failed" >&2;} +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_fc_v" >&5 +printf "%s\n" "$ac_cv_prog_fc_v" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Fortran libraries of $FC" >&5 +printf %s "checking for Fortran libraries of $FC... " >&6; } +if test ${ac_cv_fc_libs+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "x$FCLIBS" != "x"; then + ac_cv_fc_libs="$FCLIBS" # Let the user override the test. +else + +cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF + +# Compile and link our simple test program by passing a flag (argument +# 1 to this macro) to the Fortran compiler in order to get +# "verbose" output that we can then parse for the Fortran linker +# flags. +ac_save_FCFLAGS=$FCFLAGS +FCFLAGS="$FCFLAGS $ac_cv_prog_fc_v" +eval "set x $ac_link" +shift +printf "%s\n" "$as_me:${as_lineno-$LINENO}: $*" >&5 +# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH, +# LIBRARY_PATH; skip all such settings. +ac_fc_v_output=`eval $ac_link 5>&1 2>&1 | + sed '/^Driving:/d; /^Configured with:/d; + '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"` +printf "%s\n" "$ac_fc_v_output" >&5 +FCFLAGS=$ac_save_FCFLAGS + +rm -rf conftest* + +# On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where +# /foo, /bar, and /baz are search directories for the Fortran linker. +# Here, we change these into -L/foo -L/bar -L/baz (and put it first): +ac_fc_v_output="`echo $ac_fc_v_output | + grep 'LPATH is:' | + sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_fc_v_output" + +# FIXME: we keep getting bitten by quoted arguments; a more general fix +# that detects unbalanced quotes in FLIBS should be implemented +# and (ugh) tested at some point. +case $ac_fc_v_output in + # With xlf replace commas with spaces, + # and remove "-link" and closing parenthesis. + *xlfentry*) + ac_fc_v_output=`echo $ac_fc_v_output | + sed ' + s/,/ /g + s/ -link / /g + s/) *$// + ' + ` ;; + + # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted + # $LIBS confuse us, and the libraries appear later in the output anyway). + *mGLOB_options_string*) + ac_fc_v_output=`echo $ac_fc_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;; + + # Portland Group compiler has singly- or doubly-quoted -cmdline argument + # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4. + # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2". + *-cmdline\ * | *-ignore\ * | *-def\ *) + ac_fc_v_output=`echo $ac_fc_v_output | sed "\ + s/-cmdline *'[^']*'/ /g; s/-cmdline *\"[^\"]*\"/ /g + s/-ignore *'[^']*'/ /g; s/-ignore *\"[^\"]*\"/ /g + s/-def *'[^']*'/ /g; s/-def *\"[^\"]*\"/ /g"` ;; + + # If we are using fort77 (the f2c wrapper) then filter output and delete quotes. + *fort77*f2c*gcc*) + ac_fc_v_output=`echo "$ac_fc_v_output" | sed -n ' + /:[ ]\+Running[ ]\{1,\}"gcc"/{ + /"-c"/d + /[.]c"*/d + s/^.*"gcc"/"gcc"/ + s/"//gp + }'` ;; + + # If we are using Cray Fortran then delete quotes. + *cft90*) + ac_fc_v_output=`echo $ac_fc_v_output | sed 's/"//g'` ;; +esac + + + +ac_cv_fc_libs= + +# Save positional arguments (if any) +ac_save_positional="$@" + +set X $ac_fc_v_output +while test $# != 1; do + shift + ac_arg=$1 + case $ac_arg in + [\\/]*.a | ?:[\\/]*.a) + ac_exists=false + for ac_i in $ac_cv_fc_libs; do + if test x"$ac_arg" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue +then : + +else $as_nop + ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg" +fi + ;; + -bI:*) + ac_exists=false + for ac_i in $ac_cv_fc_libs; do + if test x"$ac_arg" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue +then : + +else $as_nop + if test "$ac_compiler_gnu" = yes; then + for ac_link_opt in $ac_arg; do + ac_cv_fc_libs="$ac_cv_fc_libs -Xlinker $ac_link_opt" + done +else + ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg" +fi +fi + ;; + # Ignore these flags. + -lang* | -lcrt*.o | -lc | -lgcc* | -lSystem | -libmil | -little \ + |-LANG:=* | -LIST:* | -LNO:* | -link) + ;; + -lkernel32) + # Ignore this library only on Windows-like systems. + case $host_os in + cygwin* | msys* ) ;; + *) + ac_exists=false + for ac_i in $ac_cv_fc_libs; do + if test x"$ac_arg" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue +then : + +else $as_nop + ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg" +fi + ;; + esac + ;; + -[LRuYz]) + # These flags, when seen by themselves, take an argument. + # We remove the space between option and argument and re-iterate + # unless we find an empty arg or a new option (starting with -) + case $2 in + "" | -*);; + *) + ac_arg="$ac_arg$2" + shift; shift + set X $ac_arg "$@" + ;; + esac + ;; + -YP,*) + for ac_j in `printf "%s\n" "$ac_arg" | sed -e 's/-YP,/-L/;s/:/ -L/g'`; do + ac_exists=false + for ac_i in $ac_cv_fc_libs; do + if test x"$ac_j" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue +then : + +else $as_nop + ac_arg="$ac_arg $ac_j" + ac_cv_fc_libs="$ac_cv_fc_libs $ac_j" +fi + done + ;; + -[lLR]*) + ac_exists=false + for ac_i in $ac_cv_fc_libs; do + if test x"$ac_arg" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue +then : + +else $as_nop + ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg" +fi + ;; + -zallextract*| -zdefaultextract) + ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg" + ;; + -mllvm) ${2+shift};; # Defend against 'clang -mllvm -loopopt=0'. + # Ignore everything else. + esac +done +# restore positional arguments +set X $ac_save_positional; shift + +# We only consider "LD_RUN_PATH" on Solaris systems. If this is seen, +# then we insist that the "run path" must be an absolute path (i.e. it +# must begin with a "/"). +case `(uname -sr) 2>/dev/null` in + "SunOS 5"*) + ac_ld_run_path=`printf "%s\n" "$ac_fc_v_output" | + sed -n 's,^.*LD_RUN_PATH *= *\(/[^ ]*\).*$,-R\1,p'` + test "x$ac_ld_run_path" != x && + if test "$ac_compiler_gnu" = yes; then + for ac_link_opt in $ac_ld_run_path; do + ac_cv_fc_libs="$ac_cv_fc_libs -Xlinker $ac_link_opt" + done +else + ac_cv_fc_libs="$ac_cv_fc_libs $ac_ld_run_path" +fi + ;; +esac +fi # test "x$[]_AC_LANG_PREFIX[]LIBS" = "x" + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_libs" >&5 +printf "%s\n" "$ac_cv_fc_libs" >&6; } +FCLIBS="$ac_cv_fc_libs" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dummy main to link with Fortran libraries" >&5 +printf %s "checking for dummy main to link with Fortran libraries... " >&6; } +if test ${ac_cv_fc_dummy_main+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_fc_dm_save_LIBS=$LIBS + LIBS="$LIBS $FCLIBS" + ac_fortran_dm_var=FC_DUMMY_MAIN + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + # First, try linking without a dummy main: + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_fortran_dummy_main=none +else $as_nop + ac_cv_fortran_dummy_main=unknown +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_cv_fortran_dummy_main = unknown; then + for ac_func in MAIN__ MAIN_ __main MAIN _MAIN __MAIN main_ main__ _main; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define $ac_fortran_dm_var $ac_func +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_fortran_dummy_main=$ac_func; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + done + fi + ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu + ac_cv_fc_dummy_main=$ac_cv_fortran_dummy_main + rm -rf conftest* + LIBS=$ac_fc_dm_save_LIBS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_dummy_main" >&5 +printf "%s\n" "$ac_cv_fc_dummy_main" >&6; } +FC_DUMMY_MAIN=$ac_cv_fc_dummy_main +if test "$FC_DUMMY_MAIN" != unknown +then : + if test $FC_DUMMY_MAIN != none; then + +printf "%s\n" "#define FC_DUMMY_MAIN $FC_DUMMY_MAIN" >>confdefs.h + + if test "x$ac_cv_fc_dummy_main" = "x$ac_cv_f77_dummy_main"; then + +printf "%s\n" "#define FC_DUMMY_MAIN_EQ_F77 1" >>confdefs.h + + fi +fi +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "linking to Fortran libraries from C fails +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Fortran name-mangling scheme" >&5 +printf %s "checking for Fortran name-mangling scheme... " >&6; } +if test ${ac_cv_fc_mangling+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat > conftest.$ac_ext <<_ACEOF + subroutine foobar() + return + end + subroutine foo_bar() + return + end +_ACEOF +if ac_fn_fc_try_compile "$LINENO" +then : + mv conftest.$ac_objext cfortran_test.$ac_objext + + ac_save_LIBS=$LIBS + LIBS="cfortran_test.$ac_objext $LIBS $FCLIBS" + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + ac_success=no + for ac_foobar in foobar FOOBAR; do + for ac_underscore in "" "_"; do + ac_func="$ac_foobar$ac_underscore" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_func (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_success=yes; break 2 +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + done + done + ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu + + if test "$ac_success" = "yes"; then + case $ac_foobar in + foobar) + ac_case=lower + ac_foo_bar=foo_bar + ;; + FOOBAR) + ac_case=upper + ac_foo_bar=FOO_BAR + ;; + esac + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + ac_success_extra=no + for ac_extra in "" "_"; do + ac_func="$ac_foo_bar$ac_underscore$ac_extra" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_func (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_success_extra=yes; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + done + ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu + + if test "$ac_success_extra" = "yes"; then + ac_cv_fc_mangling="$ac_case case" + if test -z "$ac_underscore"; then + ac_cv_fc_mangling="$ac_cv_fc_mangling, no underscore" + else + ac_cv_fc_mangling="$ac_cv_fc_mangling, underscore" + fi + if test -z "$ac_extra"; then + ac_cv_fc_mangling="$ac_cv_fc_mangling, no extra underscore" + else + ac_cv_fc_mangling="$ac_cv_fc_mangling, extra underscore" + fi + else + ac_cv_fc_mangling="unknown" + fi + else + ac_cv_fc_mangling="unknown" + fi + + LIBS=$ac_save_LIBS + rm -rf conftest* + rm -f cfortran_test* +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compile a simple Fortran program +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_mangling" >&5 +printf "%s\n" "$ac_cv_fc_mangling" >&6; } + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu +case $ac_cv_fc_mangling in + "lower case, no underscore, no extra underscore") + printf "%s\n" "#define FC_FUNC(name,NAME) name" >>confdefs.h + + printf "%s\n" "#define FC_FUNC_(name,NAME) name" >>confdefs.h + ;; + "lower case, no underscore, extra underscore") + printf "%s\n" "#define FC_FUNC(name,NAME) name" >>confdefs.h + + printf "%s\n" "#define FC_FUNC_(name,NAME) name ## _" >>confdefs.h + ;; + "lower case, underscore, no extra underscore") + printf "%s\n" "#define FC_FUNC(name,NAME) name ## _" >>confdefs.h + + printf "%s\n" "#define FC_FUNC_(name,NAME) name ## _" >>confdefs.h + ;; + "lower case, underscore, extra underscore") + printf "%s\n" "#define FC_FUNC(name,NAME) name ## _" >>confdefs.h + + printf "%s\n" "#define FC_FUNC_(name,NAME) name ## __" >>confdefs.h + ;; + "upper case, no underscore, no extra underscore") + printf "%s\n" "#define FC_FUNC(name,NAME) NAME" >>confdefs.h + + printf "%s\n" "#define FC_FUNC_(name,NAME) NAME" >>confdefs.h + ;; + "upper case, no underscore, extra underscore") + printf "%s\n" "#define FC_FUNC(name,NAME) NAME" >>confdefs.h + + printf "%s\n" "#define FC_FUNC_(name,NAME) NAME ## _" >>confdefs.h + ;; + "upper case, underscore, no extra underscore") + printf "%s\n" "#define FC_FUNC(name,NAME) NAME ## _" >>confdefs.h + + printf "%s\n" "#define FC_FUNC_(name,NAME) NAME ## _" >>confdefs.h + ;; + "upper case, underscore, extra underscore") + printf "%s\n" "#define FC_FUNC(name,NAME) NAME ## _" >>confdefs.h + + printf "%s\n" "#define FC_FUNC_(name,NAME) NAME ## __" >>confdefs.h + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unknown Fortran name-mangling scheme" >&5 +printf "%s\n" "$as_me: WARNING: unknown Fortran name-mangling scheme" >&2;} + ;; +esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +case "$ac_cv_fc_mangling" in + "lower case, no underscore, no extra underscore" ) ;; + "lower case, underscore, no extra underscore" ) MY_DEFS="-DAdd_" ;; + "lower case, no underscore, extra underscore" ) MY_DEFS="-DAdd_" ;; + "lower case, underscore, extra underscore" ) MY_DEFS="-DAdd__" ;; + "upper case, no underscore, no extra underscore" ) MY_DEFS="-DUPPER" ;; + "upper case, no underscore, extra underscore" ) MY_DEFS="-DUPPER" ;; + "upper case, underscore, no extra underscore" ) MY_DEFS="-DUPPER" ;; + "upper case, underscore, extra underscore" ) MY_DEFS="-DUPPER" ;; +esac + + +# Add FCLIBS to MUMPS_LFLAGS, so that they get into the .pc files section for static builds +MUMPS_LFLAGS="$MUMPS_LFLAGS $FCLIBS" + +# check which floating-point precision to build + +# Check whether --with-precision was given. +if test ${with_precision+y} +then : + withval=$with_precision; precision=$withval + case "$precision" in + single | double | all ) ;; + *) as_fn_error $? "unsupported value $precision for option --with-precision" "$LINENO" 5 ;; + esac +else $as_nop + precision=double +fi + + if test "$precision" = single || test "$precision" = all; then + MUMPS_SINGLE_TRUE= + MUMPS_SINGLE_FALSE='#' +else + MUMPS_SINGLE_TRUE='#' + MUMPS_SINGLE_FALSE= +fi + + if test "$precision" = double || test "$precision" = all; then + MUMPS_DOUBLE_TRUE= + MUMPS_DOUBLE_FALSE='#' +else + MUMPS_DOUBLE_TRUE='#' + MUMPS_DOUBLE_FALSE= +fi + + +# check which integer size to build + +# Check whether --with-intsize was given. +if test ${with_intsize+y} +then : + withval=$with_intsize; intsize=$withval +else $as_nop + intsize=32 +fi + +case "$intsize" in + 32 ) +printf "%s\n" "#define MUMPS_INTSIZE32 /**/" >>confdefs.h + ;; + 64 ) +printf "%s\n" "#define MUMPS_INTSIZE64 /**/" >>confdefs.h + ;; + *) as_fn_error $? "unsupported value $intsize for option --with-intsize" "$LINENO" 5 ;; +esac + +# Mumps can make use of pthreads +# check for pthread.h header file and library +# Check whether --enable-pthread-mumps was given. +if test ${enable_pthread_mumps+y} +then : + enableval=$enable_pthread_mumps; enable_pthread_mumps=$enableval +else $as_nop + enable_pthread_mumps=yes +fi + +if test $enable_pthread_mumps = yes ; then + ac_fn_c_check_header_compile "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_h" = xyes +then : + +else $as_nop + enable_pthread_mumps=no +fi + +fi +if test $enable_pthread_mumps = yes ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +printf %s "checking for pthread_create in -lpthread... " >&6; } +if test ${ac_cv_lib_pthread_pthread_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char pthread_create (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_pthread_pthread_create=yes +else $as_nop + ac_cv_lib_pthread_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = xyes +then : + MUMPS_LFLAGS="$MUMPS_LFLAGS -lpthread" +else $as_nop + enable_pthread_mumps=no +fi + +fi +if test $enable_pthread_mumps = no ; then + MY_DEFS="$MY_DEFS -DWITHOUT_PTHREAD=1" +fi + +# Mumps can use OpenMP +# but if single threaded, then it (5.2.1) seems to become slower within Ipopt, so disable by default +if test -z "$enable_openmp" ; then + enable_openmp=no +fi +ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu + +if test -e penmp || test -e mp; then + as_fn_error $? "AC_OPENMP clobbers files named 'mp' and 'penmp'. Aborting configure because one of these files already exists." "$LINENO" 5 +fi +# Check whether --enable-openmp was given. +if test ${enable_openmp+y} +then : + enableval=$enable_openmp; +fi + + OPENMP_FCFLAGS= + if test "$enable_openmp" != no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $FC option to support OpenMP" >&5 +printf %s "checking for $FC option to support OpenMP... " >&6; } +if test ${ac_cv_prog_fc_openmp+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_fc_openmp='not found' + for ac_option in '' -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp -homp \ + -Popenmp --openmp; do + + ac_save_FCFLAGS=$FCFLAGS + FCFLAGS="$FCFLAGS $ac_option" + cat > conftest.$ac_ext <<_ACEOF + + program main + implicit none +!$ integer tid + tid = 42 + call omp_set_num_threads(2) + end + +_ACEOF +if ac_fn_fc_try_compile "$LINENO" +then : + cat > conftest.$ac_ext <<_ACEOF + + program main + implicit none +!$ integer tid + tid = 42 + call omp_set_num_threads(2) + end + +_ACEOF +if ac_fn_fc_try_link "$LINENO" +then : + ac_cv_prog_fc_openmp=$ac_option +else $as_nop + ac_cv_prog_fc_openmp='unsupported' +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + FCFLAGS=$ac_save_FCFLAGS + + if test "$ac_cv_prog_fc_openmp" != 'not found'; then + break + fi + done + if test "$ac_cv_prog_fc_openmp" = 'not found'; then + ac_cv_prog_fc_openmp='unsupported' + elif test "$ac_cv_prog_fc_openmp" = ''; then + ac_cv_prog_fc_openmp='none needed' + fi + rm -f penmp mp +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_fc_openmp" >&5 +printf "%s\n" "$ac_cv_prog_fc_openmp" >&6; } + if test "$ac_cv_prog_fc_openmp" != 'unsupported' && \ + test "$ac_cv_prog_fc_openmp" != 'none needed'; then + OPENMP_FCFLAGS="$ac_cv_prog_fc_openmp" + fi + fi + + +FCFLAGS="$FCFLAGS $OPENMP_FCFLAGS" +MUMPS_LFLAGS="$MUMPS_LFLAGS $OPENMP_FCFLAGS" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + if test -z "$PKG_CONFIG" ; then + if test -n "$ac_tool_prefix"; then + for ac_prog in pkgconf pkg-config + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$PKG_CONFIG"; then + ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PKG_CONFIG="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PKG_CONFIG=$ac_cv_prog_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$PKG_CONFIG" && break + done +fi +if test -z "$PKG_CONFIG"; then + ac_ct_PKG_CONFIG=$PKG_CONFIG + for ac_prog in pkgconf pkg-config +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_PKG_CONFIG"; then + ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_PKG_CONFIG="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG +if test -n "$ac_ct_PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 +printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_PKG_CONFIG" && break +done + + if test "x$ac_ct_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_ct_PKG_CONFIG + fi +fi + + fi + if test -n "$PKG_CONFIG" ; then + pkg_min_version=0.16.0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking $PKG_CONFIG is at least version $pkg_min_version" >&5 +printf %s "checking $PKG_CONFIG is at least version $pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $pkg_min_version ; then + pkg_version=`$PKG_CONFIG --version` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes: $pkg_version" >&5 +printf "%s\n" "yes: $pkg_version" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + PKG_CONFIG="" + fi + fi + + if test -n "$PKG_CONFIG" && + $PKG_CONFIG --atleast-pkgconfig-version 0.20 ; then + pkg_short_errors=" --short-errors " + else + pkg_short_errors="" + fi + + pkg_static= + if test -n "$PKG_CONFIG" ; then + case "$LDFLAGS" in "-static" | "* -static*" ) pkg_static=--static ;; esac + fi + + if test -n "$PKG_CONFIG"; then + COIN_HAS_PKGCONFIG_TRUE= + COIN_HAS_PKGCONFIG_FALSE='#' +else + COIN_HAS_PKGCONFIG_TRUE='#' + COIN_HAS_PKGCONFIG_FALSE= +fi + + + + COIN_PKG_CONFIG_PATH="${PKG_CONFIG_PATH}" + + + COIN_PKG_CONFIG_PATH="${expanded_libdir}/pkgconfig:${COIN_PKG_CONFIG_PATH}" + if test -n "$PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $PKG_CONFIG path is \"$COIN_PKG_CONFIG_PATH\"" >&5 +printf "%s\n" "$as_me: $PKG_CONFIG path is \"$COIN_PKG_CONFIG_PATH\"" >&6;} + fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LAPACK" >&5 +printf %s "checking for LAPACK... " >&6; } + + + + + + + + + +# Check whether --with-lapack was given. +if test ${with_lapack+y} +then : + withval=$with_lapack; +fi + + + +# Check whether --with-lapack-lflags was given. +if test ${with_lapack_lflags+y} +then : + withval=$with_lapack_lflags; +fi + + + + + + + + coin_has_lapack=no + lapack_keep_looking=yes + + if test "$with_lapack" != "no" ; then + if test "$with_lapack" != "yes" && test -z "$with_lapack_lflags" ; then + with_lapack_lflags="$with_lapack" + fi + if test -n "$with_lapack_lflags" ; then + + ac_save_LIBS="$LIBS" + LIBS="$with_lapack_lflags $LIBS" + + + dsyev_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dsyev + ;; + "upper case") + ac_name=DSYEV + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dsyev_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + coin_has_lapack=yes + lapack_what="user-specified ($with_lapack_lflags)" + lapack_keep_looking=no + lapack_lflags=$with_lapack_lflags + else as_fn_error $? "Cannot link to user-specified Lapack $with_lapack_lflags." "$LINENO" 5 + fi + + fi + else + lapack_keep_looking=no + lapack_what="user-specified" + fi + + + if test "$lapack_keep_looking" = yes ; then + case $build in + *-linux*) + case " int$intsize " in + *\ int64\ * ) coin_mkl="-lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lm" ;; + *) coin_mkl="-lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lm" ;; + esac + + ac_save_LIBS="$LIBS" + LIBS="$coin_mkl $LIBS" + + + dsyev_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dsyev + ;; + "upper case") + ac_name=DSYEV + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dsyev_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + coin_has_lapack=yes + lapack_lflags="$coin_mkl" + lapack_what="Intel MKL ($lapack_lflags)" + + + fi + + ;; + + *-*-solaris*) + case " int$intsize " in + *\ int64\ * ) ;; + *) + ac_save_LIBS="$LIBS" + LIBS="-lsunperf $LIBS" + + + dsyev_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dsyev + ;; + "upper case") + ac_name=DSYEV + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dsyev_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + coin_has_lapack=yes + lapack_lflags=-lsunperf + lapack_what="Sun Performance Library ($lapack_lflags)" + + + fi + ;; + esac + ;; + + *-cygwin* | *-mingw* | *-msys*) + old_IFS="$IFS" + IFS=";" + coin_mkl="" + for d in $LIB ; do + # turn $d into unix-style short path (no spaces); cannot do -us, + # so first do -ws, then -u + d=`cygpath -ws "$d"` + d=`cygpath -u "$d"` + if test "$enable_shared" = yes ; then + if test -e "$d/mkl_core_dll.lib" ; then + case " int$intsize " in + *\ int64\ * ) coin_mkl="$d/mkl_intel_ilp64_dll.lib $d/mkl_sequential_dll.lib $d/mkl_core_dll.lib" ;; + *) coin_mkl="$d/mkl_intel_lp64_dll.lib $d/mkl_sequential_dll.lib $d/mkl_core_dll.lib" ;; + esac + break + fi + else + if test -e "$d/mkl_core.lib" ; then + case " int$intsize " in + *\ int64\ * ) coin_mkl="$d/mkl_intel_ilp64.lib $d/mkl_sequential.lib $d/mkl_core.lib" ;; + *) coin_mkl="$d/mkl_intel_lp64.lib $d/mkl_sequential.lib $d/mkl_core.lib" ;; + esac + break + fi + fi + done + IFS="$old_IFS" + if test -n "$coin_mkl" ; then + + ac_save_LIBS="$LIBS" + LIBS="$coin_mkl $LIBS" + + + dsyev_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dsyev + ;; + "upper case") + ac_name=DSYEV + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dsyev_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + coin_has_lapack=yes + lapack_lflags="$coin_mkl" + lapack_what="Intel MKL ($lapack_lflags)" + + + fi + + fi + ;; + + *-darwin*) + case " int$intsize " in + *\ int64\ * ) coin_mkl="-lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lm" ;; + *) coin_mkl="-lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lm" ;; + esac + + ac_save_LIBS="$LIBS" + LIBS="$coin_mkl $LIBS" + + + dsyev_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dsyev + ;; + "upper case") + ac_name=DSYEV + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dsyev_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + coin_has_lapack=yes + lapack_lflags="$coin_mkl" + lapack_what="Intel MKL ($lapack_lflags)" + + + fi + + if test "$coin_has_lapack" = no ; then + case " int$intsize " in + *\ int64\ * ) ;; + *) + ac_save_LIBS="$LIBS" + LIBS="-framework Accelerate $LIBS" + + + dsyev_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dsyev + ;; + "upper case") + ac_name=DSYEV + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dsyev_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + coin_has_lapack=yes + lapack_lflags="-framework Accelerate" + lapack_what="Accelerate framework ($lapack_lflags)" + + + fi + + ;; + esac + fi + ;; + esac + if test "$coin_has_lapack" = yes ; then + lapack_keep_looking=no + fi + fi + + if test "$lapack_keep_looking" = yes ; then + case " int$intsize " in + *\ int64\ * ) ;; + *) + + + if test -n "$PKG_CONFIG" ; then + if PKG_CONFIG_PATH="$COIN_PKG_CONFIG_PATH" $PKG_CONFIG --exists "lapack blas" ; then + LAPACK_VERSIONS=`PKG_CONFIG_PATH="$COIN_PKG_CONFIG_PATH" $PKG_CONFIG --modversion "lapack blas" 2>/dev/null | tr '\n' ' '` + lapack_what="generic module (lapack.pc blas.pc)" + + ac_save_LIBS="$LIBS" + + + if test -n "lapack" ; then + temp_LFLAGS=`PKG_CONFIG_PATH="$COIN_PKG_CONFIG_PATH" $PKG_CONFIG --libs $pkg_static lapack` + LIBS="$temp_LFLAGS $LIBS" + fi + + + dsyev_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dsyev + ;; + "upper case") + ac_name=DSYEV + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dsyev_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + coin_has_lapack=yes + lapack_keep_looking=no + lapack_pcfiles="lapack blas" + else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: lapack.pc and blas.pc present, but could not find dsyev when trying to link with LAPACK." >&5 +printf "%s\n" "$as_me: WARNING: lapack.pc and blas.pc present, but could not find dsyev when trying to link with LAPACK." >&2;} + fi + + + else + LAPACK_PKG_ERRORS=`PKG_CONFIG_PATH="$COIN_PKG_CONFIG_PATH" $PKG_CONFIG $pkg_short_errors --errors-to-stdout --print-errors "lapack blas"` + + fi + else + as_fn_error $? "\"Cannot check for existence of module lapack without pkgconf\"" "$LINENO" 5 + fi + + ;; + esac + fi + + if test "$lapack_keep_looking" = yes ; then + case " int$intsize " in + *\ int64\ * ) coin_lapack="-llapack64 -lblas64" ;; + *) coin_lapack="-llapack -lblas" ;; + esac + + ac_save_LIBS="$LIBS" + LIBS="$coin_lapack $LIBS" + + + dsyev_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dsyev + ;; + "upper case") + ac_name=DSYEV + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dsyev_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + coin_has_lapack=yes + lapack_lflags="$coin_lapack" + lapack_what="generic library ($lapack_lflags)" + + fi + + fi + + case "$coin_has_lapack" in + yes) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $coin_has_lapack: $lapack_what" >&5 +printf "%s\n" "$coin_has_lapack: $lapack_what" >&6; } + ;; + no) + if test -n "$lapack_what" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $coin_has_lapack ($lapack_what)" >&5 +printf "%s\n" "$coin_has_lapack ($lapack_what)" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $coin_has_lapack" >&5 +printf "%s\n" "$coin_has_lapack" >&6; } + fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: CHK_LAPACK: unexpected result '$coin_has_lapack'" >&5 +printf "%s\n" "$as_me: WARNING: CHK_LAPACK: unexpected result '$coin_has_lapack'" >&2;} + ;; + esac + + if test $coin_has_lapack = yes; then + COIN_HAS_LAPACK_TRUE= + COIN_HAS_LAPACK_FALSE='#' +else + COIN_HAS_LAPACK_TRUE='#' + COIN_HAS_LAPACK_FALSE= +fi + + + if test $coin_has_lapack = yes ; then + +printf "%s\n" "#define THIRDPARTYMUMPS_HAS_LAPACK 1" >>confdefs.h + + + + + case "${dsyev_namemangling}" in + "lower case, no underscore, no extra underscore") + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC(name,NAME) name" >>confdefs.h + + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC_(name,NAME) name" >>confdefs.h + ;; + "lower case, no underscore, extra underscore") + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC(name,NAME) name" >>confdefs.h + + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC_(name,NAME) name ## _" >>confdefs.h + ;; + "lower case, underscore, no extra underscore") + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC(name,NAME) name ## _" >>confdefs.h + + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC_(name,NAME) name ## _" >>confdefs.h + ;; + "lower case, underscore, extra underscore") + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC(name,NAME) name ## _" >>confdefs.h + + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC_(name,NAME) name ## __" >>confdefs.h + ;; + "upper case, no underscore, no extra underscore") + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC(name,NAME) NAME" >>confdefs.h + + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC_(name,NAME) NAME" >>confdefs.h + ;; + "upper case, no underscore, extra underscore") + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC(name,NAME) NAME" >>confdefs.h + + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC_(name,NAME) NAME ## _" >>confdefs.h + ;; + "upper case, underscore, no extra underscore") + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC(name,NAME) NAME ## _" >>confdefs.h + + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC_(name,NAME) NAME ## _" >>confdefs.h + ;; + "upper case, underscore, extra underscore") + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC(name,NAME) NAME ## _" >>confdefs.h + + printf "%s\n" "#define THIRDPARTYMUMPS_LAPACK_FUNC_(name,NAME) NAME ## __" >>confdefs.h + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Unsupported or unknown name-mangling scheme: ${dsyev_namemangling}" >&5 +printf "%s\n" "$as_me: WARNING: Unsupported or unknown name-mangling scheme: ${dsyev_namemangling}" >&2;} + ;; + esac + + if test -n "$lapack_pcfiles" ; then + MUMPS_PCFILES="$lapack_pcfiles $MUMPS_PCFILES" + fi + MUMPS_LFLAGS="$lapack_lflags $MUMPS_LFLAGS" + + fi + +if test $coin_has_lapack != yes; then + as_fn_error $? "Required package LAPACK not found." "$LINENO" 5 +fi + +# if the BLAS library includes the GEMMT level-3 BLAS extension, it is strongly recommend to use it + + ac_save_LIBS="$LIBS" + LIBS="$lapack_lflags $LIBS" + + if test -n "$lapack_pcfiles" ; then + temp_LFLAGS=`PKG_CONFIG_PATH="$COIN_PKG_CONFIG_PATH" $PKG_CONFIG --libs $pkg_static $lapack_pcfiles` + LIBS="$temp_LFLAGS $LIBS" + fi + + + dgemmt_namemangling=unknown + + for ac_extra in "no extra underscore" "extra underscore" ; do + for ac_case in "lower case" "upper case" ; do + for ac_trail in "underscore" "no underscore" ; do + case $ac_case in + "lower case") + ac_name=dgemmt + ;; + "upper case") + ac_name=DGEMMT + ;; + esac + if test "$ac_trail" = "underscore" ; then + ac_name=${ac_name}_ + fi + if test "$ac_extra" = "extra underscore" ; then + ac_name=${ac_name}_ + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for function $ac_name in $LIBS" >&5 +printf %s "checking for function $ac_name in $LIBS... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char $ac_name (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return $ac_name (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + dgemmt_namemangling="${ac_case}, ${ac_trail}, ${ac_extra}" + ac_success=yes +else $as_nop + ac_success=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_success" >&5 +printf "%s\n" "$ac_success" >&6; } + if test $ac_success = yes ; then + break 3 + fi + done + done + done + LIBS=$ac_save_LIBS + + if test $ac_success = yes ; then + MY_FDEFS="$MY_FDEFS -DGEMMT_AVAILABLE" + + fi + + + + + + + + coin_save_LIBS="$LIBS" + LIBS= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing cos" >&5 +printf %s "checking for library containing cos... " >&6; } +if test ${ac_cv_search_cos+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char cos (); +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +return cos (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_cos=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_cos+y} +then : + break +fi +done +if test ${ac_cv_search_cos+y} +then : + +else $as_nop + ac_cv_search_cos=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_cos" >&5 +printf "%s\n" "$ac_cv_search_cos" >&6; } +ac_res=$ac_cv_search_cos +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + if test "$ac_cv_search_cos" != 'none required' ; then + METISCHECK_LFLAGS="$ac_cv_search_cos $METISCHECK_LFLAGS" + + fi +fi + + LIBS="$coin_save_LIBS" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library Metis with combined link and compile check" >&5 +printf %s "checking for library Metis with combined link and compile check... " >&6; } + + + + + + + + coin_has_metis=noInfo + if test x"$COIN_SKIP_PROJECTS" != x ; then + for pkg in `echo $COIN_SKIP_PROJECTS | tr '[:upper:]' '[:lower:]'` ; do + if test "$pkg" = "metis" ; then + coin_has_metis=skipping + fi + done + fi + + + if test "$coin_has_metis" != skipping ; then + + + + +# Check whether --with-metis was given. +if test ${with_metis+y} +then : + withval=$with_metis; +fi + + + +# Check whether --with-metis-lflags was given. +if test ${with_metis_lflags+y} +then : + withval=$with_metis_lflags; +fi + + + +# Check whether --with-metis-cflags was given. +if test ${with_metis_cflags+y} +then : + withval=$with_metis_cflags; +fi + + + + + + + + + + + metis_lflags="-lmetis "$METISCHECK_LFLAGS"" + metis_cflags="" + metis_data="" + coin_has_metis=requested + metis_userflags='no' + + + withval="$with_metis" + if test -n "$withval" ; then + case "$withval" in + no ) + coin_has_metis=skipping + metis_failmode='command line' + ;; + yes ) + coin_has_metis=requested + metis_failmode='' + ;; + * ) + coin_has_metis=requested + metis_failmode='' + metis_lflags="$withval" + metis_userflags='yes' + ;; + esac + else + if test -n "$with_metis_lflags" || + test -n "$with_metis_cflags" || + test -n "$with_metis_data" ; then + coin_has_metis=requested + metis_failmode='' + metis_userflags='yes' + fi + fi + + + if test "$coin_has_metis" != skipping ; then + withval="$with_metis_lflags" + if test -n "$withval" ; then + coin_has_metis=requested + metis_lflags="$withval" + metis_userflags='yes' + fi + + withval="$with_metis_cflags" + if test -n "$withval" ; then + coin_has_metis=requested + metis_cflags="$withval" + metis_userflags='yes' + fi + fi + + + + + + + if test $coin_has_metis != skipping ; then + ac_save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$metis_cflags" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define __STDC_WANT_IEC_60559_BFP_EXT__ + #ifdef __STDC__ + #include + #endif + #include "metis.h" + #ifndef METIS_VER_MAJOR + #define METIS_VER_MAJOR 4 + #ifdef IDXTYPE_INT + #define IDXTYPEWIDTH 32 + #else + #define IDXTYPEWIDTH 64 + #endif + #endif + #if defined(MUMPS_INTSIZE32) && defined(INT_WIDTH) && INT_WIDTH != IDXTYPEWIDTH + #error "Metis does not use int type for idx_t, but this build of MUMPS requires it" + #endif + #if defined(MUMPS_INTSIZE64) && IDXTYPEWIDTH != 64 + #error "Metis does not use 64-bit integers for idx_t, but this build of MUMPS requires it" + #endif + +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + coin_has_metis='no' + metis_failmode="header compile" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CPPFLAGS=$ac_save_CPPFLAGS + fi + + + if test "$coin_has_metis" != skipping ; then + ac_save_LIBS=$LIBS + ac_save_CPPFLAGS=$CPPFLAGS + LIBS="$metis_lflags" + CPPFLAGS="$metis_cflags" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define __STDC_WANT_IEC_60559_BFP_EXT__ + #ifdef __STDC__ + #include + #endif + #include "metis.h" + #ifndef METIS_VER_MAJOR + #define METIS_VER_MAJOR 4 + #ifdef IDXTYPE_INT + #define IDXTYPEWIDTH 32 + #else + #define IDXTYPEWIDTH 64 + #endif + #endif + #if defined(MUMPS_INTSIZE32) && defined(INT_WIDTH) && INT_WIDTH != IDXTYPEWIDTH + #error "Metis does not use int type for idx_t, but this build of MUMPS requires it" + #endif + #if defined(MUMPS_INTSIZE64) && IDXTYPEWIDTH != 64 + #error "Metis does not use 64-bit integers for idx_t, but this build of MUMPS requires it" + #endif + +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ +#if METIS_VER_MAJOR < 5 + metis_nodend((int*)0, (int*)0, (int*)0, (int*)0, (int*)0, (int*)0, (int*)0); + #else + METIS_NodeND((int*)0, (int*)0, (int*)0, (int*)0, (int*)0, (int*)0, (int*)0); + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + +else $as_nop + coin_has_metis='no' + if test -n "$metis_failmode" ; then + metis_failmode="$metis_failmode, link with header" + else + metis_failmode="link with header" + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_save_LIBS + CPPFLAGS=$ac_save_CPPFLAGS + fi + + + if test $coin_has_metis = requested ; then + coin_has_metis=yes + fi + + + # Define BUILDTOOLS_DEBUG to enable debugging output + if test "$BUILDTOOLS_DEBUG" = 1 ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: FIND_PRIM_LIB result for metis: \"$coin_has_metis\"" >&5 +printf "%s\n" "$as_me: FIND_PRIM_LIB result for metis: \"$coin_has_metis\"" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Collected values for package 'metis'" >&5 +printf "%s\n" "$as_me: Collected values for package 'metis'" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: metis_lflags is \"$metis_lflags\"" >&5 +printf "%s\n" "$as_me: metis_lflags is \"$metis_lflags\"" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: metis_cflags is \"$metis_cflags\"" >&5 +printf "%s\n" "$as_me: metis_cflags is \"$metis_cflags\"" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: metis_data is \"$metis_data\"" >&5 +printf "%s\n" "$as_me: metis_data is \"$metis_data\"" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: metis_pcfiles is \"$metis_pcfiles\"" >&5 +printf "%s\n" "$as_me: metis_pcfiles is \"$metis_pcfiles\"" >&6;} + fi + + if test -n "$metis_failmode" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $coin_has_metis ($metis_failmode)" >&5 +printf "%s\n" "$coin_has_metis ($metis_failmode)" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $coin_has_metis" >&5 +printf "%s\n" "$coin_has_metis" >&6; } + fi + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $coin_has_metis (COIN_SKIP_PROJECTS)" >&5 +printf "%s\n" "$coin_has_metis (COIN_SKIP_PROJECTS)" >&6; } + fi + + + if test "$coin_has_metis" = 'no' ; then + if expr "$metis_failmode" : '.*header.*' &>/dev/null ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Compiler flags were \"$metis_cflags\". Use --with-metis-cflags to overwrite. Check config.log for details of failed compile attempt." >&5 +printf "%s\n" "$as_me: Compiler flags were \"$metis_cflags\". Use --with-metis-cflags to overwrite. Check config.log for details of failed compile attempt." >&6;} + fi + if expr "$metis_failmode" : '.*link.*' &>/dev/null ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Linker flags are \"$metis_lflags\". Use --with-metis-lflags to overwrite. Check config.log for details of failed link attempt." >&5 +printf "%s\n" "$as_me: Linker flags are \"$metis_lflags\". Use --with-metis-lflags to overwrite. Check config.log for details of failed link attempt." >&6;} + fi + if test "$metis_userflags" = 'yes' ; then + as_fn_error $? "user-specified flags for Metis do not work." "$LINENO" 5 + fi + fi + + + if test "$coin_has_metis" != yes ; then + coin_has_metis=no + fi + + + if test $coin_has_metis = yes; then + COIN_HAS_METIS_TRUE= + COIN_HAS_METIS_FALSE='#' +else + COIN_HAS_METIS_TRUE='#' + COIN_HAS_METIS_FALSE= +fi + + + + if test $coin_has_metis = yes ; then + +printf "%s\n" "#define THIRDPARTYMUMPS_HAS_METIS 1" >>confdefs.h + + MUMPS_LFLAGS="$metis_lflags $MUMPS_LFLAGS" + MUMPS_CFLAGS="$metis_cflags $MUMPS_CFLAGS" + + + + + fi + + + +# check that Metis flags also work with Fortran compiler +if test "$coin_has_metis" = yes ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether Metis library is linkable with Fortran compiler" >&5 +printf %s "checking whether Metis library is linkable with Fortran compiler... " >&6; } + ac_ext=${ac_fc_srcext-f} +ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' +ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_fc_compiler_gnu + + orig_LIBS="$LIBS" + LIBS="$LIBS $metis_lflags" + cat > conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +if ac_fn_fc_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + if test "$metis_userflags" = yes ; then + as_fn_error $? "Metis linker flags $metis_lflags worked with C compiler, but failed with Fortran compiler. Check config.log for details." "$LINENO" 5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Metis linker flags $metis_lflags worked with C compiler, but failed with Fortran compiler. Check config.log for details. Disabling Metis." >&5 +printf "%s\n" "$as_me: WARNING: Metis linker flags $metis_lflags worked with C compiler, but failed with Fortran compiler. Check config.log for details. Disabling Metis." >&2;} + coin_has_metis=no + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + LIBS="$orig_LIBS" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi + + if test $coin_has_metis = yes; then + COIN_HAS_METIS_TRUE= + COIN_HAS_METIS_FALSE='#' +else + COIN_HAS_METIS_TRUE='#' + COIN_HAS_METIS_FALSE= +fi + + +if test "$coin_has_metis" = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Metis version" >&5 +printf %s "checking Metis version... " >&6; } + ac_save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$MUMPS_CFLAGS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include "metis.h" + #ifndef METIS_VER_MAJOR + #error metis4 + #endif + +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + MY_DEFS="$MY_DEFS -Dmetis" + MY_FDEFS="$MY_FDEFS -Dmetis" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 5" >&5 +printf "%s\n" "5" >&6; } + +else $as_nop + MY_DEFS="$MY_DEFS -Dmetis4" + MY_FDEFS="$MY_FDEFS -Dmetis4" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 4" >&5 +printf "%s\n" "4" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CPPFLAGS=$ac_save_CPPFLAGS +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Adjust Fortran preprocessor flags for IBM compiler +case $FC in *xlf*) + fdefs= + if test -n "$MY_FDEFS"; then + for flag in $MY_FDEFS; do + fdefs="$fdefs -WF,$flag" + done + fi + MY_FDEFS="$fdefs" + ;; +esac + +# Add workaround for incompatibility with Fortran 2003 (https://github.com/coin-or-tools/ThirdParty-Mumps/issues/4) +case $FC in *gfortran*) MY_FDEFS="$MY_FDEFS -std=legacy" ;; esac + +# Specify 8-byte integers if intsize=64 (TODO This should become a macro in BuildTools that figures out the right flag to use) +if test $intsize = 64 ; then + case $FC in + *gfortran*) MY_FDEFS="$MY_FDEFS -fdefault-integer-8" ;; + *ifort*) + case $build in + *-cygwin* | *-mingw* | *-msys* ) MY_FDEFS="$MY_FDEFS -integer-size:64" ;; + *) MY_FDEFS="$MY_FDEFS -integer-size 64" ;; + esac + ;; + *) as_fn_error $? "Do not know how to select 8-byte integers for Fortran compiler $FC" "$LINENO" 5 ;; + esac +fi + + + + + if test "$BUILDTOOLS_DEBUG" = 1 ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: FINALIZE_FLAGS for MUMPS:" >&5 +printf "%s\n" "$as_me: FINALIZE_FLAGS for MUMPS:" >&6;} + fi + MUMPS_LFLAGS_NOPC=$MUMPS_LFLAGS + + MUMPS_CFLAGS_NOPC=$MUMPS_CFLAGS + + if test -n "${MUMPS_PCFILES}" ; then + temp_CFLAGS=`PKG_CONFIG_PATH="$COIN_PKG_CONFIG_PATH" $PKG_CONFIG --cflags ${MUMPS_PCFILES}` + temp_LFLAGS=`PKG_CONFIG_PATH="$COIN_PKG_CONFIG_PATH" $PKG_CONFIG --libs $pkg_static ${MUMPS_PCFILES}` + MUMPS_CFLAGS="$temp_CFLAGS ${MUMPS_CFLAGS}" + MUMPS_LFLAGS="$temp_LFLAGS ${MUMPS_LFLAGS}" + fi + + # setup XYZ_EXPORT symbol for library users + libexport_attribute= + if test "$enable_shared" = yes ; then + case $build_os in + cygwin* | mingw* | msys* | cegcc* ) + libexport_attribute="__declspec(dllimport)" + if test "$enable_static" = yes ; then + as_fn_error $? "Cannot do DLL and static LIB builds simultaneously. Do not add --enable-static without --disable-shared." "$LINENO" 5 + fi + ;; + esac + fi + +printf "%s\n" "#define MUMPS_EXPORT $libexport_attribute" >>confdefs.h + + + # add -DXYZ_BUILD to XYZ_CFLAGS + MUMPS_CFLAGS="${MUMPS_CFLAGS} -DMUMPS_BUILD" + + # Define BUILDTOOLS_DEBUG to enable debugging output + if test "$BUILDTOOLS_DEBUG" = 1 ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: MUMPS_LFLAGS_NOPC: \"${MUMPS_LFLAGS_NOPC}\"" >&5 +printf "%s\n" "$as_me: MUMPS_LFLAGS_NOPC: \"${MUMPS_LFLAGS_NOPC}\"" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: MUMPS_CFLAGS_NOPC: \"${MUMPS_CFLAGS_NOPC}\"" >&5 +printf "%s\n" "$as_me: MUMPS_CFLAGS_NOPC: \"${MUMPS_CFLAGS_NOPC}\"" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: adding \"${MUMPS_PCFILES}\"" >&5 +printf "%s\n" "$as_me: adding \"${MUMPS_PCFILES}\"" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: MUMPS_LFLAGS: \"${MUMPS_LFLAGS}\"" >&5 +printf "%s\n" "$as_me: MUMPS_LFLAGS: \"${MUMPS_LFLAGS}\"" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: MUMPS_CFLAGS: \"${MUMPS_CFLAGS}\"" >&5 +printf "%s\n" "$as_me: MUMPS_CFLAGS: \"${MUMPS_CFLAGS}\"" >&6;} + fi + + + +# if libexport_attribute is set by COIN_FINALIZE_FLAGS to __declspec(dllimport) +# then we want to use MUMPS_CALL=__declspec(dllexport) when building Mumps +# and users should use __declspec(dllimport), but the parenthesis are difficult +# to pass on via compiler flags +# so also create and install our own version of mumps_compat.h instead +if test "$libexport_attribute" = "__declspec(dllimport)" ; then + MY_DEFS="$MY_DEFS -DMUMPS_CALL=\"__declspec(dllexport)\"" +fi + +printf "%s\n" "#define MUMPS_CALL $libexport_attribute" >>confdefs.h + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: additional C preprocessor flags: $MY_DEFS" >&5 +printf "%s\n" "$as_me: additional C preprocessor flags: $MY_DEFS" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: additional Fortran preprocessor flags: $MY_FDEFS" >&5 +printf "%s\n" "$as_me: additional Fortran preprocessor flags: $MY_FDEFS" >&6;} + +ac_config_files="$ac_config_files Makefile coinmumps.pc" + +ac_config_headers="$ac_config_headers config.h mumps_compat.h mumps_int_def.h" + + + + cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +printf %s "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 +printf "%s\n" "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${COIN_RELOCATABLE_TRUE}" && test -z "${COIN_RELOCATABLE_FALSE}"; then + as_fn_error $? "conditional \"COIN_RELOCATABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${COIN_STATIC_BUILD_TRUE}" && test -z "${COIN_STATIC_BUILD_FALSE}"; then + as_fn_error $? "conditional \"COIN_STATIC_BUILD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MUMPS_SINGLE_TRUE}" && test -z "${MUMPS_SINGLE_FALSE}"; then + as_fn_error $? "conditional \"MUMPS_SINGLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MUMPS_DOUBLE_TRUE}" && test -z "${MUMPS_DOUBLE_FALSE}"; then + as_fn_error $? "conditional \"MUMPS_DOUBLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${COIN_HAS_PKGCONFIG_TRUE}" && test -z "${COIN_HAS_PKGCONFIG_FALSE}"; then + as_fn_error $? "conditional \"COIN_HAS_PKGCONFIG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${COIN_HAS_LAPACK_TRUE}" && test -z "${COIN_HAS_LAPACK_FALSE}"; then + as_fn_error $? "conditional \"COIN_HAS_LAPACK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${COIN_HAS_METIS_TRUE}" && test -z "${COIN_HAS_METIS_FALSE}"; then + as_fn_error $? "conditional \"COIN_HAS_METIS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${COIN_HAS_METIS_TRUE}" && test -z "${COIN_HAS_METIS_FALSE}"; then + as_fn_error $? "conditional \"COIN_HAS_METIS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else $as_nop + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else $as_nop + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else $as_nop + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ThirdPartyMumps $as_me 3.0.3, which was +generated by GNU Autoconf 2.71. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to . +ThirdPartyMumps home page: ." + +_ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config='$ac_cs_config_escaped' +ac_cs_version="\\ +ThirdPartyMumps config.status 3.0.3 +configured by $0, generated by GNU Autoconf 2.71, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2021 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + printf "%s\n" "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + printf "%s\n" "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + printf "%s\n" "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + printf "%s\n" "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_FC='`$ECHO "$LD_FC" | $SED "$delay_single_quote_subst"`' +reload_flag_FC='`$ECHO "$reload_flag_FC" | $SED "$delay_single_quote_subst"`' +reload_cmds_FC='`$ECHO "$reload_cmds_FC" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_FC='`$ECHO "$old_archive_cmds_FC" | $SED "$delay_single_quote_subst"`' +compiler_FC='`$ECHO "$compiler_FC" | $SED "$delay_single_quote_subst"`' +GCC_FC='`$ECHO "$GCC_FC" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_FC='`$ECHO "$lt_prog_compiler_no_builtin_flag_FC" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_FC='`$ECHO "$lt_prog_compiler_pic_FC" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_FC='`$ECHO "$lt_prog_compiler_wl_FC" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_FC='`$ECHO "$lt_prog_compiler_static_FC" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_FC='`$ECHO "$lt_cv_prog_compiler_c_o_FC" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_FC='`$ECHO "$archive_cmds_need_lc_FC" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_FC='`$ECHO "$enable_shared_with_static_runtimes_FC" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_FC='`$ECHO "$export_dynamic_flag_spec_FC" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_FC='`$ECHO "$whole_archive_flag_spec_FC" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_FC='`$ECHO "$compiler_needs_object_FC" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_FC='`$ECHO "$old_archive_from_new_cmds_FC" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_FC='`$ECHO "$old_archive_from_expsyms_cmds_FC" | $SED "$delay_single_quote_subst"`' +archive_cmds_FC='`$ECHO "$archive_cmds_FC" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_FC='`$ECHO "$archive_expsym_cmds_FC" | $SED "$delay_single_quote_subst"`' +module_cmds_FC='`$ECHO "$module_cmds_FC" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_FC='`$ECHO "$module_expsym_cmds_FC" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_FC='`$ECHO "$with_gnu_ld_FC" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_FC='`$ECHO "$allow_undefined_flag_FC" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_FC='`$ECHO "$no_undefined_flag_FC" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_FC='`$ECHO "$hardcode_libdir_flag_spec_FC" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_FC='`$ECHO "$hardcode_libdir_separator_FC" | $SED "$delay_single_quote_subst"`' +hardcode_direct_FC='`$ECHO "$hardcode_direct_FC" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_FC='`$ECHO "$hardcode_direct_absolute_FC" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_FC='`$ECHO "$hardcode_minus_L_FC" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_FC='`$ECHO "$hardcode_shlibpath_var_FC" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_FC='`$ECHO "$hardcode_automatic_FC" | $SED "$delay_single_quote_subst"`' +inherit_rpath_FC='`$ECHO "$inherit_rpath_FC" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_FC='`$ECHO "$link_all_deplibs_FC" | $SED "$delay_single_quote_subst"`' +always_export_symbols_FC='`$ECHO "$always_export_symbols_FC" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_FC='`$ECHO "$export_symbols_cmds_FC" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_FC='`$ECHO "$exclude_expsyms_FC" | $SED "$delay_single_quote_subst"`' +include_expsyms_FC='`$ECHO "$include_expsyms_FC" | $SED "$delay_single_quote_subst"`' +prelink_cmds_FC='`$ECHO "$prelink_cmds_FC" | $SED "$delay_single_quote_subst"`' +postlink_cmds_FC='`$ECHO "$postlink_cmds_FC" | $SED "$delay_single_quote_subst"`' +file_list_spec_FC='`$ECHO "$file_list_spec_FC" | $SED "$delay_single_quote_subst"`' +hardcode_action_FC='`$ECHO "$hardcode_action_FC" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_FC='`$ECHO "$compiler_lib_search_dirs_FC" | $SED "$delay_single_quote_subst"`' +predep_objects_FC='`$ECHO "$predep_objects_FC" | $SED "$delay_single_quote_subst"`' +postdep_objects_FC='`$ECHO "$postdep_objects_FC" | $SED "$delay_single_quote_subst"`' +predeps_FC='`$ECHO "$predeps_FC" | $SED "$delay_single_quote_subst"`' +postdeps_FC='`$ECHO "$postdeps_FC" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_FC='`$ECHO "$compiler_lib_search_path_FC" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_FC \ +reload_flag_FC \ +compiler_FC \ +lt_prog_compiler_no_builtin_flag_FC \ +lt_prog_compiler_pic_FC \ +lt_prog_compiler_wl_FC \ +lt_prog_compiler_static_FC \ +lt_cv_prog_compiler_c_o_FC \ +export_dynamic_flag_spec_FC \ +whole_archive_flag_spec_FC \ +compiler_needs_object_FC \ +with_gnu_ld_FC \ +allow_undefined_flag_FC \ +no_undefined_flag_FC \ +hardcode_libdir_flag_spec_FC \ +hardcode_libdir_separator_FC \ +exclude_expsyms_FC \ +include_expsyms_FC \ +file_list_spec_FC \ +compiler_lib_search_dirs_FC \ +predep_objects_FC \ +postdep_objects_FC \ +predeps_FC \ +postdeps_FC \ +compiler_lib_search_path_FC; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_FC \ +old_archive_cmds_FC \ +old_archive_from_new_cmds_FC \ +old_archive_from_expsyms_cmds_FC \ +archive_cmds_FC \ +archive_expsym_cmds_FC \ +module_cmds_FC \ +module_expsym_cmds_FC \ +export_symbols_cmds_FC \ +prelink_cmds_FC \ +postlink_cmds_FC; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "libtoolclpatch") CONFIG_COMMANDS="$CONFIG_COMMANDS libtoolclpatch" ;; + "libtoolmingwpatch") CONFIG_COMMANDS="$CONFIG_COMMANDS libtoolmingwpatch" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "coinmumps.pc") CONFIG_FILES="$CONFIG_FILES coinmumps.pc" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "mumps_compat.h") CONFIG_HEADERS="$CONFIG_HEADERS mumps_compat.h" ;; + "mumps_int_def.h") CONFIG_HEADERS="$CONFIG_HEADERS mumps_int_def.h" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files + test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers + test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`printf "%s\n" "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +printf "%s\n" "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? + done + if test $am_rc -ne 0; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# The names of the tagged configurations supported by this script. +available_tags='FC ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: FC + +# The linker used to build libraries. +LD=$lt_LD_FC + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_FC +reload_cmds=$lt_reload_cmds_FC + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_FC + +# A language specific compiler. +CC=$lt_compiler_FC + +# Is the compiler the GNU compiler? +with_gcc=$GCC_FC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_FC + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_FC + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_FC + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_FC + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_FC + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_FC + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_FC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_FC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_FC + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_FC + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_FC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_FC + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_FC +archive_expsym_cmds=$lt_archive_expsym_cmds_FC + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_FC +module_expsym_cmds=$lt_module_expsym_cmds_FC + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_FC + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_FC + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_FC + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_FC + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_FC + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_FC + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_FC + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_FC + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_FC + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_FC + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_FC + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_FC + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_FC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_FC + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_FC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_FC + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_FC + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_FC + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_FC + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_FC + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_FC + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_FC +postdep_objects=$lt_postdep_objects_FC +predeps=$lt_predeps_FC +postdeps=$lt_postdeps_FC + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_FC + +# ### END LIBTOOL TAG CONFIG: FC +_LT_EOF + + ;; + "libtoolclpatch":C) sed -e '/^deplibs_check_method/s/.*/deplibs_check_method="pass_all"/g' \ + -e 's|always_export_symbols=yes|always_export_symbols=no|g' \ + -e '/func_append old_deplibs/s/\(.*\)/case $arg in *mkl_*.lib) ;; *) \1 ;; esac/g' \ + -e '/static library .deplib is not portable/a case $deplib in *mkl_*.lib) newdependency_libs="$deplib $newdependency_libs" ;; esac' \ + libtool > libtool.tmp + mv libtool.tmp libtool + chmod 755 libtool ;; + "libtoolmingwpatch":C) sed -e '/^deplibs_check_method/s/.*/deplibs_check_method="pass_all"/g' libtool > libtool.tmp + mv libtool.tmp libtool + chmod 755 libtool ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configuration of $PACKAGE_NAME successful" >&5 +printf "%s\n" "$as_me: Configuration of $PACKAGE_NAME successful" >&6;} + + diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/configure.ac b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/configure.ac new file mode 100644 index 0000000..4f554e6 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/configure.ac @@ -0,0 +1,242 @@ +# Copyright (C) 2007-2009 International Business Machines. +# All Rights Reserved. +# This file is distributed under the Eclipse Public License. +# +# Author: Andreas Waechter IBM 2006-04-13 + +############################################################################# +# Names and other basic things # +############################################################################# + +AC_INIT([ThirdPartyMumps],[3.0.3],[https://github.com/coin-or-tools/ThirdParty-Mumps/issues/new],[],[https://github.com/coin-or-tools/ThirdParty-Mumps]) + +AC_COPYRIGHT([ +Copyright 2007-2009 International Business Machines and others. +All Rights Reserved. +This file is part of the open source package Coin which is distributed +under the Eclipse Public License.]) + +# List one file in the package so that the configure script can test +# whether the package is actually there +AC_CONFIG_SRCDIR(MUMPS/src/mumps_common.c) + +AC_COIN_INITIALIZE + +############################################################################# +# Standard build tool stuff # +############################################################################# + +# Get the name of the C compiler and appropriate compiler options +AC_COIN_PROG_CC + +# Get the name of the Fortran compiler and appropriate compiler options +AC_COIN_PROG_FC +if test -z "$FC" ; then + AC_MSG_ERROR([No Fortran 90 compiler found. Try setting environment variable FC.]) +fi + +# Initialize libtool +AC_COIN_PROG_LIBTOOL + +# Figure out name mangling that Fortran objects will have and translate +# them to what MUMPS wants, this also includes AC_FC_LIBRARY_LDFLAGS +AC_FC_WRAPPERS +case "$ac_cv_fc_mangling" in + "lower case, no underscore, no extra underscore" ) ;; + "lower case, underscore, no extra underscore" ) MY_DEFS="-DAdd_" ;; + "lower case, no underscore, extra underscore" ) MY_DEFS="-DAdd_" ;; + "lower case, underscore, extra underscore" ) MY_DEFS="-DAdd__" ;; + "upper case, no underscore, no extra underscore" ) MY_DEFS="-DUPPER" ;; + "upper case, no underscore, extra underscore" ) MY_DEFS="-DUPPER" ;; + "upper case, underscore, no extra underscore" ) MY_DEFS="-DUPPER" ;; + "upper case, underscore, extra underscore" ) MY_DEFS="-DUPPER" ;; +esac +AC_SUBST(MY_DEFS) + +# Add FCLIBS to MUMPS_LFLAGS, so that they get into the .pc files section for static builds +MUMPS_LFLAGS="$MUMPS_LFLAGS $FCLIBS" + +# check which floating-point precision to build +AC_ARG_WITH([precision], + [AS_HELP_STRING([--with-precision],[floating-point precision to build: single, double (default), or all])], + [precision=$withval + case "$precision" in + single | double | all ) ;; + *) AC_MSG_ERROR([unsupported value $precision for option --with-precision]) ;; + esac], + [precision=double]) +AM_CONDITIONAL([MUMPS_SINGLE],[test "$precision" = single || test "$precision" = all]) +AM_CONDITIONAL([MUMPS_DOUBLE],[test "$precision" = double || test "$precision" = all]) + +# check which integer size to build +AC_ARG_WITH([intsize], + [AS_HELP_STRING([--with-intsize],[integer size in bits to use: 32 or 64])], + [intsize=$withval], + [intsize=32]) +case "$intsize" in + 32 ) AC_DEFINE(MUMPS_INTSIZE32, [], [Define if MUMPS integers have a size of 32-bit]) ;; + 64 ) AC_DEFINE(MUMPS_INTSIZE64, [], [Define if MUMPS integers have a size of 64-bit]) ;; + *) AC_MSG_ERROR([unsupported value $intsize for option --with-intsize]) ;; +esac + +# Mumps can make use of pthreads +# check for pthread.h header file and library +AC_ARG_ENABLE([pthread-mumps], + [AS_HELP_STRING([--disable-pthread-mumps],[disable use of pthread library])], + [enable_pthread_mumps=$enableval], + [enable_pthread_mumps=yes]) +if test $enable_pthread_mumps = yes ; then + AC_CHECK_HEADER([pthread.h],[],[enable_pthread_mumps=no]) +fi +if test $enable_pthread_mumps = yes ; then + AC_CHECK_LIB([pthread],[pthread_create], + [MUMPS_LFLAGS="$MUMPS_LFLAGS -lpthread"], + [enable_pthread_mumps=no]) +fi +if test $enable_pthread_mumps = no ; then + MY_DEFS="$MY_DEFS -DWITHOUT_PTHREAD=1" +fi + +# Mumps can use OpenMP +# but if single threaded, then it (5.2.1) seems to become slower within Ipopt, so disable by default +if test -z "$enable_openmp" ; then + enable_openmp=no +fi +AC_LANG_PUSH(Fortran) +AC_OPENMP +FCFLAGS="$FCFLAGS $OPENMP_FCFLAGS" +MUMPS_LFLAGS="$MUMPS_LFLAGS $OPENMP_FCFLAGS" +AC_LANG_POP(Fortran) + +AC_COIN_CHK_LAPACK(MUMPS, int$intsize) +if test $coin_has_lapack != yes; then + AC_MSG_ERROR([Required package LAPACK not found.]) +fi + +# if the BLAS library includes the GEMMT level-3 BLAS extension, it is strongly recommend to use it +AC_COIN_TRY_LINK([dgemmt],[$lapack_lflags],[$lapack_pcfiles],[MY_FDEFS="$MY_FDEFS -DGEMMT_AVAILABLE"]) + +AC_COIN_CHK_LIBM(METISCHECK) +AC_LANG_PUSH(C) +AC_COIN_CHK_LIBHDR(Metis,[MUMPS],[-lmetis "$METISCHECK_LFLAGS"],[],[], + [#if METIS_VER_MAJOR < 5 + metis_nodend((int*)0, (int*)0, (int*)0, (int*)0, (int*)0, (int*)0, (int*)0); + #else + METIS_NodeND((int*)0, (int*)0, (int*)0, (int*)0, (int*)0, (int*)0, (int*)0); + #endif + ], + [#define __STDC_WANT_IEC_60559_BFP_EXT__ + #ifdef __STDC__ + #include + #endif + #include "metis.h" + #ifndef METIS_VER_MAJOR + #define METIS_VER_MAJOR 4 + #ifdef IDXTYPE_INT + #define IDXTYPEWIDTH 32 + #else + #define IDXTYPEWIDTH 64 + #endif + #endif + #if defined(MUMPS_INTSIZE32) && defined(INT_WIDTH) && INT_WIDTH != IDXTYPEWIDTH + #error "Metis does not use int type for idx_t, but this build of MUMPS requires it" + #endif + #if defined(MUMPS_INTSIZE64) && IDXTYPEWIDTH != 64 + #error "Metis does not use 64-bit integers for idx_t, but this build of MUMPS requires it" + #endif + ]) + +# check that Metis flags also work with Fortran compiler +if test "$coin_has_metis" = yes ; then + AC_MSG_CHECKING([whether Metis library is linkable with Fortran compiler]) + AC_LANG_PUSH(Fortran) + orig_LIBS="$LIBS" + LIBS="$LIBS $metis_lflags" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + if test "$metis_userflags" = yes ; then + AC_MSG_ERROR([Metis linker flags $metis_lflags worked with C compiler, but failed with Fortran compiler. Check config.log for details.]) + else + AC_MSG_WARN([Metis linker flags $metis_lflags worked with C compiler, but failed with Fortran compiler. Check config.log for details. Disabling Metis.]) + coin_has_metis=no + fi]) + LIBS="$orig_LIBS" + AC_LANG_POP(Fortran) +fi + +AM_CONDITIONAL(COIN_HAS_METIS, [test $coin_has_metis = yes]) + +if test "$coin_has_metis" = yes; then + AC_MSG_CHECKING([Metis version]) + ac_save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$MUMPS_CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ + #include "metis.h" + #ifndef METIS_VER_MAJOR + #error metis4 + #endif + ],[])], + [MY_DEFS="$MY_DEFS -Dmetis" + MY_FDEFS="$MY_FDEFS -Dmetis" + AC_MSG_RESULT([5]) + ], + [MY_DEFS="$MY_DEFS -Dmetis4" + MY_FDEFS="$MY_FDEFS -Dmetis4" + AC_MSG_RESULT([4]) + ]) + CPPFLAGS=$ac_save_CPPFLAGS +fi + +AC_LANG_POP(C) + +# Adjust Fortran preprocessor flags for IBM compiler +case $FC in *xlf*) + fdefs= + if test -n "$MY_FDEFS"; then + for flag in $MY_FDEFS; do + fdefs="$fdefs -WF,$flag" + done + fi + MY_FDEFS="$fdefs" + ;; +esac + +# Add workaround for incompatibility with Fortran 2003 (https://github.com/coin-or-tools/ThirdParty-Mumps/issues/4) +case $FC in *gfortran*) MY_FDEFS="$MY_FDEFS -std=legacy" ;; esac + +# Specify 8-byte integers if intsize=64 (TODO This should become a macro in BuildTools that figures out the right flag to use) +if test $intsize = 64 ; then + case $FC in + *gfortran*) MY_FDEFS="$MY_FDEFS -fdefault-integer-8" ;; + *ifort*) + case $build in + *-cygwin* | *-mingw* | *-msys* ) MY_FDEFS="$MY_FDEFS -integer-size:64" ;; + *) MY_FDEFS="$MY_FDEFS -integer-size 64" ;; + esac + ;; + *) AC_MSG_ERROR([Do not know how to select 8-byte integers for Fortran compiler $FC]) ;; + esac +fi + +AC_SUBST(MY_FDEFS) + +AC_COIN_FINALIZE_FLAGS([MUMPS]) + +# if libexport_attribute is set by COIN_FINALIZE_FLAGS to __declspec(dllimport) +# then we want to use MUMPS_CALL=__declspec(dllexport) when building Mumps +# and users should use __declspec(dllimport), but the parenthesis are difficult +# to pass on via compiler flags +# so also create and install our own version of mumps_compat.h instead +if test "$libexport_attribute" = "__declspec(dllimport)" ; then + MY_DEFS="$MY_DEFS -DMUMPS_CALL=\"__declspec(dllexport)\"" +fi +AC_DEFINE_UNQUOTED(MUMPS_CALL, [$libexport_attribute], [Library Visibility Attribute]) + +AC_MSG_NOTICE([additional C preprocessor flags: $MY_DEFS]) +AC_MSG_NOTICE([additional Fortran preprocessor flags: $MY_FDEFS]) + +AC_CONFIG_FILES([Makefile coinmumps.pc]) +AC_CONFIG_HEADERS([config.h mumps_compat.h mumps_int_def.h]) + +AC_COIN_FINALIZE diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/depcomp b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/depcomp new file mode 100755 index 0000000..6b39162 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2020 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/get.Mumps b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/get.Mumps new file mode 100755 index 0000000..e7782ef --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/get.Mumps @@ -0,0 +1,70 @@ +#!/bin/sh + +# Set the following to the latest MUMPS version. +# THERE MUST BE NO SPACE BEFORE AND AFTER THE EQUAL (=) OPERATOR. +mumps_ver=5.5.0 + +set -e + +wgetcount=`which wget 2>/dev/null | wc -l` +if test ! $wgetcount = 1; then + curlcount=`which curl 2>/dev/null | wc -l` + if test ! $curlcount = 1; then + fetchcount=`which fetch 2>/dev/null | wc -l` + if test ! $fetchcount = 1; then + echo "None of the utilities, wget, curl, or fetch found in PATH. Cannot download source." + exit -1 + else + wgetcmd=fetch + fi + else + wgetcmd="curl -L -O" + fi +else +wgetcmd="wget" +fi + +echo " " +echo "Running script for downloading the source code for MUMPS" +echo " " + +rm -f MUMPS*.tgz + +echo "Downloading the source code from coin-or-tools.github.io..." +if $wgetcmd http://coin-or-tools.github.io/ThirdParty-Mumps/MUMPS_${mumps_ver}.tar.gz ; +then + echo "Download finished." +else + echo + echo "Downloading from GitHub failed, trying mumps.enseeiht.fr..." + if $wgetcmd http://mumps.enseeiht.fr/MUMPS_${mumps_ver}.tar.gz ; + then + echo "Download finished." + else + echo "Download failed...exiting" + fi +fi + +echo "Uncompressing the tarball..." +gunzip -f MUMPS_${mumps_ver}.tar.gz + +echo "Unpacking the source code..." +tar xf MUMPS_${mumps_ver}.tar + +echo "Deleting the tar file..." +rm MUMPS_${mumps_ver}.tar + +rm -rf MUMPS +mv MUMPS_${mumps_ver} MUMPS + +echo " " +echo "Done downloading the source code for MUMPS." +echo " " +echo "Apply a patch to improve MPI compatibility." +echo " " + +patch -p0 < mumps_mpi.patch +mv MUMPS/libseq/mpi.h MUMPS/libseq/mumps_mpi.h + +echo " " +echo "Verify that there are no error message in the output above." diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/ltmain.sh b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/ltmain.sh new file mode 100755 index 0000000..0f0a2da --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/ltmain.sh @@ -0,0 +1,11147 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4.6 +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2014-01-07.03; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname (GNU libtool) 2.4.6 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -stdlib=* select c++ std lib with clang + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/missing b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/missing new file mode 100755 index 0000000..8d0eaad --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_compat.h.in b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_compat.h.in new file mode 100644 index 0000000..b28f5c0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_compat.h.in @@ -0,0 +1,26 @@ +/* mumps_compat.h.in. */ + +#ifndef MUMPS_COMPAT_H +#define MUMPS_COMPAT_H + +#ifndef MUMPS_CALL +/* Define Mumps calling convention. */ +#undef MUMPS_CALL +#endif + +/* tell using codes that we changed mpi.h to mumps_mpi.h */ +#define COIN_USE_MUMPS_MPI_H + +/* copied from MUMPS' own mumps_compat.h */ +#if defined(_WIN32) && ! defined(__MINGW32__) +# define MUMPS_WIN32 1 +#endif + +#if (__STDC_VERSION__ >= 199901L) +# define MUMPS_INLINE static inline +#else +# define MUMPS_INLINE +#endif + + +#endif /* MUMPS_COMPAT_H */ diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_int_def.h.in b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_int_def.h.in new file mode 100644 index 0000000..13aaa5b --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_int_def.h.in @@ -0,0 +1,10 @@ +#ifndef MUMPS_INT_H +#define MUMPS_INT_H + +/* Define if MUMPS integers have a size of 32-bit */ +#undef MUMPS_INTSIZE32 + +/* Define if MUMPS integers have a size of 64-bit */ +#undef MUMPS_INTSIZE64 + +#endif diff --git a/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_mpi.patch b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_mpi.patch new file mode 100644 index 0000000..5da26ae --- /dev/null +++ b/locomotion/src/third_party/qpOASES/external/ThirdParty-Mumps/mumps_mpi.patch @@ -0,0 +1,57 @@ +diff -ur MUMPS_5.4.0/libseq/mpic.c MUMPS/libseq/mpic.c +--- MUMPS_5.4.0/libseq/mpic.c 2021-04-13 17:26:34.000000000 +0200 ++++ MUMPS/libseq/mpic.c 2021-05-12 16:25:49.708906988 +0200 +@@ -13,7 +13,7 @@ + * https://cecill.info/licences/Licence_CeCILL-C_V1-en.html) + * + */ +-#include "mpi.h" ++#include "mumps_mpi.h" + LIBSEQ_INT LIBSEQ_CALL MPI_Init(LIBSEQ_INT *pargc, char ***pargv) + { + return 0; +diff -ur MUMPS_5.4.0/src/mumps_metis64.h MUMPS/src/mumps_metis64.h +--- MUMPS_5.4.0/src/mumps_metis64.h 2021-04-13 17:26:35.000000000 +0200 ++++ MUMPS/src/mumps_metis64.h 2021-05-12 16:25:49.708906988 +0200 +@@ -18,7 +18,11 @@ + /* Interfacing with 64-bit (par)metis, for METIS 4 or METIS 5 */ + #include "mumps_common.h" /* includes mumps_compat.h and mumps_c_types.h */ + #if defined(parmetis) || defined(parmetis3) ++#ifdef MPI + #include "mpi.h" ++#else ++#include "mumps_mpi.h" ++#endif + #define MUMPS_PARMETIS_64 \ + F_SYMBOL(parmetis_64,PARMETIS_64) + void MUMPS_CALL +diff -ur MUMPS_5.4.0/src/mumps_metis.h MUMPS/src/mumps_metis.h +--- MUMPS_5.4.0/src/mumps_metis.h 2021-04-13 17:26:35.000000000 +0200 ++++ MUMPS/src/mumps_metis.h 2021-05-12 16:25:49.708906988 +0200 +@@ -18,7 +18,11 @@ + /* Interfacing with 32-bit (par)metis, for METIS 4 or METIS 5 */ + #include "mumps_common.h" /* includes mumps_compat.h and mumps_c_types.h */ + #if defined(parmetis) || defined(parmetis3) ++#ifdef MPI + #include "mpi.h" ++#else ++#include "mumps_mpi.h" ++#endif + #define MUMPS_PARMETIS \ + F_SYMBOL(parmetis,PARMETIS) + void MUMPS_CALL +diff -ur MUMPS_5.4.0/src/mumps_scotch.h MUMPS/src/mumps_scotch.h +--- MUMPS_5.4.0/src/mumps_scotch.h 2021-04-13 17:26:35.000000000 +0200 ++++ MUMPS/src/mumps_scotch.h 2021-05-12 16:25:49.708906988 +0200 +@@ -72,7 +72,11 @@ + MUMPS_SCOTCH_SET_PTHREAD_NUMBER (MUMPS_INT *PTHREAD_NUMBER); + #endif /*scotch or ptscotch*/ + #if defined(ptscotch) ++#ifdef MPI + #include "mpi.h" ++#else ++#include "mumps_mpi.h" ++#endif + #include "ptscotch.h" + #define MUMPS_DGRAPHINIT \ + F_SYMBOL(dgraphinit,DGRAPHINIT) diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES.hpp new file mode 100644 index 0000000..e8c57c5 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES.hpp @@ -0,0 +1,73 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + */ + + +#if defined(__SINGLE_OBJECT__) || defined(__C_WRAPPER__) + +#include +#include +#include +#include +#include +#include + +#if !defined(__MATLAB__) || defined(WIN32) +#include +#include +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(SOLVER_MA27) || defined(SOLVER_MA57) +#include +#include +#endif + +#if !defined(__C_WRAPPER__) && !defined(__MATLAB__) +#include +#include +#endif + +#else /* default compilation mode */ + +#include +#include +#include +#include +#include +#include + +#endif diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Bounds.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Bounds.hpp new file mode 100644 index 0000000..adfc892 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Bounds.hpp @@ -0,0 +1,256 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Bounds.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the Bounds class designed to manage working sets of + * bounds within a QProblem. + */ + + +#ifndef QPOASES_BOUNDS_HPP +#define QPOASES_BOUNDS_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Manages working sets of bounds (i.e. box constraints). + * + * This class manages working sets of bounds (= box constraints) + * by storing index sets and other status information. + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + */ +class Bounds : public SubjectTo +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + Bounds( ); + + /** Constructor which takes the number of bounds. */ + Bounds( int_t _n /**< Number of bounds. */ + ); + + /** Copy constructor (deep copy). */ + Bounds( const Bounds& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~Bounds( ); + + /** Assignment operator (deep copy). */ + Bounds& operator=( const Bounds& rhs /**< Rhs object. */ + ); + + + /** Initialises object with given number of bounds. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS */ + returnValue init( int_t _n = 0 /**< Number of bounds. */ + ); + + + /** Initially adds number of a new (i.e. not yet in the list) bound to + * given index set. + * \return SUCCESSFUL_RETURN \n + RET_SETUP_BOUND_FAILED \n + RET_INDEX_OUT_OF_BOUNDS \n + RET_INVALID_ARGUMENTS */ + returnValue setupBound( int_t number, /**< Number of new bound. */ + SubjectToStatus _status /**< Status of new bound. */ + ); + + /** Initially adds all numbers of new (i.e. not yet in the list) bounds to + * to the index set of free bounds; the order depends on the SujectToType + * of each index. + * \return SUCCESSFUL_RETURN \n + RET_SETUP_BOUND_FAILED */ + returnValue setupAllFree( ); + + /** Initially adds all numbers of new (i.e. not yet in the list) bounds to + * to the index set of fixed bounds (on their lower bounds); + * the order depends on the SujectToType of each index. + * \return SUCCESSFUL_RETURN \n + RET_SETUP_BOUND_FAILED */ + returnValue setupAllLower( ); + + /** Initially adds all numbers of new (i.e. not yet in the list) bounds to + * to the index set of fixed bounds (on their upper bounds); + * the order depends on the SujectToType of each index. + * \return SUCCESSFUL_RETURN \n + RET_SETUP_BOUND_FAILED */ + returnValue setupAllUpper( ); + + + /** Moves index of a bound from index list of fixed to that of free bounds. + * \return SUCCESSFUL_RETURN \n + RET_MOVING_BOUND_FAILED \n + RET_INDEX_OUT_OF_BOUNDS */ + returnValue moveFixedToFree( int_t number /**< Number of bound to be freed. */ + ); + + /** Moves index of a bound from index list of free to that of fixed bounds. + * \return SUCCESSFUL_RETURN \n + RET_MOVING_BOUND_FAILED \n + RET_INDEX_OUT_OF_BOUNDS */ + returnValue moveFreeToFixed( int_t number, /**< Number of bound to be fixed. */ + SubjectToStatus _status /**< Status of bound to be fixed. */ + ); + + /** Flip fixed bound. + * \return SUCCESSFUL_RETURN \n + RET_MOVING_BOUND_FAILED \n + RET_INDEX_OUT_OF_BOUNDS */ + returnValue flipFixed( int_t number ); + + /** Swaps the indices of two free bounds within the index set. + * \return SUCCESSFUL_RETURN \n + RET_SWAPINDEX_FAILED */ + returnValue swapFree( int_t number1, /**< Number of first constraint or bound. */ + int_t number2 /**< Number of second constraint or bound. */ + ); + + + /** Returns number of variables. + * \return Number of variables. */ + inline int_t getNV( ) const; + + /** Returns number of implicitly fixed variables. + * \return Number of implicitly fixed variables. */ + inline int_t getNFV( ) const; + + /** Returns number of bounded (but possibly free) variables. + * \return Number of bounded (but possibly free) variables. */ + inline int_t getNBV( ) const; + + /** Returns number of unbounded variables. + * \return Number of unbounded variables. */ + inline int_t getNUV( ) const; + + /** Returns number of free variables. + * \return Number of free variables. */ + inline int_t getNFR( ) const; + + /** Returns number of fixed variables. + * \return Number of fixed variables. */ + inline int_t getNFX( ) const; + + + /** Returns a pointer to free variables index list. + * \return Pointer to free variables index list. */ + inline Indexlist* getFree( ); + + /** Returns a pointer to fixed variables index list. + * \return Pointer to fixed variables index list. */ + inline Indexlist* getFixed( ); + + + /** Shifts forward type and status of all bounds by a given + * offset. This offset has to lie within the range [0,n/2] and has to + * be an integer divisor of the total number of bounds n. + * Type and status of the first \ bounds is thrown away, + * type and status of the last \ bounds is doubled, + * e.g. for offset = 2: \n + * shift( {b1,b2,b3,b4,b5,b6} ) = {b3,b4,b5,b6,b5,b6} + * \return SUCCESSFUL_RETURN \n + RET_INDEX_OUT_OF_BOUNDS \n + RET_INVALID_ARGUMENTS \n + RET_SHIFTING_FAILED */ + virtual returnValue shift( int_t offset /**< Shift offset within the range [0,n/2] and integer divisor of n. */ + ); + + /** Rotates forward type and status of all bounds by a given + * offset. This offset has to lie within the range [0,n]. + * Example for offset = 2: \n + * rotate( {b1,b2,b3,b4,b5,b6} ) = {b3,b4,b5,b6,b1,b2} + * \return SUCCESSFUL_RETURN \n + RET_INDEX_OUT_OF_BOUNDS \n + RET_ROTATING_FAILED */ + virtual returnValue rotate( int_t offset /**< Rotation offset within the range [0,n]. */ + ); + + + /** Prints information on bounds object + * (in particular, lists of free and fixed bounds. + * \return SUCCESSFUL_RETURN \n + RET_INDEXLIST_CORRUPTED */ + returnValue print( ); + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const Bounds& rhs /**< Rhs object. */ + ); + + + /** Initially adds all numbers of new (i.e. not yet in the list) bounds to + * to the index set corresponding to the desired status; + * the order depends on the SujectToType of each index. + * \return SUCCESSFUL_RETURN \n + RET_SETUP_BOUND_FAILED */ + returnValue setupAll( SubjectToStatus _status /**< Desired initial status for all bounds. */ + ); + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + Indexlist freee; /**< Index list of free variables. */ + Indexlist fixed; /**< Index list of fixed variables. */ +}; + + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_BOUNDS_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Bounds.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/Bounds.ipp new file mode 100644 index 0000000..1aa1508 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Bounds.ipp @@ -0,0 +1,120 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Bounds.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of inlined member functions of the Bounds class designed + * to manage working sets of bounds within a QProblem. + */ + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + +/* + * g e t N V + */ +inline int_t Bounds::getNV( ) const +{ + return n; +} + + +/* + * g e t N F V + */ +inline int_t Bounds::getNFV( ) const +{ + return getNumberOfType( ST_EQUALITY ); +} + + +/* + * g e t N B V + */ +inline int_t Bounds::getNBV( ) const +{ + return getNumberOfType( ST_BOUNDED ); +} + + +/* + * g e t N U V + */ +inline int_t Bounds::getNUV( ) const +{ + return getNumberOfType( ST_UNBOUNDED ); +} + + +/* + * g e t N F R + */ +inline int_t Bounds::getNFR( ) const +{ + return freee.getLength( ); +} + + +/* + * g e t N F X + */ +inline int_t Bounds::getNFX( ) const +{ + return fixed.getLength( ); +} + + +/* + * g e t F r e e + */ +inline Indexlist* Bounds::getFree( ) +{ + return &freee; +} + + +/* + * g e t F i x e d + */ +inline Indexlist* Bounds::getFixed( ) +{ + return &fixed; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Constants.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Constants.hpp new file mode 100644 index 0000000..3a4c632 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Constants.hpp @@ -0,0 +1,77 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Constants.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Definition of all global constants. + */ + + +#ifndef QPOASES_CONSTANTS_HPP +#define QPOASES_CONSTANTS_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** Numerical value of machine precision (min eps, s.t. 1+eps > 1). + * Note: this value has to be positive! */ +#ifdef __USE_SINGLE_PRECISION__ +const real_t EPS = 1.193e-07f; +#else +const real_t EPS = 2.221e-16; +#endif /* __USE_SINGLE_PRECISION__ */ + + +/** Numerical value of zero (for situations in which it would be + * unreasonable to compare with 0.0). + * Note: this value has to be positive! */ +const real_t ZERO = 1.0e-25; + +/** Numerical value of infinity (e.g. for non-existing bounds). + Note: this value has to be positive! */ +const real_t INFTY = 1.0e20; + + +/** Maximum number of characters within a string. + * Note: this value should be at least 41! */ +const uint_t MAX_STRING_LENGTH = 160; + + +END_NAMESPACE_QPOASES + + +#endif /* QPOASES_CONSTANTS_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/ConstraintProduct.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/ConstraintProduct.hpp new file mode 100644 index 0000000..b9d9a4e --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/ConstraintProduct.hpp @@ -0,0 +1,91 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/ConstraintProduct.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2009-2017 + * + * Declaration of the ConstraintProduct class which allows to specify a + * user-defined function for evaluating the constraint product at the + * current iterate to speed-up QP solution in case of a specially structured + * constraint matrix. + */ + + + +#ifndef QPOASES_CONSTRAINT_PRODUCT_HPP +#define QPOASES_CONSTRAINT_PRODUCT_HPP + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Interface for specifying user-defined evaluations of constraint products. + * + * A class which allows to specify a user-defined function for evaluating the + * constraint product at the current iterate to speed-up QP solution in case + * of a specially structured constraint matrix. + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2009-2017 + */ +class ConstraintProduct +{ + public: + /** Default constructor. */ + ConstraintProduct( ) {}; + + /** Copy constructor. */ + ConstraintProduct( const ConstraintProduct &toCopy /**< Rhs object. */ + ) {}; + + /** Destructor. */ + virtual ~ConstraintProduct( ) {}; + + /** Assignment operator. */ + ConstraintProduct &operator=( const ConstraintProduct &toCopy /**< Rhs object. */ + ) + { + return *this; + } + + /** Evaluates the product of a given constraint with the current iterate. + * This function needs to be implemented in a derived class for the + * user-defined constraint product function. + * \return 0: successful \n + otherwise: not successful */ + virtual int_t operator() ( int_t constrIndex, /**< Number of constraint to be evaluated. */ + const real_t* const x, /**< Array containing current primal iterate. */ + real_t* const constrValue /**< Output: Scalar value of the evaluated constraint. */ + ) const = 0; +}; + +END_NAMESPACE_QPOASES + + +#endif /* QPOASES_CONSTRAINT_PRODUCT_HPP */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Constraints.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Constraints.hpp new file mode 100644 index 0000000..3497e9a --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Constraints.hpp @@ -0,0 +1,246 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Constraints.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the Constraints class designed to manage working sets of + * constraints within a QProblem. + */ + + +#ifndef QPOASES_CONSTRAINTS_HPP +#define QPOASES_CONSTRAINTS_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Manages working sets of constraints. + * + * This class manages working sets of constraints by storing + * index sets and other status information. + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + */ +class Constraints : public SubjectTo +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + Constraints( ); + + /** Constructor which takes the number of constraints. */ + Constraints( int_t _n /**< Number of constraints. */ + ); + + /** Copy constructor (deep copy). */ + Constraints( const Constraints& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~Constraints( ); + + /** Assignment operator (deep copy). */ + Constraints& operator=( const Constraints& rhs /**< Rhs object. */ + ); + + + /** Initialises object with given number of constraints. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS */ + returnValue init( int_t _n = 0 /**< Number of constraints. */ + ); + + + /** Initially adds number of a new (i.e. not yet in the list) constraint to + * a given index set. + * \return SUCCESSFUL_RETURN \n + RET_SETUP_CONSTRAINT_FAILED \n + RET_INDEX_OUT_OF_BOUNDS \n + RET_INVALID_ARGUMENTS */ + returnValue setupConstraint( int_t number, /**< Number of new constraint. */ + SubjectToStatus _status /**< Status of new constraint. */ + ); + + /** Initially adds all enabled numbers of new (i.e. not yet in the list) constraints to + * to the index set of inactive constraints; the order depends on the SujectToType + * of each index. Only disabled constraints are added to index set of disabled constraints! + * \return SUCCESSFUL_RETURN \n + RET_SETUP_CONSTRAINT_FAILED */ + returnValue setupAllInactive( ); + + /** Initially adds all enabled numbers of new (i.e. not yet in the list) constraints to + * to the index set of active constraints (on their lower bounds); the order depends on the SujectToType + * of each index. Only disabled constraints are added to index set of disabled constraints! + * \return SUCCESSFUL_RETURN \n + RET_SETUP_CONSTRAINT_FAILED */ + returnValue setupAllLower( ); + + /** Initially adds all enabled numbers of new (i.e. not yet in the list) constraints to + * to the index set of active constraints (on their upper bounds); the order depends on the SujectToType + * of each index. Only disabled constraints are added to index set of disabled constraints! + * \return SUCCESSFUL_RETURN \n + RET_SETUP_CONSTRAINT_FAILED */ + returnValue setupAllUpper( ); + + + /** Moves index of a constraint from index list of active to that of inactive constraints. + * \return SUCCESSFUL_RETURN \n + RET_MOVING_CONSTRAINT_FAILED */ + returnValue moveActiveToInactive( int_t number /**< Number of constraint to become inactive. */ + ); + + /** Moves index of a constraint from index list of inactive to that of active constraints. + * \return SUCCESSFUL_RETURN \n + RET_MOVING_CONSTRAINT_FAILED */ + returnValue moveInactiveToActive( int_t number, /**< Number of constraint to become active. */ + SubjectToStatus _status /**< Status of constraint to become active. */ + ); + + /** Flip fixed constraint. + * \return SUCCESSFUL_RETURN \n + RET_MOVING_CONSTRAINT_FAILED \n + RET_INDEX_OUT_OF_BOUNDS */ + returnValue flipFixed( int_t number ); + + + /** Returns the number of constraints. + * \return Number of constraints. */ + inline int_t getNC( ) const; + + /** Returns the number of implicit equality constraints. + * \return Number of implicit equality constraints. */ + inline int_t getNEC( ) const; + + /** Returns the number of "real" inequality constraints. + * \return Number of "real" inequality constraints. */ + inline int_t getNIC( ) const; + + /** Returns the number of unbounded constraints (i.e. without any bounds). + * \return Number of unbounded constraints (i.e. without any bounds). */ + inline int_t getNUC( ) const; + + /** Returns the number of active constraints. + * \return Number of active constraints. */ + inline int_t getNAC( ) const; + + /** Returns the number of inactive constraints. + * \return Number of inactive constraints. */ + inline int_t getNIAC( ) const; + + + /** Returns a pointer to active constraints index list. + * \return Pointer to active constraints index list. */ + inline Indexlist* getActive( ); + + /** Returns a pointer to inactive constraints index list. + * \return Pointer to inactive constraints index list. */ + inline Indexlist* getInactive( ); + + + /** Shifts forward type and status of all constraints by a given + * offset. This offset has to lie within the range [0,n/2] and has to + * be an integer divisor of the total number of constraints n. + * Type and status of the first \ constraints is thrown away, + * type and status of the last \ constraints is doubled, + * e.g. for offset = 2: \n + * shift( {c1,c2,c3,c4,c5,c6} ) = {c3,c4,c5,c6,c5,c6} + * \return SUCCESSFUL_RETURN \n + RET_INDEX_OUT_OF_BOUNDS \n + RET_INVALID_ARGUMENTS \n + RET_SHIFTING_FAILED */ + virtual returnValue shift( int_t offset /**< Shift offset within the range [0,n/2] and integer divisor of n. */ + ); + + /** Rotates forward type and status of all constraints by a given + * offset. This offset has to lie within the range [0,n]. + * Example for offset = 2: \n + * rotate( {c1,c2,c3,c4,c5,c6} ) = {c3,c4,c5,c6,c1,c2} + * \return SUCCESSFUL_RETURN \n + RET_INDEX_OUT_OF_BOUNDS \n + RET_ROTATING_FAILED */ + virtual returnValue rotate( int_t offset /**< Rotation offset within the range [0,n]. */ + ); + + + /** Prints information on constraints object + * (in particular, lists of inactive and active constraints. + * \return SUCCESSFUL_RETURN \n + RET_INDEXLIST_CORRUPTED */ + returnValue print( ); + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const Constraints& rhs /**< Rhs object. */ + ); + + + /** Initially adds all numbers of new (i.e. not yet in the list) bounds to + * to the index set corresponding to the desired status; + * the order depends on the SujectToType of each index. + * \return SUCCESSFUL_RETURN \n + RET_SETUP_CONSTRAINT_FAILED */ + returnValue setupAll( SubjectToStatus _status /**< Desired initial status for all bounds. */ + ); + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + Indexlist active; /**< Index list of active constraints. */ + Indexlist inactive; /**< Index list of inactive constraints. */ +}; + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_CONSTRAINTS_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Constraints.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/Constraints.ipp new file mode 100644 index 0000000..d5bd3aa --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Constraints.ipp @@ -0,0 +1,122 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Constraints.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of inlined member functions of the Constraints class designed + * to manage working sets of constraints within a QProblem. + */ + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * g e t N C + */ +inline int_t Constraints::getNC( ) const +{ + return n; +} + + +/* + * g e t N E C + */ +inline int_t Constraints::getNEC( ) const +{ + return getNumberOfType( ST_EQUALITY ); +} + + +/* + * g e t N I C + */ +inline int_t Constraints::getNIC( ) const +{ + return getNumberOfType( ST_BOUNDED ); +} + + +/* + * g e t N U C + */ +inline int_t Constraints::getNUC( ) const +{ + return getNumberOfType( ST_UNBOUNDED ); +} + + +/* + * g e t N A C + */ +inline int_t Constraints::getNAC( ) const +{ + return active.getLength( ); +} + + +/* + * g e t N I A C + */ +inline int_t Constraints::getNIAC( ) const +{ + return inactive.getLength( ); +} + + + +/* + * g e t A c t i v e + */ +inline Indexlist* Constraints::getActive( ) +{ + return &active; +} + + +/* + * g e t I n a c t i v e + */ +inline Indexlist* Constraints::getInactive( ) +{ + return &inactive; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Flipper.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Flipper.hpp new file mode 100644 index 0000000..f9bf78d --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Flipper.hpp @@ -0,0 +1,155 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Flipper.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the Options class designed to manage user-specified + * options for solving a QProblem. + */ + + +#ifndef QPOASES_FLIPPER_HPP +#define QPOASES_FLIPPER_HPP + + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Auxiliary class for storing a copy of the current matrix factorisations. + * + * This auxiliary class stores a copy of the current matrix factorisations. It + * is used by the classe QProblemB and QProblem in case flipping bounds are enabled. + * + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + */ +class Flipper +{ + friend class QProblemB; + friend class QProblem; + + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + Flipper( ); + + /** Constructor which takes the number of bounds and constraints. */ + Flipper( uint_t _nV, /**< Number of bounds. */ + uint_t _nC = 0 /**< Number of constraints. */ + ); + + /** Copy constructor (deep copy). */ + Flipper( const Flipper& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + ~Flipper( ); + + /** Assignment operator (deep copy). */ + Flipper& operator=( const Flipper& rhs /**< Rhs object. */ + ); + + + /** Initialises object with given number of bounds and constraints. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS */ + returnValue init( uint_t _nV = 0, /**< Number of bounds. */ + uint_t _nC = 0 /**< Number of constraints. */ + ); + + + /** Copies current values to non-null arguments (assumed to be allocated with consistent size). + * \return SUCCESSFUL_RETURN */ + returnValue get( Bounds* const _bounds, /**< Pointer to new bounds. */ + real_t* const R, /**< New matrix R. */ + Constraints* const _constraints = 0, /**< Pointer to new constraints. */ + real_t* const _Q = 0, /**< New matrix Q. */ + real_t* const _T = 0 /**< New matrix T. */ + ) const; + + /** Assigns new values to non-null arguments. + * \return SUCCESSFUL_RETURN */ + returnValue set( const Bounds* const _bounds, /**< Pointer to new bounds. */ + const real_t* const _R, /**< New matrix R. */ + const Constraints* const _constraints = 0, /**< Pointer to new constraints. */ + const real_t* const _Q = 0, /**< New matrix Q. */ + const real_t* const _T = 0 /**< New matrix T. */ + ); + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const Flipper& rhs /**< Rhs object. */ + ); + + /** Returns dimension of matrix T. + * \return Dimension of matrix T. */ + uint_t getDimT( ) const; + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + uint_t nV; /**< Number of variables. */ + uint_t nC; /**< Number of constraints. */ + + Bounds bounds; /**< Data structure for problem's bounds. */ + Constraints constraints; /**< Data structure for problem's constraints. */ + + real_t* R; /**< Cholesky factor of H (i.e. H = R^T*R). */ + real_t* Q; /**< Orthonormal quadratic matrix, A = [0 T]*Q'. */ + real_t* T; /**< Reverse triangular matrix, A = [0 T]*Q'. */ +}; + + +END_NAMESPACE_QPOASES + + +#endif /* QPOASES_FLIPPER_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Indexlist.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Indexlist.hpp new file mode 100644 index 0000000..94a2560 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Indexlist.hpp @@ -0,0 +1,199 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Indexlist.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the Indexlist class designed to manage index lists of + * constraints and bounds within a SubjectTo object. + */ + + +#ifndef QPOASES_INDEXLIST_HPP +#define QPOASES_INDEXLIST_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Stores and manages index lists. + * + * This class manages index lists of active/inactive bounds/constraints. + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + */ +class Indexlist +{ + /* + * FRIENDS + */ + friend class DenseMatrix; + friend class SymDenseMat; + friend class SparseMatrix; + friend class SparseMatrixRow; + friend class SymSparseMat; + + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + Indexlist( ); + + /** Constructor which takes the desired physical length of the index list. */ + Indexlist( int_t n /**< Physical length of index list. */ + ); + + /** Copy constructor (deep copy). */ + Indexlist( const Indexlist& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + ~Indexlist( ); + + /** Assingment operator (deep copy). */ + Indexlist& operator=( const Indexlist& rhs /**< Rhs object. */ + ); + + + /** Initialises index list of desired physical length. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS */ + returnValue init( int_t n = 0 /**< Physical length of index list. */ + ); + + + /** Creates an array of all numbers within the index set in correct order. + * \return SUCCESSFUL_RETURN \n + RET_INDEXLIST_CORRUPTED */ + returnValue getNumberArray( int_t** const numberarray /**< Output: Array of numbers (NULL on error). */ + ) const; + + /** Creates an array of all numbers within the index set in correct order. + * \return SUCCESSFUL_RETURN \n + RET_INDEXLIST_CORRUPTED */ + returnValue getISortArray( int_t** const iSortArray /**< Output: iSort Array. */ + ) const; + + + /** Determines the index within the index list at which a given number is stored. + * \return >= 0: Index of given number. \n + -1: Number not found. */ + int_t getIndex( int_t givennumber /**< Number whose index shall be determined. */ + ) const; + + /** Returns the number stored at a given physical index. + * \return >= 0: Number stored at given physical index. \n + -RET_INDEXLIST_OUTOFBOUNDS */ + int_t getNumber( int_t physicalindex /**< Physical index of the number to be returned. */ + ) const; + + + /** Returns the current length of the index list. + * \return Current length of the index list. */ + inline int_t getLength( ) const; + + /** Returns last number within the index list. + * \return Last number within the index list. */ + inline int_t getLastNumber( ) const; + + + /** Adds number to index list. + * \return SUCCESSFUL_RETURN \n + RET_INDEXLIST_MUST_BE_REORDERD \n + RET_INDEXLIST_EXCEEDS_MAX_LENGTH */ + returnValue addNumber( int_t addnumber /**< Number to be added. */ + ); + + /** Removes number from index list. + * \return SUCCESSFUL_RETURN */ + returnValue removeNumber( int_t removenumber /**< Number to be removed. */ + ); + + /** Swaps two numbers within index list. + * \return SUCCESSFUL_RETURN */ + returnValue swapNumbers( int_t number1, /**< First number for swapping. */ + int_t number2 /**< Second number for swapping. */ + ); + + /** Determines if a given number is contained in the index set. + * \return BT_TRUE iff number is contain in the index set */ + inline BooleanType isMember( int_t _number /**< Number to be tested for membership. */ + ) const; + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const Indexlist& rhs /**< Rhs object. */ + ); + + /** Find first index j between -1 and length in sorted list of indices + * iSort such that numbers[iSort[j]] <= i < numbers[iSort[j+1]]. Uses + * bisection. + * \return j. */ + int_t findInsert( int_t i + ) const; + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + int_t* number; /**< Array to store numbers of constraints or bounds. */ + int_t* iSort; /**< Index list to sort vector \a number */ + + int_t length; /**< Length of index list. */ + int_t first; /**< Physical index of first element. */ + int_t last; /**< Physical index of last element. */ + int_t lastusedindex; /**< Physical index of last entry in index list. */ + int_t physicallength; /**< Physical length of index list. */ +}; + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_INDEXLIST_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Indexlist.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/Indexlist.ipp new file mode 100644 index 0000000..178252f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Indexlist.ipp @@ -0,0 +1,92 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Indexlist.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of inlined member functions of the Indexlist class designed + * to manage index lists of constraints and bounds within a QProblem_SubjectTo. + */ + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * g e t N u m b e r + */ +inline int_t Indexlist::getNumber( int_t physicalindex ) const +{ + /* consistency check */ + if ( ( physicalindex < 0 ) || ( physicalindex > length ) ) + return -RET_INDEXLIST_OUTOFBOUNDS; + + return number[physicalindex]; +} + + +/* + * g e t L e n g t h + */ +inline int_t Indexlist::getLength( ) const +{ + return length; +} + + +/* + * g e t L a s t N u m b e r + */ +inline int_t Indexlist::getLastNumber( ) const +{ + return number[length-1]; +} + + +/* + * g e t L a s t N u m b e r + */ +inline BooleanType Indexlist::isMember( int_t _number ) const +{ + if ( getIndex( _number ) >= 0 ) + return BT_TRUE; + else + return BT_FALSE; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/LapackBlasReplacement.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/LapackBlasReplacement.hpp new file mode 100644 index 0000000..2c34c58 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/LapackBlasReplacement.hpp @@ -0,0 +1,128 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/LapackBlasReplacement.hpp + * \author Andreas Potschka, Hans Joachim Ferreau, Christian Kirches + * \version 3.2 + * \date 2009-2017 + * + * Declarations for external LAPACK/BLAS functions. + */ + + + +#ifndef QPOASES_LAPACKBLASREPLACEMENT_HPP +#define QPOASES_LAPACKBLASREPLACEMENT_HPP + + +#ifdef __AVOID_LA_NAMING_CONFLICTS__ + + #define SGEMM qpOASES_sgemm + #define DGEMM qpOASES_gemm + #define SPOTRF qpOASES_spotrf + #define DPOTRF qpOASES_dpotrf + #define STRTRS qpOASES_strtrs + #define DTRTRS qpOASES_dtrtrs + #define STRCON qpOASES_strcon + #define DTRCON qpOASES_dtrcon + +#else + + #define SGEMM sgemm_ + #define DGEMM dgemm_ + #define SPOTRF spotrf_ + #define DPOTRF dpotrf_ + #define STRTRS strtrs_ + #define DTRTRS dtrtrs_ + #define STRCON strcon_ + #define DTRCON dtrcon_ + +#endif + + +#ifdef __USE_SINGLE_PRECISION__ + + /** Macro for calling level 3 BLAS operation in single precision. */ + #define GEMM SGEMM + /** Macro for calling level 3 BLAS operation in single precision. */ + #define POTRF SPOTRF + + /** Macro for calling level 3 BLAS operation in single precision. */ + #define TRTRS STRTRS + /** Macro for calling level 3 BLAS operation in single precision. */ + #define TRCON strcon_ + +#else + + /** Macro for calling level 3 BLAS operation in double precision. */ + #define GEMM DGEMM + /** Macro for calling level 3 BLAS operation in double precision. */ + #define POTRF DPOTRF + + /** Macro for calling level 3 BLAS operation in double precision. */ + #define TRTRS DTRTRS + /** Macro for calling level 3 BLAS operation in double precision. */ + #define TRCON DTRCON + +#endif /* __USE_SINGLE_PRECISION__ */ + + +extern "C" +{ + /** Performs one of the matrix-matrix operation in double precision. */ + void DGEMM( const char*, const char*, const la_uint_t*, const la_uint_t*, const la_uint_t*, + const double*, const double*, const la_uint_t*, const double*, const la_uint_t*, + const double*, double*, const la_uint_t* ); + /** Performs one of the matrix-matrix operation in single precision. */ + void SGEMM( const char*, const char*, const la_uint_t*, const la_uint_t*, const la_uint_t*, + const float*, const float*, const la_uint_t*, const float*, const la_uint_t*, + const float*, float*, const la_uint_t* ); + + /** Calculates the Cholesky factorization of a real symmetric positive definite matrix in double precision. */ + void DPOTRF( const char*, const la_uint_t*, double*, const la_uint_t*, la_int_t* ); + /** Calculates the Cholesky factorization of a real symmetric positive definite matrix in single precision. */ + void SPOTRF( const char*, const la_uint_t*, float*, const la_uint_t*, la_int_t* ); + + /** Solves a triangular system (double precision) */ + void DTRTRS( const char* UPLO, const char* TRANS, const char* DIAG, const la_uint_t* N, const la_uint_t* NRHS, + double* A, const la_uint_t* LDA, double* B, const la_uint_t* LDB, la_int_t* INFO ); + /** Solves a triangular system (single precision) */ + void STRTRS( const char* UPLO, const char* TRANS, const char* DIAG, const la_uint_t* N, const la_uint_t* NRHS, + float* A, const la_uint_t* LDA, float* B, const la_uint_t* LDB, la_int_t* INFO ); + + /** Estimate the reciprocal of the condition number of a triangular matrix in double precision */ + void DTRCON( const char* NORM, const char* UPLO, const char* DIAG, const la_uint_t* N, double* A, const la_uint_t* LDA, + double* RCOND, double* WORK, const la_uint_t* IWORK, la_int_t* INFO ); + /** Estimate the reciprocal of the condition number of a triangular matrix in single precision */ + void STRCON( const char* NORM, const char* UPLO, const char* DIAG, const la_uint_t* N, float* A, const la_uint_t* LDA, + float* RCOND, float* WORK, const la_uint_t* IWORK, la_int_t* INFO ); +} + +#endif /* QPOASES_LAPACKBLASREPLACEMENT_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Matrices.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Matrices.hpp new file mode 100644 index 0000000..960bca8 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Matrices.hpp @@ -0,0 +1,984 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Matrices.hpp + * \author Andreas Potschka, Hans Joachim Ferreau, Christian Kirches + * \version 3.2 + * \date 2009-2017 + * + * Various matrix classes: Abstract base matrix class, dense and sparse matrices, + * including symmetry exploiting specializations. + */ + + + +#ifndef QPOASES_MATRICES_HPP +#define QPOASES_MATRICES_HPP + + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + + /** + * \brief Abstract base class for interfacing tailored matrix-vector operations. + * + * Abstract base matrix class. Supplies interface to matrix vector + * products, including products with submatrices given by (ordered) working set + * index lists (see \a SubjectTo). + * + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + */ +class Matrix +{ + public: + /** Default constructor. */ + Matrix( ) { doNotFreeMemory(); }; + + /** Destructor. */ + virtual ~Matrix( ) { }; + + /** Frees all internal memory. */ + virtual void free( ) = 0; + + /** Returns a deep-copy of the Matrix object. + * \return Deep-copy of Matrix object */ + virtual Matrix* duplicate( ) const = 0; + + /** Returns i-th diagonal entry. + * \return i-th diagonal entry */ + virtual real_t diag( int_t i /**< Index. */ + ) const = 0; + + /** Checks whether matrix is square and diagonal. + * \return BT_TRUE iff matrix is square and diagonal; \n + * BT_FALSE otherwise. */ + virtual BooleanType isDiag( ) const = 0; + + /** Get the N-norm of the matrix + * \return N-norm of the matrix + */ + virtual real_t getNorm( int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const = 0; + + /** Get the N-norm of a row + * \return N-norm of row \a rNum + */ + virtual real_t getRowNorm( int_t rNum, /**< Row number. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const = 0; + + /** Get the N-norm of all rows + * \return SUCCESSFUL_RETURN */ + virtual returnValue getRowNorm( real_t* norm, /**< Norm of each row. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const = 0; + + /** Retrieve indexed entries of matrix row multiplied by alpha. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getRow( int_t rNum, /**< Row number. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + real_t alpha, /**< Scalar factor. */ + real_t* row /**< Output row vector. */ + ) const = 0; + + /** Retrieve indexed entries of matrix column multiplied by alpha. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getCol( int_t cNum, /**< Column number. */ + const Indexlist* const irows, /**< Index list specifying rows. */ + real_t alpha, /**< Scalar factor. */ + real_t* col /**< Output column vector. */ + ) const = 0; + + /** Retrieve entries of submatrix in Harwell-Boeing sparse format. + * If irn, jcn, and avals are null, this only counts the number of nonzeros. + * Otherwise, numNonzeros containts the size of irn, jcn, and avals on entry, + * and the written number of entries on return. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getSparseSubmatrix( + const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t rowoffset, /**< Offset for row entries. */ + int_t coloffset, /**< Offset for row entries. */ + int_t& numNonzeros, /**< Number of nonzeros in submatrix. */ + int_t* irn, /**< Row position of entries (as position in irows) plus rowoffset. */ + int_t* jcn, /**< Column position of entries (as position in irows) plus coloffset. */ + real_t* avals, /**< Numerical values of the entries. */ + BooleanType only_lower_triangular = BT_FALSE /**< if true, only the lower triangular portion is returned. This can only be true for symmetric matrices and if irows==jcols. */ + ) const; + + /** Retrieve entries of submatrix in Harwell-Boeing sparse format. + * If irn, jcn, and avals are null, this only counts the number of nonzeros. + * Otherwise, numNonzeros containts the size of irn, jcn, and avals on entry, + * and the written number of entries on return. This version retrieves one + * column. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getSparseSubmatrix( + const Indexlist* const irows, /**< Index list specifying rows. */ + int_t idx_icol, /**< Index list specifying columns. */ + int_t rowoffset, /**< Offset for row entries. */ + int_t coloffset, /**< Offset for row entries. */ + int_t& numNonzeros, /**< Number of nonzeros in submatrix. */ + int_t* irn, /**< Row position of entries (as position in irows) plus rowoffset. */ + int_t* jcn, /**< Column position of entries (as position in irows) plus coloffset. */ + real_t* avals, /**< Numerical values of the entries. */ + BooleanType only_lower_triangular = BT_FALSE /**< if true, only the lower triangular portion is returned. This can only be true for symmetric matrices and if irows==jcols. */ + ) const; + + /** Retrieve entries of submatrix in Harwell-Boeing sparse format. + * If irn, jcn, and avals are null, this only counts the number of nonzeros. + * Otherwise, numNonzeros containts the size of irn, jcn, and avals on entry, + * and the written number of entries on return. This version retrieves one row. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getSparseSubmatrix( + int_t idx_row, /**< Row number. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t rowoffset, /**< Offset for row entries. */ + int_t coloffset, /**< Offset for row entries. */ + int_t& numNonzeros, /**< Number of nonzeros in submatrix. */ + int_t* irn, /**< Row position of entries (as position in irows) plus rowoffset. */ + int_t* jcn, /**< Column position of entries (as position in irows) plus coloffset. */ + real_t* avals, /**< Numerical values of the entries. */ + BooleanType only_lower_triangular = BT_FALSE /**< if true, only the lower triangular portion is returned. This can only be true for symmetric matrices and if irows==jcols. */ + ) const; + + /** Retrieve entries of submatrix in Harwell-Boeing sparse format. + * If irn, jcn, and avals are null, this only counts the number of nonzeros. + * Otherwise, numNonzeros containts the size of irn, jcn, and avals on entry, + * and the written number of entries on return. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getSparseSubmatrix( + int_t irowsLength, /**< Number of rows. */ + const int_t* const irowsNumber, /**< Array with row numbers. */ + int_t icolsLength, /**< Number of columns. */ + const int_t* const icolsNumber, /**< Array with column numbers. */ + int_t rowoffset, /**< Offset for row entries. */ + int_t coloffset, /**< Offset for row entries. */ + int_t& numNonzeros, /**< Number of nonzeros in submatrix. */ + int_t* irn, /**< Row position of entries (as position in irows) plus rowoffset. */ + int_t* jcn, /**< Column position of entries (as position in irows) plus coloffset. */ + real_t* avals, /**< Numerical values of the entries. */ + BooleanType only_lower_triangular = BT_FALSE /**< if true, only the lower triangular portion is returned. This can only be true for symmetric matrices and if irows==jcols. */ + ) const = 0; + + /** Evaluate Y=alpha*A*X + beta*Y. + * \return SUCCESSFUL_RETURN */ + virtual returnValue times ( int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const = 0; + + /** Evaluate Y=alpha*A'*X + beta*Y. + * \return SUCCESSFUL_RETURN */ + virtual returnValue transTimes ( int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const = 0; + + /** Evaluate matrix vector product with submatrix given by Indexlist. + * \return SUCCESSFUL_RETURN */ + virtual returnValue times ( const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD, /**< Leading dimension of output y. */ + BooleanType yCompr = BT_TRUE /**< Compressed storage for y. */ + ) const = 0; + + /** Evaluate matrix transpose vector product. + * \return SUCCESSFUL_RETURN */ + virtual returnValue transTimes ( const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const = 0; + + /** Adds given offset to diagonal of matrix. + * \return SUCCESSFUL_RETURN \n + RET_NO_DIAGONAL_AVAILABLE */ + virtual returnValue addToDiag( real_t alpha /**< Diagonal offset. */ + ) = 0; + + /** Allocates and creates dense matrix array in row major format. + * + * Note: Calling function has to free allocated memory! + * + * \return Pointer to matrix array. + */ + virtual real_t* full() const = 0; + + + /** Prints matrix to screen. + * \return SUCCESSFUL_RETURN */ + virtual returnValue print( const char* name = 0 /** Name of matrix. */ + ) const = 0; + + /** Write matrix to file. + * \return SUCCESSFUL_RETURN */ + virtual returnValue writeToFile( FILE* output_file, const char* prefix ) const = 0; + + /** Returns whether internal memory needs to be de-allocated. + * \return BT_TRUE iff internal memory needs to be de-allocated, \n + BT_FALSE otherwise */ + BooleanType needToFreeMemory( ) const { return freeMemory; }; + + /** Enables de-allocation of internal memory. */ + void doFreeMemory( ) { freeMemory = BT_TRUE; }; + + /** Disables de-allocation of internal memory. */ + void doNotFreeMemory( ) { freeMemory = BT_FALSE; }; + + + protected: + BooleanType freeMemory; /**< Indicating whether internal memory needs to be de-allocated. */ + +}; + + +/** + * \brief Abstract base class for interfacing matrix-vector operations tailored to symmetric matrices. + * + * Abstract base class for symmetric matrices. Extends Matrix interface with + * bilinear form evaluation. + * + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + */ +class SymmetricMatrix : public virtual Matrix +{ + public: + /** Default constructor. */ + SymmetricMatrix( ) { }; + + /** Destructor. */ + virtual ~SymmetricMatrix( ) { }; + + /** Returns a deep-copy of the SymmetricMatrix object. + * \return Deep-copy of SymmetricMatrix object */ + virtual SymmetricMatrix* duplicateSym( ) const = 0; + + + /** Compute bilinear form y = x'*H*x using submatrix given by index list. + * \return SUCCESSFUL_RETURN */ + virtual returnValue bilinear( const Indexlist* const icols, /**< Index list specifying columns of x. */ + int_t xN, /**< Number of vectors to multiply. */ + const real_t* x, /**< Input vector to be multiplied (uncompressed). */ + int_t xLD, /**< Leading dimension of input x. */ + real_t* y, /**< Output vector of results (compressed). */ + int_t yLD /**< Leading dimension of output y. */ + ) const = 0; + +}; + + +/** + * \brief Interfaces matrix-vector operations tailored to general dense matrices. + * + * Dense matrix class (row major format). + * + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + */ +class DenseMatrix : public virtual Matrix +{ + public: + /** Default constructor. */ + DenseMatrix( ) : nRows(0), nCols(0), leaDim(0), val(0) { }; + + /** Constructor from vector of values. + * Caution: Data pointer must be valid throughout lifetime + */ + DenseMatrix( int_t m, /**< Number of rows. */ + int_t n, /**< Number of columns. */ + int_t lD, /**< Leading dimension. */ + real_t* v /**< Values. */ + ) : nRows(m), nCols(n), leaDim(lD), val(v) {} + + + /** Destructor. */ + virtual ~DenseMatrix( ); + + /** Frees all internal memory. */ + virtual void free( ); + + /** Returns a deep-copy of the Matrix object. + * \return Deep-copy of Matrix object */ + virtual Matrix *duplicate( ) const; + + /** Returns i-th diagonal entry. + * \return i-th diagonal entry */ + virtual real_t diag( int_t i /**< Index. */ + ) const; + + /** Checks whether matrix is square and diagonal. + * \return BT_TRUE iff matrix is square and diagonal; \n + * BT_FALSE otherwise. */ + virtual BooleanType isDiag( ) const; + + /** Get the N-norm of the matrix + * \return N-norm of the matrix + */ + virtual real_t getNorm( int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Get the N-norm of a row + * \return N-norm of row \a rNum + */ + virtual real_t getRowNorm( int_t rNum, /**< Row number. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Get the N-norm of all rows + * \return SUCCESSFUL_RETURN */ + virtual returnValue getRowNorm( real_t* norm, /**< Norm of each row. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Retrieve indexed entries of matrix row multiplied by alpha. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getRow( int_t rNum, /**< Row number. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + real_t alpha, /**< Scalar factor. */ + real_t* row /**< Output row vector. */ + ) const; + + /** Retrieve indexed entries of matrix column multiplied by alpha. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getCol( + int_t cNum, /**< Column number. */ + const Indexlist* const irows, /**< Index list specifying rows. */ + real_t alpha, /**< Scalar factor. */ + real_t* col /**< Output column vector. */ + ) const; + + /** Retrieve entries of submatrix in Harwell-Boeing sparse format. + * If irn, jcn, and avals are null, this only counts the number of nonzeros. + * Otherwise, numNonzeros containts the size of irn, jcn, and avals on entry, + * and the written number of entries on return. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getSparseSubmatrix( + int_t irowsLength, /**< Number of rows. */ + const int_t* const irowsNumber, /**< Array with row numbers. */ + int_t icolsLength, /**< Number of columns. */ + const int_t* const icolsNumber, /**< Array with column numbers. */ + int_t rowoffset, /**< Offset for row entries. */ + int_t coloffset, /**< Offset for row entries. */ + int_t& numNonzeros, /**< Number of nonzeros in submatrix. */ + int_t* irn, /**< Row position of entries (as position in irows) plus rowoffset. */ + int_t* jcn, /**< Column position of entries (as position in irows) plus coloffset. */ + real_t* avals, /**< Numerical values of the entries. */ + BooleanType only_lower_triangular = BT_FALSE /**< if true, only the lower triangular portion is returned. This can only be true for symmetric matrices and if irows==jcols. */ + ) const; + + + /** Evaluate Y=alpha*A*X + beta*Y. + * \return SUCCESSFUL_RETURN. */ + virtual returnValue times( int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Evaluate Y=alpha*A'*X + beta*Y. + * \return SUCCESSFUL_RETURN. */ + virtual returnValue transTimes( int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Evaluate matrix vector product with submatrix given by Indexlist. + * \return SUCCESSFUL_RETURN */ + virtual returnValue times( const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD, /**< Leading dimension of output y. */ + BooleanType yCompr = BT_TRUE /**< Compressed storage for y. */ + ) const; + + /** Evaluate matrix transpose vector product. + * \return SUCCESSFUL_RETURN */ + virtual returnValue transTimes( const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Adds given offset to diagonal of matrix. + * \return SUCCESSFUL_RETURN \n + RET_NO_DIAGONAL_AVAILABLE */ + virtual returnValue addToDiag( real_t alpha /**< Diagonal offset. */ + ); + + + /** Allocates and creates dense matrix array in row major format. + * + * Note: Calling function has to free allocated memory! + * + * \return Pointer to matrix array. + */ + virtual real_t* full() const; + + + /** Prints matrix to screen. + * \return SUCCESSFUL_RETURN */ + virtual returnValue print( const char* name = 0 /** Name of matrix. */ + ) const; + + /** Write matrix to file. + * \return SUCCESSFUL_RETURN */ + virtual returnValue writeToFile( FILE* output_file, const char* prefix ) const; + + protected: + int_t nRows; /**< Number of rows. */ + int_t nCols; /**< Number of columns. */ + int_t leaDim; /**< Leading dimension. */ + real_t* val; /**< Vector of entries. */ +}; + + +/** + * \brief Interfaces matrix-vector operations tailored to symmetric dense matrices. + * + * Symmetric dense matrix class. + * + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + */ +class SymDenseMat : public DenseMatrix, public SymmetricMatrix +{ + public: + /** Default constructor. */ + SymDenseMat() : DenseMatrix() { }; + + /** Constructor from vector of values. */ + SymDenseMat( int_t m, /**< Number of rows. */ + int_t n, /**< Number of columns. */ + int_t lD, /**< Leading dimension. */ + real_t* v /**< Values. */ + ) : DenseMatrix(m, n, lD, v) { }; + + /** Destructor. */ + virtual ~SymDenseMat() { }; + + /** Returns a deep-copy of the Matrix object. + * \return Deep-copy of Matrix object */ + virtual Matrix *duplicate( ) const; + + /** Returns a deep-copy of the SymmetricMatrix object. + * \return Deep-copy of SymmetricMatrix object */ + virtual SymmetricMatrix* duplicateSym( ) const; + + + /** Compute bilinear form y = x'*H*x using submatrix given by index list. + * \return SUCCESSFUL_RETURN */ + virtual returnValue bilinear( const Indexlist* const icols, /**< Index list specifying columns of x. */ + int_t xN, /**< Number of vectors to multiply. */ + const real_t* x, /**< Input vector to be multiplied (uncompressed). */ + int_t xLD, /**< Leading dimension of input x. */ + real_t* y, /**< Output vector of results (compressed). */ + int_t yLD /**< Leading dimension of output y. */ + ) const; +}; + + +/** + * \brief Interfaces matrix-vector operations tailored to general sparse matrices. + * + * Sparse matrix class (col compressed format). + * + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + */ +class SparseMatrix : public virtual Matrix +{ + public: + /** Default constructor. */ + SparseMatrix( ); + + /** Constructor with arguments. */ + SparseMatrix( int_t nr, /**< Number of rows. */ + int_t nc, /**< Number of columns. */ + sparse_int_t* r, /**< Row indices (length). */ + sparse_int_t* c, /**< Indices to first entry of columns (nCols+1). */ + real_t* v /**< Vector of entries (length). */ + ); + + /** Constructor from dense matrix. */ + SparseMatrix( int_t nr, /**< Number of rows. */ + int_t nc, /**< Number of columns. */ + int_t ld, /**< Leading dimension. */ + const real_t* const v /**< Row major stored matrix elements. */ + ); + + /** Destructor. */ + virtual ~SparseMatrix( ); + + /** Frees all internal memory. */ + virtual void free( ); + + /** Returns a deep-copy of the Matrix object. + * \return Deep-copy of Matrix object */ + virtual Matrix *duplicate( ) const; + + + /** Sets value array. + * + * Thanks to Frank Chuang. + */ + virtual void setVal( const real_t* newVal /**< ... */ + ); + + /** Returns i-th diagonal entry. + * \return i-th diagonal entry (or INFTY if diagonal does not exist)*/ + virtual real_t diag( int_t i /**< Index. */ + ) const; + + /** Checks whether matrix is square and diagonal. + * \return BT_TRUE iff matrix is square and diagonal; \n + * BT_FALSE otherwise. */ + virtual BooleanType isDiag( ) const; + + + /** Get the N-norm of the matrix + * \return N-norm of the matrix + */ + virtual real_t getNorm( int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Get the N-norm of a row + * \return N-norm of row \a rNum + */ + virtual real_t getRowNorm( int_t rNum, /**< Row number. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Get the N-norm of all rows + * \return SUCCESSFUL_RETURN */ + virtual returnValue getRowNorm( real_t* norm, /**< Norm of each row. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Retrieve indexed entries of matrix row multiplied by alpha. */ + virtual returnValue getRow( int_t rNum, /**< Row number. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + real_t alpha, /**< Scalar factor. */ + real_t* row /**< Output row vector. */ + ) const; + + /** Retrieve indexed entries of matrix column multiplied by alpha. */ + virtual returnValue getCol( int_t cNum, /**< Column number. */ + const Indexlist* const irows, /**< Index list specifying rows. */ + real_t alpha, /**< Scalar factor. */ + real_t* col /**< Output column vector. */ + ) const; + + /** Retrieve entries of submatrix in Harwell-Boeing sparse format. + * If irn, jcn, and avals are null, this only counts the number of nonzeros. + * Otherwise, numNonzeros containts the size of irn, jcn, and avals on entry, + * and the written number of entries on return. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getSparseSubmatrix( + int_t irowsLength, /**< Number of rows. */ + const int_t* const irowsNumber, /**< Array with row numbers. */ + int_t icolsLength, /**< Number of columns. */ + const int_t* const icolsNumber, /**< Array with column numbers. */ + int_t rowoffset, /**< Offset for row entries. */ + int_t coloffset, /**< Offset for row entries. */ + int_t& numNonzeros, /**< Number of nonzeros in submatrix. */ + int_t* irn, /**< Row position of entries (as position in irows) plus rowoffset. */ + int_t* jcn, /**< Column position of entries (as position in irows) plus coloffset. */ + real_t* avals, /**< Numerical values of the entries. */ + BooleanType only_lower_triangular = BT_FALSE /**< if true, only the lower triangular portion is returned. This can only be true for symmetric matrices and if irows==jcols. */ + ) const; + + /** Evaluate Y=alpha*A*X + beta*Y. */ + virtual returnValue times ( int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Evaluate Y=alpha*A'*X + beta*Y. */ + virtual returnValue transTimes ( int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Evaluate matrix vector product with submatrix given by Indexlist. */ + virtual returnValue times ( const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD, /**< Leading dimension of output y. */ + BooleanType yCompr = BT_TRUE /**< Compressed storage for y. */ + ) const; + + /** Evaluate matrix transpose vector product. */ + virtual returnValue transTimes ( const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Adds given offset to diagonal of matrix. + * \return SUCCESSFUL_RETURN \n + RET_NO_DIAGONAL_AVAILABLE */ + virtual returnValue addToDiag( real_t alpha /**< Diagonal offset. */ + ); + + /** Create jd field from ir and jc. + * \return Pointer to jd. */ + sparse_int_t* createDiagInfo(); + + /** Allocates and creates dense matrix array in row major format. + * + * Note: Calling function has to free allocated memory! + * + * \return Pointer to matrix array. + */ + virtual real_t* full() const; + + /** Prints matrix to screen. + * \return SUCCESSFUL_RETURN */ + virtual returnValue print( const char* name = 0 /** Name of matrix. */ + ) const; + + /** Write matrix to file. + * \return SUCCESSFUL_RETURN */ + virtual returnValue writeToFile( FILE* output_file, const char* prefix ) const; + + + protected: + int_t nRows; /**< Number of rows. */ + int_t nCols; /**< Number of columns. */ + sparse_int_t* ir; /**< Row indices (length). */ + sparse_int_t* jc; /**< Indices to first entry of columns (nCols+1). */ + sparse_int_t* jd; /**< Indices to first entry of lower triangle (including diagonal) (nCols). */ + real_t* val; /**< Vector of entries (length). */ +}; + + +/** + * \brief Interfaces matrix-vector operations tailored to general sparse matrices. + * + * Sparse matrix class (row compressed format). + * + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + */ +class SparseMatrixRow : public virtual Matrix +{ + public: + /** Default constructor. */ + SparseMatrixRow( ); + + /** Constructor with arguments. */ + SparseMatrixRow( int_t nr, /**< Number of rows. */ + int_t nc, /**< Number of columns. */ + sparse_int_t* r, /**< Indices to first entry of rows (nRows+1). */ + sparse_int_t* c, /**< Column indices (length). */ + real_t* v /**< Vector of entries (length). */ + ); + + /** Constructor from dense matrix. */ + SparseMatrixRow( int_t nr, /**< Number of rows. */ + int_t nc, /**< Number of columns. */ + int_t ld, /**< Leading dimension. */ + const real_t* const v /**< Row major stored matrix elements. */ + ); + + /** Destructor. */ + virtual ~SparseMatrixRow( ); + + /** Frees all internal memory. */ + virtual void free( ); + + /** Returns a deep-copy of the Matrix object. + * \return Deep-copy of Matrix object */ + virtual Matrix *duplicate( ) const; + + /** Returns i-th diagonal entry. + * \return i-th diagonal entry (or INFTY if diagonal does not exist)*/ + virtual real_t diag( int_t i /**< Index. */ + ) const; + + /** Checks whether matrix is square and diagonal. + * \return BT_TRUE iff matrix is square and diagonal; \n + * BT_FALSE otherwise. */ + virtual BooleanType isDiag( ) const; + + + /** Get the N-norm of the matrix + * \return N-norm of the matrix + */ + virtual real_t getNorm( int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Get the N-norm of a row + * \return N-norm of row \a rNum + */ + virtual real_t getRowNorm( int_t rNum, /**< Row number. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Get the N-norm of all rows + * \return SUCCESSFUL_RETURN */ + virtual returnValue getRowNorm( real_t* norm, /**< Norm of each row. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ) const; + + /** Retrieve indexed entries of matrix row multiplied by alpha. */ + virtual returnValue getRow ( int_t rNum, /**< Row number. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + real_t alpha, /**< Scalar factor. */ + real_t* row /**< Output row vector. */ + ) const; + + /** Retrieve indexed entries of matrix column multiplied by alpha. */ + virtual returnValue getCol ( int_t cNum, /**< Column number. */ + const Indexlist* const irows, /**< Index list specifying rows. */ + real_t alpha, /**< Scalar factor. */ + real_t* col /**< Output column vector. */ + ) const; + + /** Retrieve entries of submatrix in Harwell-Boeing sparse format. + * If irn, jcn, and avals are null, this only counts the number of nonzeros. + * Otherwise, numNonzeros containts the size of irn, jcn, and avals on entry, + * and the written number of entries on return. + * \return SUCCESSFUL_RETURN */ + virtual returnValue getSparseSubmatrix( + int_t irowsLength, /**< Number of rows. */ + const int_t* const irowsNumber, /**< Array with row numbers. */ + int_t icolsLength, /**< Number of columns. */ + const int_t* const icolsNumber, /**< Array with column numbers. */ + int_t rowoffset, /**< Offset for row entries. */ + int_t coloffset, /**< Offset for row entries. */ + int_t& numNonzeros, /**< Number of nonzeros in submatrix. */ + int_t* irn, /**< Row position of entries (as position in irows) plus rowoffset. */ + int_t* jcn, /**< Column position of entries (as position in irows) plus coloffset. */ + real_t* avals, /**< Numerical values of the entries. */ + BooleanType only_lower_triangular = BT_FALSE /**< if true, only the lower triangular portion is returned. This can only be true for symmetric matrices and if irows==jcols. */ + ) const; + + /** Evaluate Y=alpha*A*X + beta*Y. */ + virtual returnValue times( int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Evaluate Y=alpha*A'*X + beta*Y. */ + virtual returnValue transTimes( int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Evaluate matrix vector product with submatrix given by Indexlist. */ + virtual returnValue times( const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD, /**< Leading dimension of output y. */ + BooleanType yCompr = BT_TRUE /**< Compressed storage for y. */ + ) const; + + /** Evaluate matrix transpose vector product. */ + virtual returnValue transTimes( const Indexlist* const irows, /**< Index list specifying rows. */ + const Indexlist* const icols, /**< Index list specifying columns. */ + int_t xN, /**< Number of vectors to multiply. */ + real_t alpha, /**< Scalar factor for matrix vector product. */ + const real_t* x, /**< Input vector to be multiplied. */ + int_t xLD, /**< Leading dimension of input x. */ + real_t beta, /**< Scalar factor for y. */ + real_t* y, /**< Output vector of results. */ + int_t yLD /**< Leading dimension of output y. */ + ) const; + + /** Adds given offset to diagonal of matrix. + * \return SUCCESSFUL_RETURN \n + RET_NO_DIAGONAL_AVAILABLE */ + virtual returnValue addToDiag( real_t alpha /**< Diagonal offset. */ + ); + + /** Create jd field from ir and jc. + * \return Pointer to jd. */ + sparse_int_t* createDiagInfo(); + + /** Allocates and creates dense matrix array in row major format. + * + * Note: Calling function has to free allocated memory! + * + * \return Pointer to matrix array. + */ + virtual real_t* full() const; + + /** Prints matrix to screen. + * \return SUCCESSFUL_RETURN */ + virtual returnValue print( const char* name = 0 /** Name of matrix. */ + ) const; + + /** Write matrix to file. + * \return SUCCESSFUL_RETURN */ + virtual returnValue writeToFile( FILE* output_file, const char* prefix ) const; + + protected: + int_t nRows; /**< Number of rows. */ + int_t nCols; /**< Number of columns. */ + sparse_int_t* jr; /**< Indices to first entry of row (nRows+1). */ + sparse_int_t* ic; /**< Column indices (length). */ + sparse_int_t* jd; /**< Indices to first entry of upper triangle (including diagonal) (nRows). */ + real_t* val; /**< Vector of entries (length). */ +}; + + +/** + * \brief Interfaces matrix-vector operations tailored to symmetric sparse matrices. + * + * Symmetric sparse matrix class (column compressed format). + * + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + */ +class SymSparseMat : public SymmetricMatrix, public SparseMatrix +{ + public: + /** Default constructor. */ + SymSparseMat( ) : SparseMatrix( ) { }; + + /** Constructor with arguments. */ + SymSparseMat( int_t nr, /**< Number of rows. */ + int_t nc, /**< Number of columns. */ + sparse_int_t* r, /**< Row indices (length). */ + sparse_int_t* c, /**< Indices to first entry of columns (nCols+1). */ + real_t* v /**< Vector of entries (length). */ + ) : SparseMatrix(nr, nc, r, c, v) { }; + + /** Constructor from dense matrix. */ + SymSparseMat( int_t nr, /**< Number of rows. */ + int_t nc, /**< Number of columns. */ + int_t ld, /**< Leading dimension. */ + const real_t* const v /**< Row major stored matrix elements. */ + ) : SparseMatrix(nr, nc, ld, v) { }; + + /** Destructor. */ + virtual ~SymSparseMat( ) { }; + + /** Returns a deep-copy of the Matrix object. + * \return Deep-copy of Matrix object */ + virtual Matrix *duplicate( ) const; + + /** Returns a deep-copy of the SymmetricMatrix object. + * \return Deep-copy of SymmetricMatrix object */ + virtual SymmetricMatrix* duplicateSym( ) const; + + + /** Compute bilinear form y = x'*H*x using submatrix given by index list. + * \return SUCCESSFUL_RETURN */ + virtual returnValue bilinear( const Indexlist* const icols, /**< Index list specifying columns of x. */ + int_t xN, /**< Number of vectors to multiply. */ + const real_t* x, /**< Input vector to be multiplied (uncompressed). */ + int_t xLD, /**< Leading dimension of input x. */ + real_t* y, /**< Output vector of results (compressed). */ + int_t yLD /**< Leading dimension of output y. */ + ) const; +}; + + +END_NAMESPACE_QPOASES + + +#endif /* QPOASES_MATRICES_HPP */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/MessageHandling.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/MessageHandling.hpp new file mode 100644 index 0000000..918f21a --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/MessageHandling.hpp @@ -0,0 +1,480 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/MessageHandling.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches (thanks to Leonard Wirsching) + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the MessageHandling class including global return values. + */ + + +#ifndef QPOASES_MESSAGEHANDLING_HPP +#define QPOASES_MESSAGEHANDLING_HPP + + +#include +#include + +#ifdef __DEBUG__ +#include +#endif + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** Default file to display messages. */ +extern FILE* stdFile; + + +/** + * \brief Defines all symbols for global return values. + * + * The enumeration returnValueType defines all symbols for global return values. + * Important: All return values are assumed to be nonnegative! + * + * \author Hans Joachim Ferreau + */ +enum returnValue +{ +TERMINAL_LIST_ELEMENT = -1, /**< Terminal list element, internal usage only! */ +/* miscellaneous */ +SUCCESSFUL_RETURN = 0, /**< Successful return. */ +RET_DIV_BY_ZERO, /**< Division by zero. */ +RET_INDEX_OUT_OF_BOUNDS, /**< Index out of bounds. */ +RET_INVALID_ARGUMENTS, /**< At least one of the arguments is invalid. */ +RET_ERROR_UNDEFINED, /**< Error number undefined. */ +RET_WARNING_UNDEFINED, /**< Warning number undefined. */ +RET_INFO_UNDEFINED, /**< Info number undefined. */ +RET_EWI_UNDEFINED, /**< Error/warning/info number undefined. */ +RET_AVAILABLE_WITH_LINUX_ONLY, /**< This function is available under Linux only. */ +RET_UNKNOWN_BUG, /**< The error occurred is not yet known. */ +RET_PRINTLEVEL_CHANGED, /**< Print level changed. (10) */ +RET_NOT_YET_IMPLEMENTED, /**< Requested function is not yet implemented in this version of qpOASES. */ +/* Indexlist */ +RET_INDEXLIST_MUST_BE_REORDERD, /**< Index list has to be reordered. */ +RET_INDEXLIST_EXCEEDS_MAX_LENGTH, /**< Index list exceeds its maximal physical length. */ +RET_INDEXLIST_CORRUPTED, /**< Index list corrupted. */ +RET_INDEXLIST_OUTOFBOUNDS, /**< Physical index is out of bounds. */ +RET_INDEXLIST_ADD_FAILED, /**< Adding indices from another index set failed. */ +RET_INDEXLIST_INTERSECT_FAILED, /**< Intersection with another index set failed. */ +/* SubjectTo / Bounds / Constraints */ +RET_INDEX_ALREADY_OF_DESIRED_STATUS, /**< Index is already of desired status. (18) */ +RET_ADDINDEX_FAILED, /**< Adding index to index set failed. */ +RET_REMOVEINDEX_FAILED, /**< Removing index from index set failed. (20) */ +RET_SWAPINDEX_FAILED, /**< Cannot swap between different indexsets. */ +RET_NOTHING_TO_DO, /**< Nothing to do. */ +RET_SETUP_BOUND_FAILED, /**< Setting up bound index failed. */ +RET_SETUP_CONSTRAINT_FAILED, /**< Setting up constraint index failed. */ +RET_MOVING_BOUND_FAILED, /**< Moving bound between index sets failed. */ +RET_MOVING_CONSTRAINT_FAILED, /**< Moving constraint between index sets failed. */ +RET_SHIFTING_FAILED, /**< Shifting of bounds/constraints failed. */ +RET_ROTATING_FAILED, /**< Rotating of bounds/constraints failed. */ +/* QProblem */ +RET_QPOBJECT_NOT_SETUP, /**< The QP object has not been setup correctly, use another constructor. */ +RET_QP_ALREADY_INITIALISED, /**< QProblem has already been initialised. (30) */ +RET_NO_INIT_WITH_STANDARD_SOLVER, /**< Initialisation via extern QP solver is not yet implemented. */ +RET_RESET_FAILED, /**< Reset failed. */ +RET_INIT_FAILED, /**< Initialisation failed. */ +RET_INIT_FAILED_TQ, /**< Initialisation failed due to TQ factorisation. */ +RET_INIT_FAILED_CHOLESKY, /**< Initialisation failed due to Cholesky decomposition. */ +RET_INIT_FAILED_HOTSTART, /**< Initialisation failed! QP could not be solved! */ +RET_INIT_FAILED_INFEASIBILITY, /**< Initial QP could not be solved due to infeasibility! */ +RET_INIT_FAILED_UNBOUNDEDNESS, /**< Initial QP could not be solved due to unboundedness! */ +RET_INIT_FAILED_REGULARISATION, /**< Initialisation failed as Hessian matrix could not be regularised. */ +RET_INIT_SUCCESSFUL, /**< Initialisation done. (40) */ +RET_OBTAINING_WORKINGSET_FAILED, /**< Failed to obtain working set for auxiliary QP. */ +RET_SETUP_WORKINGSET_FAILED, /**< Failed to setup working set for auxiliary QP. */ +RET_SETUP_AUXILIARYQP_FAILED, /**< Failed to setup auxiliary QP for initialised homotopy. */ +RET_NO_CHOLESKY_WITH_INITIAL_GUESS, /**< Externally computed Cholesky factor cannot be combined with an initial guess. */ +RET_NO_EXTERN_SOLVER, /**< No extern QP solver available. */ +RET_QP_UNBOUNDED, /**< QP is unbounded. */ +RET_QP_INFEASIBLE, /**< QP is infeasible. */ +RET_QP_NOT_SOLVED, /**< Problems occurred while solving QP with standard solver. */ +RET_QP_SOLVED, /**< QP successfully solved. */ +RET_UNABLE_TO_SOLVE_QP, /**< Problems occurred while solving QP. (50) */ +RET_INITIALISATION_STARTED, /**< Starting problem initialisation... */ +RET_HOTSTART_FAILED, /**< Unable to perform homotopy due to internal error. */ +RET_HOTSTART_FAILED_TO_INIT, /**< Unable to initialise problem. */ +RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED, /**< Unable to perform homotopy as previous QP is not solved. */ +RET_ITERATION_STARTED, /**< Iteration... */ +RET_SHIFT_DETERMINATION_FAILED, /**< Determination of shift of the QP data failed. */ +RET_STEPDIRECTION_DETERMINATION_FAILED, /**< Determination of step direction failed. */ +RET_STEPLENGTH_DETERMINATION_FAILED, /**< Determination of step direction failed. */ +RET_OPTIMAL_SOLUTION_FOUND, /**< Optimal solution of neighbouring QP found. */ +RET_HOMOTOPY_STEP_FAILED, /**< Unable to perform homotopy step. (60) */ +RET_HOTSTART_STOPPED_INFEASIBILITY, /**< Premature homotopy termination because QP is infeasible. */ +RET_HOTSTART_STOPPED_UNBOUNDEDNESS, /**< Premature homotopy termination because QP is unbounded. */ +RET_WORKINGSET_UPDATE_FAILED, /**< Unable to update working sets according to initial guesses. */ +RET_MAX_NWSR_REACHED, /**< Maximum number of working set recalculations performed. */ +RET_CONSTRAINTS_NOT_SPECIFIED, /**< Problem does comprise constraints! You also have to specify new constraints' bounds. */ +RET_INVALID_FACTORISATION_FLAG, /**< Invalid factorisation flag. */ +RET_UNABLE_TO_SAVE_QPDATA, /**< Unable to save QP data. */ +RET_STEPDIRECTION_FAILED_TQ, /**< Abnormal termination due to TQ factorisation. */ +RET_STEPDIRECTION_FAILED_CHOLESKY, /**< Abnormal termination due to Cholesky factorisation. */ +RET_CYCLING_DETECTED, /**< Cycling detected. (70) */ +RET_CYCLING_NOT_RESOLVED, /**< Cycling cannot be resolved, QP probably infeasible. */ +RET_CYCLING_RESOLVED, /**< Cycling probably resolved. */ +RET_STEPSIZE, /**< For displaying performed stepsize. */ +RET_STEPSIZE_NONPOSITIVE, /**< For displaying non-positive stepsize. */ +RET_SETUPSUBJECTTOTYPE_FAILED, /**< Setup of SubjectToTypes failed. */ +RET_ADDCONSTRAINT_FAILED, /**< Addition of constraint to working set failed. */ +RET_ADDCONSTRAINT_FAILED_INFEASIBILITY, /**< Addition of constraint to working set failed (due to QP infeasibility). */ +RET_ADDBOUND_FAILED, /**< Addition of bound to working set failed. */ +RET_ADDBOUND_FAILED_INFEASIBILITY, /**< Addition of bound to working set failed (due to QP infeasibility). */ +RET_REMOVECONSTRAINT_FAILED, /**< Removal of constraint from working set failed. (80) */ +RET_REMOVEBOUND_FAILED, /**< Removal of bound from working set failed. */ +RET_REMOVE_FROM_ACTIVESET, /**< Removing from active set... */ +RET_ADD_TO_ACTIVESET, /**< Adding to active set... */ +RET_REMOVE_FROM_ACTIVESET_FAILED, /**< Removing from active set failed. */ +RET_ADD_TO_ACTIVESET_FAILED, /**< Adding to active set failed. */ +RET_CONSTRAINT_ALREADY_ACTIVE, /**< Constraint is already active. */ +RET_ALL_CONSTRAINTS_ACTIVE, /**< All constraints are active, no further constraint can be added. */ +RET_LINEARLY_DEPENDENT, /**< New bound/constraint is linearly dependent. */ +RET_LINEARLY_INDEPENDENT, /**< New bound/constraint is linearly independent. */ +RET_LI_RESOLVED, /**< Linear independence of active constraint matrix successfully resolved. (90) */ +RET_ENSURELI_FAILED, /**< Failed to ensure linear independence of active constraint matrix. */ +RET_ENSURELI_FAILED_TQ, /**< Abnormal termination due to TQ factorisation. */ +RET_ENSURELI_FAILED_NOINDEX, /**< QP is infeasible. */ +RET_ENSURELI_FAILED_CYCLING, /**< QP is infeasible. */ +RET_BOUND_ALREADY_ACTIVE, /**< Bound is already active. */ +RET_ALL_BOUNDS_ACTIVE, /**< All bounds are active, no further bound can be added. */ +RET_CONSTRAINT_NOT_ACTIVE, /**< Constraint is not active. */ +RET_BOUND_NOT_ACTIVE, /**< Bound is not active. */ +RET_HESSIAN_NOT_SPD, /**< Projected Hessian matrix not positive definite. */ +RET_HESSIAN_INDEFINITE, /**< Hessian matrix is indefinite. (100) */ +RET_MATRIX_SHIFT_FAILED, /**< Unable to update matrices or to transform vectors. */ +RET_MATRIX_FACTORISATION_FAILED, /**< Unable to calculate new matrix factorisations. */ +RET_PRINT_ITERATION_FAILED, /**< Unable to print information on current iteration. */ +RET_NO_GLOBAL_MESSAGE_OUTPUTFILE, /**< No global message output file initialised. */ +RET_DISABLECONSTRAINTS_FAILED, /**< Unable to disbable constraints. */ +RET_ENABLECONSTRAINTS_FAILED, /**< Unable to enbable constraints. */ +RET_ALREADY_ENABLED, /**< Bound or constraint is already enabled. */ +RET_ALREADY_DISABLED, /**< Bound or constraint is already disabled. */ +RET_NO_HESSIAN_SPECIFIED, /**< No Hessian matrix has been specified. */ +RET_USING_REGULARISATION, /**< Using regularisation as Hessian matrix is not positive definite. (110) */ +RET_EPS_MUST_BE_POSITVE, /**< Eps for regularisation must be sufficiently positive. */ +RET_REGSTEPS_MUST_BE_POSITVE, /**< Maximum number of regularisation steps must be non-negative. */ +RET_HESSIAN_ALREADY_REGULARISED, /**< Hessian has been already regularised. */ +RET_CANNOT_REGULARISE_IDENTITY, /**< Identity Hessian matrix cannot be regularised. */ +RET_CANNOT_REGULARISE_SPARSE, /**< Sparse matrix cannot be regularised as diagonal entry is missing. */ +RET_NO_REGSTEP_NWSR, /**< No additional regularisation step could be performed due to limits. */ +RET_FEWER_REGSTEPS_NWSR, /**< Fewer additional regularisation steps have been performed due to limits. */ +RET_CHOLESKY_OF_ZERO_HESSIAN, /**< Cholesky decomposition of (unregularised) zero Hessian matrix. */ +RET_ZERO_HESSIAN_ASSUMED, /**< Zero Hessian matrix assumed as null pointer passed without specifying hessianType. */ +RET_CONSTRAINTS_ARE_NOT_SCALED, /**< (no longer in use) (120) */ +RET_INITIAL_BOUNDS_STATUS_NYI, /**< (no longer in use) */ +RET_ERROR_IN_CONSTRAINTPRODUCT, /**< Error in user-defined constraint product function. */ +RET_FIX_BOUNDS_FOR_LP, /**< All initial bounds must be fixed when solving an (unregularised) LP. */ +RET_USE_REGULARISATION_FOR_LP, /**< Set options.enableRegularisation=BT_TRUE for solving LPs. */ +/* SQProblem */ +RET_UPDATEMATRICES_FAILED, /**< Unable to update QP matrices. */ +RET_UPDATEMATRICES_FAILED_AS_QP_NOT_SOLVED, /**< Unable to update matrices as previous QP is not solved. */ +/* Utils */ +RET_UNABLE_TO_OPEN_FILE, /**< Unable to open file. */ +RET_UNABLE_TO_WRITE_FILE, /**< Unable to write into file. */ +RET_UNABLE_TO_READ_FILE, /**< Unable to read from file. */ +RET_FILEDATA_INCONSISTENT, /**< File contains inconsistent data. (130) */ +/* Options */ +RET_OPTIONS_ADJUSTED, /**< Options needed to be adjusted for consistency reasons. */ +/* SolutionAnalysis */ +RET_UNABLE_TO_ANALYSE_QPROBLEM, /**< Unable to analyse (S)QProblem(B) object. */ +/* Benchmark */ +RET_NWSR_SET_TO_ONE, /**< Maximum number of working set changes was set to 1. */ +RET_UNABLE_TO_READ_BENCHMARK, /**< Unable to read benchmark data. */ +RET_BENCHMARK_ABORTED, /**< Benchmark aborted. */ +RET_INITIAL_QP_SOLVED, /**< Initial QP solved. */ +RET_QP_SOLUTION_STARTED, /**< Solving QP... */ +RET_BENCHMARK_SUCCESSFUL, /**< Benchmark terminated successfully. */ +/* Sparse matrices */ +RET_NO_DIAGONAL_AVAILABLE, /**< Sparse matrix does not have entries on full diagonal. */ +RET_DIAGONAL_NOT_INITIALISED, /**< Diagonal data of sparse matrix has not been initialised. (140) */ +/* Dropping of infeasible constraints */ +RET_ENSURELI_DROPPED, /**< Linear independence resolved by dropping blocking constraint. */ +/* Schur complement computations */ +RET_KKT_MATRIX_SINGULAR, /**< KKT matrix is singular. */ +RET_QR_FACTORISATION_FAILED, /**< QR factorization of Schur complement failed. */ +RET_INERTIA_CORRECTION_FAILED, /**< Inertia correction failed after KKT matrix had too many negative eigenvalues. */ +RET_NO_SPARSE_SOLVER, /**< No factorization routine for the KKT matrix installed. */ +/* Simple exitflags */ +RET_SIMPLE_STATUS_P1, /**< QP problem could not be solved within given number of iterations. */ +RET_SIMPLE_STATUS_P0, /**< QP problem solved. */ +RET_SIMPLE_STATUS_M1, /**< QP problem could not be solved due to an internal error. */ +RET_SIMPLE_STATUS_M2, /**< QP problem is infeasible (and thus could not be solved). */ +RET_SIMPLE_STATUS_M3 /**< QP problem is unbounded (and thus could not be solved). (150) */ +}; + + +/** + * \brief Handles all kind of error messages, warnings and other information. + * + * This class handles all kinds of messages (errors, warnings, infos) initiated + * by qpOASES modules and stores the corresponding global preferences. + * + * \author Hans Joachim Ferreau (thanks to Leonard Wirsching) + * \version 3.2 + * \date 2007-2017 + */ +class MessageHandling +{ + /* + * INTERNAL DATA STRUCTURES + */ + public: + /** + * \brief Data structure for entries in global message list. + * + * Data structure for entries in global message list. + * + * \author Hans Joachim Ferreau + */ + typedef struct { + returnValue key; /**< Global return value. */ + const char* data; /**< Corresponding message. */ + VisibilityStatus globalVisibilityStatus; /**< Determines if message can be printed. + * If this value is set to VS_HIDDEN, no message is printed! */ + } ReturnValueList; + + + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + MessageHandling( ); + + /** Constructor which takes the desired output file. */ + MessageHandling( FILE* _outputFile /**< Output file. */ + ); + + /** Constructor which takes the desired visibility states. */ + MessageHandling( VisibilityStatus _errorVisibility, /**< Visibility status for error messages. */ + VisibilityStatus _warningVisibility,/**< Visibility status for warning messages. */ + VisibilityStatus _infoVisibility /**< Visibility status for info messages. */ + ); + + /** Constructor which takes the desired output file and desired visibility states. */ + MessageHandling( FILE* _outputFile, /**< Output file. */ + VisibilityStatus _errorVisibility, /**< Visibility status for error messages. */ + VisibilityStatus _warningVisibility,/**< Visibility status for warning messages. */ + VisibilityStatus _infoVisibility /**< Visibility status for info messages. */ + ); + + /** Copy constructor (deep copy). */ + MessageHandling( const MessageHandling& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + ~MessageHandling( ); + + /** Assignment operator (deep copy). */ + MessageHandling& operator=( const MessageHandling& rhs /**< Rhs object. */ + ); + + + /** Prints an error message(a simplified macro THROWERROR is also provided). \n + * Errors are defined as abnormal events which cause an immediate termination of the current (sub) function. + * Errors of a sub function should be commented by the calling function by means of a warning message + * (if this error does not cause an error of the calling function, either)! + * \return Error number returned by sub function call + */ + returnValue throwError( returnValue Enumber, /**< Error number returned by sub function call. */ + const char* additionaltext, /**< Additional error text (0, if none). */ + const char* functionname, /**< Name of function which caused the error. */ + const char* filename, /**< Name of file which caused the error. */ + const unsigned long linenumber, /**< Number of line which caused the error.incompatible binary file */ + VisibilityStatus localVisibilityStatus /**< Determines (locally) if error message can be printed to stdFile. + * If GLOBAL visibility status of the message is set to VS_HIDDEN, + * no message is printed, anyway! */ + ); + + /** Prints a warning message (a simplified macro THROWWARNING is also provided). + * Warnings are definied as abnormal events which does NOT cause an immediate termination of the current (sub) function. + * \return Warning number returned by sub function call + */ + returnValue throwWarning( returnValue Wnumber, /**< Warning number returned by sub function call. */ + const char* additionaltext, /**< Additional warning text (0, if none). */ + const char* functionname, /**< Name of function which caused the warning. */ + const char* filename, /**< Name of file which caused the warning. */ + const unsigned long linenumber, /**< Number of line which caused the warning. */ + VisibilityStatus localVisibilityStatus /**< Determines (locally) if warning message can be printed to stdFile. + * If GLOBAL visibility status of the message is set to VS_HIDDEN, + * no message is printed, anyway! */ + ); + + /** Prints a info message (a simplified macro THROWINFO is also provided). + * \return Info number returned by sub function call + */ + returnValue throwInfo( returnValue Inumber, /**< Info number returned by sub function call. */ + const char* additionaltext, /**< Additional warning text (0, if none). */ + const char* functionname, /**< Name of function which submitted the info. */ + const char* filename, /**< Name of file which submitted the info. */ + const unsigned long linenumber, /**< Number of line which submitted the info. */ + VisibilityStatus localVisibilityStatus /**< Determines (locally) if info message can be printed to stdFile. + * If GLOBAL visibility status of the message is set to VS_HIDDEN, + * no message is printed, anyway! */ + ); + + + /** Resets all preferences to default values. + * \return SUCCESSFUL_RETURN */ + returnValue reset( ); + + + /** Prints a complete list of all messages to output file. + * \return SUCCESSFUL_RETURN */ + returnValue listAllMessages( ); + + + /** Returns visibility status for error messages. + * \return Visibility status for error messages. */ + inline VisibilityStatus getErrorVisibilityStatus( ) const; + + /** Returns visibility status for warning messages. + * \return Visibility status for warning messages. */ + inline VisibilityStatus getWarningVisibilityStatus( ) const; + + /** Returns visibility status for info messages. + * \return Visibility status for info messages. */ + inline VisibilityStatus getInfoVisibilityStatus( ) const; + + /** Returns pointer to output file. + * \return Pointer to output file. */ + inline FILE* getOutputFile( ) const; + + /** Returns error count value. + * \return Error count value. */ + inline int_t getErrorCount( ) const; + + + /** Changes visibility status for error messages. */ + inline void setErrorVisibilityStatus( VisibilityStatus _errorVisibility /**< New visibility status for error messages. */ + ); + + /** Changes visibility status for warning messages. */ + inline void setWarningVisibilityStatus( VisibilityStatus _warningVisibility /**< New visibility status for warning messages. */ + ); + + /** Changes visibility status for info messages. */ + inline void setInfoVisibilityStatus( VisibilityStatus _infoVisibility /**< New visibility status for info messages. */ + ); + + /** Changes output file for messages. */ + inline void setOutputFile( FILE* _outputFile /**< New output file for messages. */ + ); + + /** Changes error count. + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENT */ + inline returnValue setErrorCount( int_t _errorCount /**< New error count value. */ + ); + + /** Provides message text corresponding to given \a returnValue. + * \return String containing message text. */ + static const char* getErrorCodeMessage( const returnValue _returnValue + ); + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Prints a info message to stdFile (auxiliary function). + * \return Error/warning/info number returned by sub function call + */ + returnValue throwMessage( + returnValue RETnumber, /**< Error/warning/info number returned by sub function call. */ + const char* additionaltext, /**< Additional warning text (0, if none). */ + const char* functionname, /**< Name of function which caused the error/warning/info. */ + const char* filename, /**< Name of file which caused the error/warning/info. */ + const unsigned long linenumber, /**< Number of line which caused the error/warning/info. */ + VisibilityStatus localVisibilityStatus, /**< Determines (locally) if info message can be printed to stdFile. + * If GLOBAL visibility status of the message is set to VS_HIDDEN, + * no message is printed, anyway! */ + const char* RETstring /**< Leading string of error/warning/info message. */ + ); + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + VisibilityStatus errorVisibility; /**< Error messages visible? */ + VisibilityStatus warningVisibility; /**< Warning messages visible? */ + VisibilityStatus infoVisibility; /**< Info messages visible? */ + + FILE* outputFile; /**< Output file for messages. */ + + int_t errorCount; /**< Counts number of errors (for nicer output only). */ +}; + + +#ifndef __FILE__ + /** Ensures that __FILE__ macro is defined. */ + #define __FILE__ 0 +#endif + +#ifndef __LINE__ + /** Ensures that __LINE__ macro is defined. */ + #define __LINE__ 0 +#endif + +/** Define __FUNC__ macro providing current function for debugging. */ +/*#define __FUNC__ 0*/ +#define __FUNC__ ("(no function name provided)") +/*#define __FUNC__ __func__*/ +/*#define __FUNC__ __FUNCTION__*/ + + +/** Short version of throwError with default values, only returnValue is needed */ +#define THROWERROR(retval) ( getGlobalMessageHandler( )->throwError((retval),0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE) ) + +/** Short version of throwWarning with default values, only returnValue is needed */ +#define THROWWARNING(retval) ( getGlobalMessageHandler( )->throwWarning((retval),0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE) ) + +/** Short version of throwInfo with default values, only returnValue is needed */ +#define THROWINFO(retval) ( getGlobalMessageHandler( )->throwInfo((retval),0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE) ) + + +/** Returns a pointer to global message handler. + * \return Pointer to global message handler. + */ +MessageHandling* getGlobalMessageHandler( ); + + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_MESSAGEHANDLING_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/MessageHandling.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/MessageHandling.ipp new file mode 100644 index 0000000..7ddb936 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/MessageHandling.ipp @@ -0,0 +1,144 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/MessageHandling.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of inlined member functions of the MessageHandling class. + */ + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * g e t E r r o r V i s i b i l i t y S t a t u s + */ +inline VisibilityStatus MessageHandling::getErrorVisibilityStatus( ) const +{ + return errorVisibility; +} + + +/* + * g e t W a r n i n g V i s i b i l i t y S t a t u s + */ +inline VisibilityStatus MessageHandling::getWarningVisibilityStatus( ) const +{ + return warningVisibility; +} + + +/* + * g e t I n f o V i s i b i l i t y S t a t u s + */ +inline VisibilityStatus MessageHandling::getInfoVisibilityStatus( ) const +{ + return infoVisibility; +} + + +/* + * g e t O u t p u t F i l e + */ +inline FILE* MessageHandling::getOutputFile( ) const +{ + return outputFile; +} + + +/* + * g e t E r r o r C o u n t + */ +inline int_t MessageHandling::getErrorCount( ) const +{ + return errorCount; +} + + +/* + * s e t E r r o r V i s i b i l i t y S t a t u s + */ +inline void MessageHandling::setErrorVisibilityStatus( VisibilityStatus _errorVisibility ) +{ + errorVisibility = _errorVisibility; +} + + +/* + * s e t W a r n i n g V i s i b i l i t y S t a t u s + */ +inline void MessageHandling::setWarningVisibilityStatus( VisibilityStatus _warningVisibility ) +{ + warningVisibility = _warningVisibility; +} + + +/* + * s e t I n f o V i s i b i l i t y S t a t u s + */ +inline void MessageHandling::setInfoVisibilityStatus( VisibilityStatus _infoVisibility ) +{ + infoVisibility = _infoVisibility; +} + + +/* + * s e t O u t p u t F i l e + */ +inline void MessageHandling::setOutputFile( FILE* _outputFile ) +{ + outputFile = _outputFile; +} + + +/* + * s e t E r r o r C o u n t + */ +inline returnValue MessageHandling::setErrorCount( int_t _errorCount ) +{ + if ( _errorCount >= -1 ) + { + errorCount = _errorCount; + return SUCCESSFUL_RETURN; + } + else + return RET_INVALID_ARGUMENTS; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Options.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Options.hpp new file mode 100644 index 0000000..49c3026 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Options.hpp @@ -0,0 +1,174 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Options.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the Options class designed to manage user-specified + * options for solving a QProblem. + */ + + +#ifndef QPOASES_OPTIONS_HPP +#define QPOASES_OPTIONS_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Manages all user-specified options for solving QPs. + * + * This class manages all user-specified options used for solving + * quadratic programs. + * + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + */ +class Options +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + Options( ); + + /** Copy constructor (deep copy). */ + Options( const Options& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + ~Options( ); + + /** Assignment operator (deep copy). */ + Options& operator=( const Options& rhs /**< Rhs object. */ + ); + + + /** Sets all options to default values. + * \return SUCCESSFUL_RETURN */ + returnValue setToDefault( ); + + /** Sets all options to values resulting in maximum reliabilty. + * \return SUCCESSFUL_RETURN */ + returnValue setToReliable( ); + + /** Sets all options to values resulting in minimum solution time. + * \return SUCCESSFUL_RETURN */ + returnValue setToMPC( ); + + /** Same as setToMPC( ), for ensuring backwards compatibility. + * \return SUCCESSFUL_RETURN */ + returnValue setToFast( ); + + + /** Ensures that all options have consistent values by automatically + * adjusting inconsistent ones. + * Note: This routine cannot (and does not try to) ensure that values + * are set to reasonable values that make the QP solution work! + * \return SUCCESSFUL_RETURN \n + * RET_OPTIONS_ADJUSTED */ + returnValue ensureConsistency( ); + + + /** Prints values of all options. + * \return SUCCESSFUL_RETURN */ + returnValue print( ) const; + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const Options& rhs /**< Rhs object. */ + ); + + /* + * PUBLIC MEMBER VARIABLES + */ + public: + PrintLevel printLevel; /**< Print level. */ + + BooleanType enableRamping; /**< Specifies whether ramping shall be enabled or not. */ + BooleanType enableFarBounds; /**< Specifies whether far bounds shall be used or not. */ + BooleanType enableFlippingBounds; /**< Specifies whether flipping bounds shall be used or not. */ + BooleanType enableRegularisation; /**< Specifies whether Hessian matrix shall be regularised in case semi-definiteness is detected. */ + BooleanType enableFullLITests; /**< Specifies whether condition-hardened LI test shall be used or not. */ + BooleanType enableNZCTests; /**< Specifies whether nonzero curvature tests shall be used. */ + int_t enableDriftCorrection; /**< Specifies the frequency of drift corrections (0 = off). */ + int_t enableCholeskyRefactorisation; /**< Specifies the frequency of full refactorisation of proj. Hessian (otherwise updates). */ + BooleanType enableEqualities; /**< Specifies whether equalities shall be always treated as active constraints. */ + + real_t terminationTolerance; /**< Termination tolerance. */ + real_t boundTolerance; /**< Lower/upper (constraints') bound tolerance (an inequality constraint whose lower and + upper bounds differ by less is regarded to be an equality constraint). */ + real_t boundRelaxation; /**< Offset for relaxing (constraints') bounds at beginning of an initial homotopy. It is also as initial value for far bounds. */ + real_t epsNum; /**< Numerator tolerance for ratio tests. */ + real_t epsDen; /**< Denominator tolerance for ratio tests. */ + real_t maxPrimalJump; /**< Maximum allowed jump in primal variables in nonzero curvature tests. */ + real_t maxDualJump; /**< Maximum allowed jump in dual variables in linear independence tests. */ + + real_t initialRamping; /**< Start value for Ramping Strategy. */ + real_t finalRamping; /**< Final value for Ramping Strategy. */ + real_t initialFarBounds; /**< Initial size of Far Bounds. */ + real_t growFarBounds; /**< Factor to grow Far Bounds. */ + SubjectToStatus initialStatusBounds; /**< Initial status of bounds at first iteration. */ + real_t epsFlipping; /**< Tolerance of squared Cholesky diagonal factor which triggers flipping bound. */ + int_t numRegularisationSteps; /**< Maximum number of successive regularisation steps. */ + real_t epsRegularisation; /**< Scaling factor of identity matrix used for Hessian regularisation. */ + int_t numRefinementSteps; /**< Maximum number of iterative refinement steps. */ + real_t epsIterRef; /**< Early termination tolerance for iterative refinement. */ + real_t epsLITests; /**< Tolerance for linear independence tests. */ + real_t epsNZCTests; /**< Tolerance for nonzero curvature tests. */ + + real_t rcondSMin; /**< Minimum reciprocal condition number of S before refactorization is triggered */ + BooleanType enableInertiaCorrection; /**< Specifies whether the working set should be repaired when negative curvature is discovered during hotstart. */ + + BooleanType enableDropInfeasibles; /**< ... */ + int_t dropBoundPriority; /**< ... */ + int_t dropEqConPriority; /**< ... */ + int_t dropIneqConPriority; /**< ... */ +}; + + +END_NAMESPACE_QPOASES + + +#endif /* QPOASES_OPTIONS_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/QProblem.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/QProblem.hpp new file mode 100644 index 0000000..8e053f9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/QProblem.hpp @@ -0,0 +1,1082 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/QProblem.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the QProblem class which is able to use the newly + * developed online active set strategy for parametric quadratic programming. + */ + + + +#ifndef QPOASES_QPROBLEM_HPP +#define QPOASES_QPROBLEM_HPP + + +#include +#include +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Implements the online active set strategy for QPs with general constraints. + * + * A class for setting up and solving quadratic programs. The main feature is + * the possibily to use the newly developed online active set strategy for + * parametric quadratic programming. + * + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + */ +class QProblem : public QProblemB +{ + /* allow SolutionAnalysis class to access private members */ + friend class SolutionAnalysis; + + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + QProblem( ); + + /** Constructor which takes the QP dimension and Hessian type + * information. If the Hessian is the zero (i.e. HST_ZERO) or the + * identity matrix (i.e. HST_IDENTITY), respectively, no memory + * is allocated for it and a NULL pointer can be passed for it + * to the init() functions. */ + QProblem( int_t _nV, /**< Number of variables. */ + int_t _nC, /**< Number of constraints. */ + HessianType _hessianType = HST_UNKNOWN, /**< Type of Hessian matrix. */ + BooleanType allocDenseMats = BT_TRUE /**< Enable allocation of dense matrices. */ + ); + + /** Copy constructor (deep copy). */ + QProblem( const QProblem& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~QProblem( ); + + /** Assignment operator (deep copy). */ + virtual QProblem& operator=( const QProblem& rhs /**< Rhs object. */ + ); + + + /** Clears all data structures of QProblemB except for QP data. + * \return SUCCESSFUL_RETURN \n + RET_RESET_FAILED */ + virtual returnValue reset( ); + + + /** Initialises a QP problem with given QP data and tries to solve it + * using at most nWSR iterations. Depending on the parameter constellation it: \n + * 1. 0, 0, 0 : starts with xOpt = 0, yOpt = 0 and gB/gC empty (or all implicit equality bounds), \n + * 2. xOpt, 0, 0 : starts with xOpt, yOpt = 0 and obtain gB/gC by "clipping", \n + * 3. 0, yOpt, 0 : starts with xOpt = 0, yOpt and obtain gB/gC from yOpt != 0, \n + * 4. 0, 0, gB/gC: starts with xOpt = 0, yOpt = 0 and gB/gC, \n + * 5. xOpt, yOpt, 0 : starts with xOpt, yOpt and obtain gB/gC from yOpt != 0, \n + * 6. xOpt, 0, gB/gC: starts with xOpt, yOpt = 0 and gB/gC, \n + * 7. xOpt, yOpt, gB/gC: starts with xOpt, yOpt and gB/gC (assume them to be consistent!) + * + * Note: This function internally calls solveInitialQP for initialisation! + * + * \return SUCCESSFUL_RETURN \n + RET_INIT_FAILED \n + RET_INIT_FAILED_CHOLESKY \n + RET_INIT_FAILED_TQ \n + RET_INIT_FAILED_HOTSTART \n + RET_INIT_FAILED_INFEASIBILITY \n + RET_INIT_FAILED_UNBOUNDEDNESS \n + RET_MAX_NWSR_REACHED \n + RET_INVALID_ARGUMENTS */ + returnValue init( SymmetricMatrix *_H, /**< Hessian matrix (a shallow copy is made). */ + const real_t* const _g, /**< Gradient vector. */ + Matrix *_A, /**< Constraint matrix (a shallow copy is made). */ + const real_t* const _lb, /**< Lower bound vector (on variables). \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const _ub, /**< Upper bound vector (on variables). \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const _lbA, /**< Lower constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const _ubA, /**< Upper constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations when using initial homotopy. + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP initialisation. \n + Output: CPU time spent for QP initialisation (if pointer passed). */ + const real_t* const xOpt = 0, /**< Optimal primal solution vector. \n + (If a null pointer is passed, the old primal solution is kept!) */ + const real_t* const yOpt = 0, /**< Optimal dual solution vector. \n + (If a null pointer is passed, the old dual solution is kept!) */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, all bounds are assumed inactive!) */ + const Constraints* const guessedConstraints = 0,/**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, all constraints are assumed inactive!) */ + const real_t* const _R = 0 /**< Pre-computed (upper triangular) Cholesky factor of Hessian matrix. + The Cholesky factor must be stored in a real_t array of size nV*nV + in row-major format. Note: Only used if xOpt/yOpt and gB are NULL! \n + (If a null pointer is passed, Cholesky decomposition is computed internally!) */ + ); + + + /** Initialises a QP problem with given QP data and tries to solve it + * using at most nWSR iterations. Depending on the parameter constellation it: \n + * 1. 0, 0, 0 : starts with xOpt = 0, yOpt = 0 and gB/gC empty (or all implicit equality bounds), \n + * 2. xOpt, 0, 0 : starts with xOpt, yOpt = 0 and obtain gB/gC by "clipping", \n + * 3. 0, yOpt, 0 : starts with xOpt = 0, yOpt and obtain gB/gC from yOpt != 0, \n + * 4. 0, 0, gB/gC: starts with xOpt = 0, yOpt = 0 and gB/gC, \n + * 5. xOpt, yOpt, 0 : starts with xOpt, yOpt and obtain gB/gC from yOpt != 0, \n + * 6. xOpt, 0, gB/gC: starts with xOpt, yOpt = 0 and gB/gC, \n + * 7. xOpt, yOpt, gB/gC: starts with xOpt, yOpt and gB/gC (assume them to be consistent!) + * + * Note: This function internally calls solveInitialQP for initialisation! + * + * \return SUCCESSFUL_RETURN \n + RET_INIT_FAILED \n + RET_INIT_FAILED_CHOLESKY \n + RET_INIT_FAILED_TQ \n + RET_INIT_FAILED_HOTSTART \n + RET_INIT_FAILED_INFEASIBILITY \n + RET_INIT_FAILED_UNBOUNDEDNESS \n + RET_MAX_NWSR_REACHED \n + RET_INVALID_ARGUMENTS */ + returnValue init( const real_t* const _H, /**< Hessian matrix (a shallow copy is made). \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + const real_t* const _g, /**< Gradient vector. */ + const real_t* const _A, /**< Constraint matrix (a shallow copy is made). */ + const real_t* const _lb, /**< Lower bound vector (on variables). \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const _ub, /**< Upper bound vector (on variables). \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const _lbA, /**< Lower constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const _ubA, /**< Upper constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations when using initial homotopy. + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP initialisation. \n + Output: CPU time spent for QP initialisation (if pointer passed). */ + const real_t* const xOpt = 0, /**< Optimal primal solution vector. \n + (If a null pointer is passed, the old primal solution is kept!) */ + const real_t* const yOpt = 0, /**< Optimal dual solution vector. \n + (If a null pointer is passed, the old dual solution is kept!) */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, all bounds are assumed inactive!) */ + const Constraints* const guessedConstraints = 0,/**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, all constraints are assumed inactive!) */ + const real_t* const _R = 0 /**< Pre-computed (upper triangular) Cholesky factor of Hessian matrix. + The Cholesky factor must be stored in a real_t array of size nV*nV + in row-major format. Note: Only used if xOpt/yOpt and gB are NULL! \n + (If a null pointer is passed, Cholesky decomposition is computed internally!) */ + ); + + /** Initialises a QP problem with given data to be read from files and solves it + * using at most nWSR iterations. Depending on the parameter constellation it: \n + * 1. 0, 0, 0 : starts with xOpt = 0, yOpt = 0 and gB/gC empty (or all implicit equality bounds), \n + * 2. xOpt, 0, 0 : starts with xOpt, yOpt = 0 and obtain gB/gC by "clipping", \n + * 3. 0, yOpt, 0 : starts with xOpt = 0, yOpt and obtain gB/gC from yOpt != 0, \n + * 4. 0, 0, gB/gC: starts with xOpt = 0, yOpt = 0 and gB/gC, \n + * 5. xOpt, yOpt, 0 : starts with xOpt, yOpt and obtain gB/gC from yOpt != 0, \n + * 6. xOpt, 0, gB/gC: starts with xOpt, yOpt = 0 and gB/gC, \n + * 7. xOpt, yOpt, gB/gC: starts with xOpt, yOpt and gB/gC (assume them to be consistent!) + * + * Note: This function internally calls solveInitialQP for initialisation! + * + * \return SUCCESSFUL_RETURN \n + RET_INIT_FAILED \n + RET_INIT_FAILED_CHOLESKY \n + RET_INIT_FAILED_TQ \n + RET_INIT_FAILED_HOTSTART \n + RET_INIT_FAILED_INFEASIBILITY \n + RET_INIT_FAILED_UNBOUNDEDNESS \n + RET_MAX_NWSR_REACHED \n + RET_UNABLE_TO_READ_FILE \n + RET_INVALID_ARGUMENTS */ + returnValue init( const char* const H_file, /**< Name of file where Hessian matrix is stored. \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + const char* const g_file, /**< Name of file where gradient vector is stored. */ + const char* const A_file, /**< Name of file where constraint matrix is stored. */ + const char* const lb_file, /**< Name of file where lower bound vector. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bound vector. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const char* const lbA_file, /**< Name of file where lower constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const char* const ubA_file, /**< Name of file where upper constraints' bound vector. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations when using initial homotopy. + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP initialisation. \n + Output: CPU time spent for QP initialisation (if pointer passed). */ + const real_t* const xOpt = 0, /**< Optimal primal solution vector. \n + (If a null pointer is passed, the old primal solution is kept!) */ + const real_t* const yOpt = 0, /**< Optimal dual solution vector. \n + (If a null pointer is passed, the old dual solution is kept!) */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, all bounds are assumed inactive!) */ + const Constraints* const guessedConstraints = 0,/**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, all constraints are assumed inactive!) */ + const char* const R_file = 0 /**< Name of the file where a pre-computed (upper triangular) Cholesky factor + of the Hessian matrix is stored. \n + (If a null pointer is passed, Cholesky decomposition is computed internally!) */ + ); + + + /** Solves an initialised QP sequence using the online active set strategy. + * By default, QP solution is started from previous solution. If a guess + * for the working set is provided, an initialised homotopy is performed. + * + * Note: This function internally calls solveQP/solveRegularisedQP + * for solving an initialised QP! + * + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS */ + returnValue hotstart( const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const lbA_new, /**< Lower constraints' bounds of neighbouring QP to be solved. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const ubA_new, /**< Upper constraints' bounds of neighbouring QP to be solved. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of bounds is kept!) */ + const Constraints* const guessedConstraints = 0 /**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of constraints is kept!) */ + ); + + /** Solves an initialised QP sequence using the online active set strategy, + * where QP data is read from files. + * By default, QP solution is started from previous solution. If a guess + * for the working set is provided, an initialised homotopy is performed. + * + * Note: This function internally calls solveQP/solveRegularisedQP + * for solving an initialised QP! + * + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS \n + RET_UNABLE_TO_READ_FILE \n + RET_INVALID_ARGUMENTS */ + returnValue hotstart( const char* const g_file, /**< Name of file where gradient, of neighbouring QP to be solved, is stored. */ + const char* const lb_file, /**< Name of file where lower bounds, of neighbouring QP to be solved, is stored. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bounds, of neighbouring QP to be solved, is stored. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const char* const lbA_file, /**< Name of file where lower constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const char* const ubA_file, /**< Name of file where upper constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of bounds is kept!) */ + const Constraints* const guessedConstraints = 0 /**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of constraints is kept!) */ + ); + + + /** Solves an equality-constrained QP problem resulting from the current working set. + * \return SUCCESSFUL_RETURN \n + * RET_STEPDIRECTION_FAILED_TQ \n + * RET_STEPDIRECTION_FAILED_CHOLESKY \n + * RET_INVALID_ARGUMENTS */ + returnValue solveCurrentEQP ( const int_t n_rhs, /**< Number of consecutive right hand sides */ + const real_t* g_in, /**< Gradient of neighbouring QP to be solved. */ + const real_t* lb_in, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* ub_in, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* lbA_in, /**< Lower constraints' bounds of neighbouring QP to be solved. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* ubA_in, /**< Upper constraints' bounds of neighbouring QP to be solved. \n */ + real_t* x_out, /**< Output: Primal solution */ + real_t* y_out /**< Output: Dual solution */ + ); + + /** Writes a vector with the state of the working set + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + virtual returnValue getWorkingSet( real_t* workingSet /** Output: array containing state of the working set. */ + ); + + /** Writes a vector with the state of the working set of bounds + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + virtual returnValue getWorkingSetBounds( real_t* workingSetB /** Output: array containing state of the working set of bounds. */ + ); + + /** Writes a vector with the state of the working set of constraints + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + virtual returnValue getWorkingSetConstraints( real_t* workingSetC /** Output: array containing state of the working set of constraints. */ + ); + + + /** Returns current constraints object of the QP (deep copy). + * \return SUCCESSFUL_RETURN \n + RET_QPOBJECT_NOT_SETUP */ + inline returnValue getConstraints( Constraints& _constraints /** Output: Constraints object. */ + ) const; + + + /** Returns the number of constraints. + * \return Number of constraints. */ + inline int_t getNC( ) const; + + /** Returns the number of (implicitly defined) equality constraints. + * \return Number of (implicitly defined) equality constraints. */ + inline int_t getNEC( ) const; + + /** Returns the number of active constraints. + * \return Number of active constraints. */ + inline int_t getNAC( ) const; + + /** Returns the number of inactive constraints. + * \return Number of inactive constraints. */ + inline int_t getNIAC( ) const; + + /** Returns the dimension of null space. + * \return Dimension of null space. */ + virtual int_t getNZ( ) const; + + + /** Returns the dual solution vector (deep copy). + * \return SUCCESSFUL_RETURN \n + RET_QP_NOT_SOLVED */ + virtual returnValue getDualSolution( real_t* const yOpt /**< Output: Dual solution vector (if QP has been solved). */ + ) const; + + + /** Defines user-defined routine for calculating the constraint product A*x + * \return SUCCESSFUL_RETURN \n */ + returnValue setConstraintProduct( ConstraintProduct* const _constraintProduct + ); + + + /** Prints concise list of properties of the current QP. + * \return SUCCESSFUL_RETURN \n */ + virtual returnValue printProperties( ); + + /** Set the incoming array to true for each variable entry that is + in the set of free variables */ + returnValue getFreeVariablesFlags( BooleanType* varIsFree ); + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const QProblem& rhs /**< Rhs object. */ + ); + + /** Solves a QProblem whose QP data is assumed to be stored in the member variables. + * A guess for its primal/dual optimal solution vectors and the corresponding + * working sets of bounds and constraints can be provided. + * Note: This function is internally called by all init functions! + * \return SUCCESSFUL_RETURN \n + RET_INIT_FAILED \n + RET_INIT_FAILED_CHOLESKY \n + RET_INIT_FAILED_TQ \n + RET_INIT_FAILED_HOTSTART \n + RET_INIT_FAILED_INFEASIBILITY \n + RET_INIT_FAILED_UNBOUNDEDNESS \n + RET_MAX_NWSR_REACHED */ + returnValue solveInitialQP( const real_t* const xOpt, /**< Optimal primal solution vector.*/ + const real_t* const yOpt, /**< Optimal dual solution vector. */ + const Bounds* const guessedBounds, /**< Optimal working set of bounds for solution (xOpt,yOpt). */ + const Constraints* const guessedConstraints, /**< Optimal working set of constraints for solution (xOpt,yOpt). */ + const real_t* const _R, /**< Pre-computed (upper triangular) Cholesky factor of Hessian matrix. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + ); + + /** Solves QProblem using online active set strategy. + * Note: This function is internally called by all hotstart functions! + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS */ + returnValue solveQP( const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const lbA_new, /**< Lower constraints' bounds of neighbouring QP to be solved. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const ubA_new, /**< Upper constraints' bounds of neighbouring QP to be solved. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + int_t nWSRperformed = 0, /**< Number of working set recalculations already performed to solve + this QP within previous solveQP() calls. This number is + always zero, except for successive calls from solveRegularisedQP() + or when using the far bound strategy. */ + BooleanType isFirstCall = BT_TRUE /**< Indicating whether this is the first call for current QP. */ + ); + + + /** Solves QProblem using online active set strategy. + * Note: This function is internally called by all hotstart functions! + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS */ + returnValue solveRegularisedQP( const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const lbA_new, /**< Lower constraints' bounds of neighbouring QP to be solved. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const ubA_new, /**< Upper constraints' bounds of neighbouring QP to be solved. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + int_t nWSRperformed = 0, /**< Number of working set recalculations already performed to solve + this QP within previous solveRegularisedQP() calls. This number is + always zero, except for successive calls when using the far bound strategy. */ + BooleanType isFirstCall = BT_TRUE /**< Indicating whether this is the first call for current QP. */ + ); + + + /** Update activities in a hot start if some of the bounds have + become infinity or if variables have become fixed. */ + /* \return SUCCESSFUL_RETURN \n + RET_HOTSTART_FAILED */ + virtual returnValue updateActivitiesForHotstart( const real_t* const lb_new, /**< New lower bounds. */ + const real_t* const ub_new, /**< New upper bounds. */ + const real_t* const lbA_new, /**< New lower constraints' bounds. */ + const real_t* const ubA_new /**< New upper constraints' bounds. */ + ); + + + /** Determines type of existing constraints and bounds (i.e. implicitly fixed, unbounded etc.). + * \return SUCCESSFUL_RETURN \n + RET_SETUPSUBJECTTOTYPE_FAILED */ + virtual returnValue setupSubjectToType( ); + + /** Determines type of new constraints and bounds (i.e. implicitly fixed, unbounded etc.). + * \return SUCCESSFUL_RETURN \n + RET_SETUPSUBJECTTOTYPE_FAILED */ + using QProblemB::setupSubjectToType; + virtual returnValue setupSubjectToType( const real_t* const lb_new, /**< New lower bounds. */ + const real_t* const ub_new, /**< New upper bounds. */ + const real_t* const lbA_new, /**< New lower constraints' bounds. */ + const real_t* const ubA_new /**< New upper constraints' bounds. */ + ); + + /** Computes the Cholesky decomposition of the projected Hessian (i.e. R^T*R = Z^T*H*Z). + * Note: If Hessian turns out not to be positive definite, the Hessian type + * is set to HST_SEMIDEF accordingly. + * \return SUCCESSFUL_RETURN \n + * RET_HESSIAN_NOT_SPD \n + * RET_INDEXLIST_CORRUPTED */ + virtual returnValue computeProjectedCholesky( ); + + /** Computes initial Cholesky decomposition of the projected Hessian making + * use of the function computeCholesky() or computeProjectedCholesky(). + * \return SUCCESSFUL_RETURN \n + * RET_HESSIAN_NOT_SPD \n + * RET_INDEXLIST_CORRUPTED */ + virtual returnValue setupInitialCholesky( ); + + /** Initialises TQ factorisation of A (i.e. A*Q = [0 T]) if NO constraint is active. + * \return SUCCESSFUL_RETURN \n + RET_INDEXLIST_CORRUPTED */ + virtual returnValue setupTQfactorisation( ); + + + /** Obtains the desired working set for the auxiliary initial QP in + * accordance with the user specifications + * (assumes that member AX has already been initialised!) + * \return SUCCESSFUL_RETURN \n + RET_OBTAINING_WORKINGSET_FAILED \n + RET_INVALID_ARGUMENTS */ + returnValue obtainAuxiliaryWorkingSet( const real_t* const xOpt, /**< Optimal primal solution vector. + * If a NULL pointer is passed, all entries are assumed to be zero. */ + const real_t* const yOpt, /**< Optimal dual solution vector. + * If a NULL pointer is passed, all entries are assumed to be zero. */ + const Bounds* const guessedBounds, /**< Guessed working set of bounds for solution (xOpt,yOpt). */ + const Constraints* const guessedConstraints, /**< Guessed working set for solution (xOpt,yOpt). */ + Bounds* auxiliaryBounds, /**< Input: Allocated bound object. \n + * Ouput: Working set of constraints for auxiliary QP. */ + Constraints* auxiliaryConstraints /**< Input: Allocated bound object. \n + * Ouput: Working set for auxiliary QP. */ + ) const; + + /** Sets up bound and constraints data structures according to auxiliaryBounds/Constraints. + * (If the working set shall be setup afresh, make sure that + * bounds and constraints data structure have been resetted + * and the TQ factorisation has been initialised!) + * \return SUCCESSFUL_RETURN \n + RET_SETUP_WORKINGSET_FAILED \n + RET_INVALID_ARGUMENTS \n + RET_UNKNOWN_BUG */ + virtual returnValue setupAuxiliaryWorkingSet( const Bounds* const auxiliaryBounds, /**< Working set of bounds for auxiliary QP. */ + const Constraints* const auxiliaryConstraints, /**< Working set of constraints for auxiliary QP. */ + BooleanType setupAfresh /**< Flag indicating if given working set shall be + * setup afresh or by updating the current one. */ + ); + + /** Sets up the optimal primal/dual solution of the auxiliary initial QP. + * \return SUCCESSFUL_RETURN */ + returnValue setupAuxiliaryQPsolution( const real_t* const xOpt, /**< Optimal primal solution vector. + * If a NULL pointer is passed, all entries are set to zero. */ + const real_t* const yOpt /**< Optimal dual solution vector. + * If a NULL pointer is passed, all entries are set to zero. */ + ); + + /** Sets up gradient of the auxiliary initial QP for given + * optimal primal/dual solution and given initial working set + * (assumes that members X, Y and BOUNDS, CONSTRAINTS have already been initialised!). + * \return SUCCESSFUL_RETURN */ + returnValue setupAuxiliaryQPgradient( ); + + /** Sets up (constraints') bounds of the auxiliary initial QP for given + * optimal primal/dual solution and given initial working set + * (assumes that members X, Y and BOUNDS, CONSTRAINTS have already been initialised!). + * \return SUCCESSFUL_RETURN \n + RET_UNKNOWN_BUG */ + returnValue setupAuxiliaryQPbounds( const Bounds* const auxiliaryBounds, /**< Working set of bounds for auxiliary QP. */ + const Constraints* const auxiliaryConstraints, /**< Working set of constraints for auxiliary QP. */ + BooleanType useRelaxation /**< Flag indicating if inactive (constraints') bounds shall be relaxed. */ + ); + + + /** Adds a constraint to active set. + * \return SUCCESSFUL_RETURN \n + RET_ADDCONSTRAINT_FAILED \n + RET_ADDCONSTRAINT_FAILED_INFEASIBILITY \n + RET_ENSURELI_FAILED */ + virtual returnValue addConstraint( int_t number, /**< Number of constraint to be added to active set. */ + SubjectToStatus C_status, /**< Status of new active constraint. */ + BooleanType updateCholesky, /**< Flag indicating if Cholesky decomposition shall be updated. */ + BooleanType ensureLI = BT_TRUE /**< Ensure linear independence by exchange rules by default. */ + ); + + /** Checks if new active constraint to be added is linearly dependent from + * from row of the active constraints matrix. + * \return RET_LINEARLY_DEPENDENT \n + RET_LINEARLY_INDEPENDENT \n + RET_INDEXLIST_CORRUPTED */ + virtual returnValue addConstraint_checkLI( int_t number /**< Number of constraint to be added to active set. */ + ); + + /** Ensures linear independence of constraint matrix when a new constraint is added. + * To this end a bound or constraint is removed simultaneously if necessary. + * \return SUCCESSFUL_RETURN \n + RET_LI_RESOLVED \n + RET_ENSURELI_FAILED \n + RET_ENSURELI_FAILED_TQ \n + RET_ENSURELI_FAILED_NOINDEX \n + RET_REMOVE_FROM_ACTIVESET */ + virtual returnValue addConstraint_ensureLI( int_t number, /**< Number of constraint to be added to active set. */ + SubjectToStatus C_status /**< Status of new active bound. */ + ); + + /** Adds a bound to active set. + * \return SUCCESSFUL_RETURN \n + RET_ADDBOUND_FAILED \n + RET_ADDBOUND_FAILED_INFEASIBILITY \n + RET_ENSURELI_FAILED */ + virtual returnValue addBound( int_t number, /**< Number of bound to be added to active set. */ + SubjectToStatus B_status, /**< Status of new active bound. */ + BooleanType updateCholesky, /**< Flag indicating if Cholesky decomposition shall be updated. */ + BooleanType ensureLI = BT_TRUE /**< Ensure linear independence by exchange rules by default. */ + ); + + /** Checks if new active bound to be added is linearly dependent from + * from row of the active constraints matrix. + * \return RET_LINEARLY_DEPENDENT \n + RET_LINEARLY_INDEPENDENT */ + virtual returnValue addBound_checkLI( int_t number /**< Number of bound to be added to active set. */ + ); + + /** Ensures linear independence of constraint matrix when a new bound is added. + * To this end a bound or constraint is removed simultaneously if necessary. + * \return SUCCESSFUL_RETURN \n + RET_LI_RESOLVED \n + RET_ENSURELI_FAILED \n + RET_ENSURELI_FAILED_TQ \n + RET_ENSURELI_FAILED_NOINDEX \n + RET_REMOVE_FROM_ACTIVESET */ + virtual returnValue addBound_ensureLI( int_t number, /**< Number of bound to be added to active set. */ + SubjectToStatus B_status /**< Status of new active bound. */ + ); + + /** Removes a constraint from active set. + * \return SUCCESSFUL_RETURN \n + RET_CONSTRAINT_NOT_ACTIVE \n + RET_REMOVECONSTRAINT_FAILED \n + RET_HESSIAN_NOT_SPD */ + virtual returnValue removeConstraint( int_t number, /**< Number of constraint to be removed from active set. */ + BooleanType updateCholesky, /**< Flag indicating if Cholesky decomposition shall be updated. */ + BooleanType allowFlipping = BT_FALSE, /**< Flag indicating if flipping bounds are allowed. */ + BooleanType ensureNZC = BT_FALSE /**< Flag indicating if non-zero curvature is ensured by exchange rules. */ + ); + + /** Removes a bounds from active set. + * \return SUCCESSFUL_RETURN \n + RET_BOUND_NOT_ACTIVE \n + RET_HESSIAN_NOT_SPD \n + RET_REMOVEBOUND_FAILED */ + virtual returnValue removeBound( int_t number, /**< Number of bound to be removed from active set. */ + BooleanType updateCholesky, /**< Flag indicating if Cholesky decomposition shall be updated. */ + BooleanType allowFlipping = BT_FALSE, /**< Flag indicating if flipping bounds are allowed. */ + BooleanType ensureNZC = BT_FALSE /**< Flag indicating if non-zero curvature is ensured by exchange rules. */ + ); + + + /** Performs robustified ratio test yield the maximum possible step length + * along the homotopy path. + * \return SUCCESSFUL_RETURN */ + returnValue performPlainRatioTest( int_t nIdx, /**< Number of ratios to be checked. */ + const int_t* const idxList, /**< Array containing the indices of all ratios to be checked. */ + const real_t* const num, /**< Array containing all numerators for performing the ratio test. */ + const real_t* const den, /**< Array containing all denominators for performing the ratio test. */ + real_t epsNum, /**< Numerator tolerance. */ + real_t epsDen, /**< Denominator tolerance. */ + real_t& t, /**< Output: Maximum possible step length along the homotopy path. */ + int_t& BC_idx /**< Output: Index of blocking constraint. */ + ) const; + + + /** Ensure non-zero curvature by primal jump. + * \return SUCCESSFUL_RETURN \n + * RET_HOTSTART_STOPPED_UNBOUNDEDNESS */ + returnValue ensureNonzeroCurvature( + BooleanType removeBoundNotConstraint, /**< SubjectTo to be removed is a bound. */ + int_t remIdx, /**< Index of bound/constraint to be removed. */ + BooleanType &exchangeHappened, /**< Output: Exchange was necessary to ensure. */ + BooleanType &addBoundNotConstraint, /**< SubjectTo to be added is a bound. */ + int_t &addIdx, /**< Index of bound/constraint to be added. */ + SubjectToStatus &addStatus /**< Status of bound/constraint to be added. */ + ); + + + /** Solves the system Ta = b or T^Ta = b where T is a reverse upper triangular matrix. + * \return SUCCESSFUL_RETURN \n + RET_DIV_BY_ZERO */ + virtual returnValue backsolveT( const real_t* const b, /**< Right hand side vector. */ + BooleanType transposed, /**< Indicates if the transposed system shall be solved. */ + real_t* const a /**< Output: Solution vector */ + ) const; + + + /** Determines step direction of the shift of the QP data. + * \return SUCCESSFUL_RETURN */ + returnValue determineDataShift( const real_t* const g_new, /**< New gradient vector. */ + const real_t* const lbA_new,/**< New lower constraints' bounds. */ + const real_t* const ubA_new,/**< New upper constraints' bounds. */ + const real_t* const lb_new, /**< New lower bounds. */ + const real_t* const ub_new, /**< New upper bounds. */ + real_t* const delta_g, /**< Output: Step direction of gradient vector. */ + real_t* const delta_lbA, /**< Output: Step direction of lower constraints' bounds. */ + real_t* const delta_ubA, /**< Output: Step direction of upper constraints' bounds. */ + real_t* const delta_lb, /**< Output: Step direction of lower bounds. */ + real_t* const delta_ub, /**< Output: Step direction of upper bounds. */ + BooleanType& Delta_bC_isZero,/**< Output: Indicates if active constraints' bounds are to be shifted. */ + BooleanType& Delta_bB_isZero/**< Output: Indicates if active bounds are to be shifted. */ + ); + + /** Determines step direction of the homotopy path. + * \return SUCCESSFUL_RETURN \n + RET_STEPDIRECTION_FAILED_TQ \n + RET_STEPDIRECTION_FAILED_CHOLESKY */ + virtual returnValue determineStepDirection( const real_t* const delta_g, /**< Step direction of gradient vector. */ + const real_t* const delta_lbA, /**< Step direction of lower constraints' bounds. */ + const real_t* const delta_ubA, /**< Step direction of upper constraints' bounds. */ + const real_t* const delta_lb, /**< Step direction of lower bounds. */ + const real_t* const delta_ub, /**< Step direction of upper bounds. */ + BooleanType Delta_bC_isZero, /**< Indicates if active constraints' bounds are to be shifted. */ + BooleanType Delta_bB_isZero, /**< Indicates if active bounds are to be shifted. */ + real_t* const delta_xFX, /**< Output: Primal homotopy step direction of fixed variables. */ + real_t* const delta_xFR, /**< Output: Primal homotopy step direction of free variables. */ + real_t* const delta_yAC, /**< Output: Dual homotopy step direction of active constraints' multiplier. */ + real_t* const delta_yFX /**< Output: Dual homotopy step direction of fixed variables' multiplier. */ + ); + + /** Determines the maximum possible step length along the homotopy path + * and performs this step (without changing working set). + * \return SUCCESSFUL_RETURN \n + * RET_ERROR_IN_CONSTRAINTPRODUCT \n + * RET_QP_INFEASIBLE */ + returnValue performStep( const real_t* const delta_g, /**< Step direction of gradient. */ + const real_t* const delta_lbA, /**< Step direction of lower constraints' bounds. */ + const real_t* const delta_ubA, /**< Step direction of upper constraints' bounds. */ + const real_t* const delta_lb, /**< Step direction of lower bounds. */ + const real_t* const delta_ub, /**< Step direction of upper bounds. */ + const real_t* const delta_xFX, /**< Primal homotopy step direction of fixed variables. */ + const real_t* const delta_xFR, /**< Primal homotopy step direction of free variables. */ + const real_t* const delta_yAC, /**< Dual homotopy step direction of active constraints' multiplier. */ + const real_t* const delta_yFX, /**< Dual homotopy step direction of fixed variables' multiplier. */ + int_t& BC_idx, /**< Output: Index of blocking constraint. */ + SubjectToStatus& BC_status, /**< Output: Status of blocking constraint. */ + BooleanType& BC_isBound /**< Output: Indicates if blocking constraint is a bound. */ + ); + + /** Updates the active set. + * \return SUCCESSFUL_RETURN \n + RET_REMOVE_FROM_ACTIVESET_FAILED \n + RET_ADD_TO_ACTIVESET_FAILED */ + returnValue changeActiveSet( int_t BC_idx, /**< Index of blocking constraint. */ + SubjectToStatus BC_status, /**< Status of blocking constraint. */ + BooleanType BC_isBound /**< Indicates if blocking constraint is a bound. */ + ); + + + /** Compute relative length of homotopy in data space for termination + * criterion. + * \return Relative length in data space. */ + real_t getRelativeHomotopyLength( const real_t* const g_new, /**< Final gradient. */ + const real_t* const lb_new, /**< Final lower variable bounds. */ + const real_t* const ub_new, /**< Final upper variable bounds. */ + const real_t* const lbA_new, /**< Final lower constraint bounds. */ + const real_t* const ubA_new /**< Final upper constraint bounds. */ + ); + + + /** Ramping Strategy to avoid ties. Modifies homotopy start without + * changing current active set. + * \return SUCCESSFUL_RETURN */ + virtual returnValue performRamping( ); + + + /** ... */ + returnValue updateFarBounds( real_t curFarBound, /**< ... */ + int_t nRamp, /**< ... */ + const real_t* const lb_new, /**< ... */ + real_t* const lb_new_far, /**< ... */ + const real_t* const ub_new, /**< ... */ + real_t* const ub_new_far, /**< ... */ + const real_t* const lbA_new, /**< ... */ + real_t* const lbA_new_far, /**< ... */ + const real_t* const ubA_new, /**< ... */ + real_t* const ubA_new_far /**< ... */ + ) const; + + + /** Drift correction at end of each active set iteration + * \return SUCCESSFUL_RETURN */ + virtual returnValue performDriftCorrection( ); + + + /** Updates QP vectors, working sets and internal data structures in order to + start from an optimal solution corresponding to initial guesses of the working + set for bounds and constraints. + * \return SUCCESSFUL_RETURN \n + * RET_SETUP_AUXILIARYQP_FAILED \n + RET_INVALID_ARGUMENTS */ + using QProblemB::setupAuxiliaryQP; + virtual returnValue setupAuxiliaryQP( const Bounds* const guessedBounds, /**< Initial guess for working set of bounds. */ + const Constraints* const guessedConstraints /**< Initial guess for working set of constraints. */ + ); + + /** Determines if it is more efficient to refactorise the matrices when + * hotstarting or not (i.e. better to update the existing factorisations). + * \return BT_TRUE iff matrices shall be refactorised afresh + */ + BooleanType shallRefactorise( const Bounds* const guessedBounds, /**< Guessed new working set of bounds. */ + const Constraints* const guessedConstraints /**< Guessed new working set of constraints. */ + ) const; + + /** Sets up internal QP data. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS \n + RET_UNKNONW_BUG */ + returnValue setupQPdata( SymmetricMatrix *_H, /**< Hessian matrix. \n + If Hessian matrix is trivial,a NULL pointer can be passed. */ + const real_t* const _g, /**< Gradient vector. */ + Matrix *_A, /**< Constraint matrix. */ + const real_t* const _lb, /**< Lower bound vector (on variables). \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const _ub, /**< Upper bound vector (on variables). \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const _lbA, /**< Lower constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const _ubA /**< Upper constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + ); + + + /** Sets up dense internal QP data. If the current Hessian is trivial + * (i.e. HST_ZERO or HST_IDENTITY) but a non-trivial one is given, + * memory for Hessian is allocated and it is set to the given one. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS \n + RET_UNKNONW_BUG */ + returnValue setupQPdata( const real_t* const _H, /**< Hessian matrix. \n + If Hessian matrix is trivial,a NULL pointer can be passed. */ + const real_t* const _g, /**< Gradient vector. */ + const real_t* const _A, /**< Constraint matrix. */ + const real_t* const _lb, /**< Lower bound vector (on variables). \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const _ub, /**< Upper bound vector (on variables). \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const _lbA, /**< Lower constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const _ubA /**< Upper constraints' bound vector. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + ); + + /** Sets up internal QP data by loading it from files. If the current Hessian + * is trivial (i.e. HST_ZERO or HST_IDENTITY) but a non-trivial one is given, + * memory for Hessian is allocated and it is set to the given one. + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE \n + RET_UNABLE_TO_READ_FILE \n + RET_INVALID_ARGUMENTS \n + RET_UNKNONW_BUG */ + returnValue setupQPdataFromFile( const char* const H_file, /**< Name of file where Hessian matrix, of neighbouring QP to be solved, is stored. \n + If Hessian matrix is trivial,a NULL pointer can be passed. */ + const char* const g_file, /**< Name of file where gradient, of neighbouring QP to be solved, is stored. */ + const char* const A_file, /**< Name of file where constraint matrix, of neighbouring QP to be solved, is stored. */ + const char* const lb_file, /**< Name of file where lower bounds, of neighbouring QP to be solved, is stored. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bounds, of neighbouring QP to be solved, is stored. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const char* const lbA_file, /**< Name of file where lower constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const char* const ubA_file /**< Name of file where upper constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + ); + + /** Loads new QP vectors from files (internal members are not affected!). + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE \n + RET_UNABLE_TO_READ_FILE \n + RET_INVALID_ARGUMENTS */ + returnValue loadQPvectorsFromFile( const char* const g_file, /**< Name of file where gradient, of neighbouring QP to be solved, is stored. */ + const char* const lb_file, /**< Name of file where lower bounds, of neighbouring QP to be solved, is stored. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bounds, of neighbouring QP to be solved, is stored. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const char* const lbA_file, /**< Name of file where lower constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const char* const ubA_file, /**< Name of file where upper constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + real_t* const g_new, /**< Output: Gradient of neighbouring QP to be solved. */ + real_t* const lb_new, /**< Output: Lower bounds of neighbouring QP to be solved */ + real_t* const ub_new, /**< Output: Upper bounds of neighbouring QP to be solved */ + real_t* const lbA_new, /**< Output: Lower constraints' bounds of neighbouring QP to be solved */ + real_t* const ubA_new /**< Output: Upper constraints' bounds of neighbouring QP to be solved */ + ) const; + + + /** Prints concise information on the current iteration. + * \return SUCCESSFUL_RETURN \n */ + returnValue printIteration( int_t iter, /**< Number of current iteration. */ + int_t BC_idx, /**< Index of blocking constraint. */ + SubjectToStatus BC_status, /**< Status of blocking constraint. */ + BooleanType BC_isBound, /**< Indicates if blocking constraint is a bound. */ + real_t homotopyLength, /**< Current homotopy distance. */ + BooleanType isFirstCall = BT_TRUE /**< Indicating whether this is the first call for current QP. */ + ); + + + /** Sets constraint matrix of the QP. \n + Note: Also internal vector Ax is recomputed! + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + inline returnValue setA( Matrix *A_new /**< New constraint matrix (a shallow copy is made). */ + ); + + /** Sets dense constraint matrix of the QP. \n + Note: Also internal vector Ax is recomputed! + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + inline returnValue setA( const real_t* const A_new /**< New dense constraint matrix (with correct dimension!), a shallow copy is made. */ + ); + + + /** Sets constraints' lower bound vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_QPOBJECT_NOT_SETUP */ + inline returnValue setLBA( const real_t* const lbA_new /**< New constraints' lower bound vector (with correct dimension!). */ + ); + + /** Changes single entry of lower constraints' bound vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_QPOBJECT_NOT_SETUP \n + * RET_INDEX_OUT_OF_BOUNDS */ + inline returnValue setLBA( int_t number, /**< Number of entry to be changed. */ + real_t value /**< New value for entry of lower constraints' bound vector (with correct dimension!). */ + ); + + /** Sets constraints' upper bound vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_QPOBJECT_NOT_SETUP */ + inline returnValue setUBA( const real_t* const ubA_new /**< New constraints' upper bound vector (with correct dimension!). */ + ); + + /** Changes single entry of upper constraints' bound vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_QPOBJECT_NOT_SETUP \n + * RET_INDEX_OUT_OF_BOUNDS */ + inline returnValue setUBA( int_t number, /**< Number of entry to be changed. */ + real_t value /**< New value for entry of upper constraints' bound vector (with correct dimension!). */ + ); + + + /** Drops the blocking bound/constraint that led to infeasibility, or finds another + * bound/constraint to drop according to drop priorities. + * \return SUCCESSFUL_RETURN \n + */ + returnValue dropInfeasibles ( int_t BC_number, /**< Number of the bound or constraint to be added. */ + SubjectToStatus BC_status, /**< New status of the bound or constraint to be added. */ + BooleanType BC_isBound, /**< Whether a bound or a constraint is to be added. */ + real_t *xiB, /**< (not yet documented) */ + real_t *xiC /**< (not yet documented) */ + ); + + /** Decides if lower bounds are smaller than upper bounds + * + * \return SUCCESSFUL_RETURN \n + * RET_QP_INFEASIBLE */ + + returnValue areBoundsConsistent(const real_t* const lb, /**< Vector of lower bounds*/ + const real_t* const ub, /**< Vector of upper bounds*/ + const real_t* const lbA, /**< Vector of lower constraints*/ + const real_t* const ubA /**< Vector of upper constraints*/ + ) const; + + + public: + /** ... + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE */ + returnValue writeQpDataIntoMatFile( const char* const filename /**< Mat file name. */ + ) const; + + /** ... + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE */ + returnValue writeQpWorkspaceIntoMatFile( const char* const filename /**< Mat file name. */ + ); + + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + BooleanType freeConstraintMatrix; /**< Flag indicating whether the constraint matrix needs to be de-allocated. */ + Matrix* A; /**< Constraint matrix. */ + + real_t* lbA; /**< Lower constraints' bound vector. */ + real_t* ubA; /**< Upper constraints' bound vector. */ + + Constraints constraints; /**< Data structure for problem's constraints. */ + + real_t* T; /**< Reverse triangular matrix, A = [0 T]*Q'. */ + real_t* Q; /**< Orthonormal quadratic matrix, A = [0 T]*Q'. */ + int_t sizeT; /**< Matrix T is stored in a (sizeT x sizeT) array. */ + + real_t* Ax; /**< Stores the current A*x \n + * (for increased efficiency only). */ + real_t* Ax_l; /**< Stores the current distance to lower constraints' bounds A*x-lbA \n + * (for increased efficiency only). */ + real_t* Ax_u; /**< Stores the current distance to lower constraints' bounds ubA-A*x \n + * (for increased efficiency only). */ + + ConstraintProduct* constraintProduct; /**< Pointer to user-defined constraint product function. */ + + real_t* tempA; /**< Temporary for determineStepDirection. */ + real_t* tempB; /**< Temporary for determineStepDirection. */ + real_t* ZFR_delta_xFRz; /**< Temporary for determineStepDirection. */ + real_t* delta_xFRy; /**< Temporary for determineStepDirection. */ + real_t* delta_xFRz; /**< Temporary for determineStepDirection. */ + real_t* delta_yAC_TMP; /**< Temporary for determineStepDirection. */ + + real_t* tempC; /**< Temporary for constraint types. */ +}; + + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_QPROBLEM_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/QProblem.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/QProblem.ipp new file mode 100644 index 0000000..611fa31 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/QProblem.ipp @@ -0,0 +1,284 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/QProblem.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of inlined member functions of the QProblem class which + * is able to use the newly developed online active set strategy for + * parametric quadratic programming. + */ + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * g e t C o n s t r a i n t s + */ +inline returnValue QProblem::getConstraints( Constraints& _constraints ) const +{ + int_t nV = getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + _constraints = constraints; + + return SUCCESSFUL_RETURN; +} + + + +/* + * g e t N C + */ +inline int_t QProblem::getNC( ) const +{ + return constraints.getNC( ); +} + + +/* + * g e t N E C + */ +inline int_t QProblem::getNEC( ) const +{ + return constraints.getNEC( ); +} + + +/* + * g e t N A C + */ +inline int_t QProblem::getNAC( ) const +{ + return constraints.getNAC( ); +} + + +/* + * g e t N I A C + */ +inline int_t QProblem::getNIAC( ) const +{ + return constraints.getNIAC( ); +} + + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + + +/* + * s e t A + */ +inline returnValue QProblem::setA( Matrix *A_new ) +{ + int_t j; + int_t nV = getNV( ); + int_t nC = getNC( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + if ( A_new == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + /* Set constraint matrix AND update member AX. */ + if ( ( freeConstraintMatrix == BT_TRUE ) && ( A != 0 ) ) + { + delete A; + A = 0; + } + A = A_new; + freeConstraintMatrix = BT_FALSE; + + A->times(1, 1.0, x, nV, 0.0, Ax, nC); + + A->getRowNorm(tempC); + + for( j=0; jtimes(1, 1.0, x, nV, 0.0, Ax, nC); + + for( j=0; j= 0 ) && ( number < nC ) ) + { + lbA[number] = value; + return SUCCESSFUL_RETURN; + } + else + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); +} + + +/* + * s e t U B A + */ +inline returnValue QProblem::setUBA( const real_t* const ubA_new ) +{ + uint_t i; + uint_t nV = (uint_t)getNV( ); + uint_t nC = (uint_t)getNC( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + if ( ubA_new != 0 ) + { + memcpy( ubA,ubA_new,nC*sizeof(real_t) ); + } + else + { + /* if no upper constraints' bounds are specified, set them to infinity */ + for( i=0; i= 0 ) && ( number < nC ) ) + { + ubA[number] = value; + return SUCCESSFUL_RETURN; + } + else + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/QProblemB.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/QProblemB.hpp new file mode 100644 index 0000000..41eeb9f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/QProblemB.hpp @@ -0,0 +1,1021 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/QProblemB.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the QProblemB class which is able to use the newly + * developed online active set strategy for parametric quadratic programming + * for problems with (simple) bounds only. + */ + + + +#ifndef QPOASES_QPROBLEMB_HPP +#define QPOASES_QPROBLEMB_HPP + + +#include +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + +class SolutionAnalysis; + +/** + * \brief Implements the online active set strategy for box-constrained QPs. + * + * Class for setting up and solving quadratic programs with bounds (= box constraints) only. + * The main feature is the possibily to use the newly developed online active set strategy + * for parametric quadratic programming. + * + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + */ +class QProblemB +{ + /* allow SolutionAnalysis class to access private members */ + friend class SolutionAnalysis; + + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + QProblemB( ); + + /** Constructor which takes the QP dimension and Hessian type + * information. If the Hessian is the zero (i.e. HST_ZERO) or the + * identity matrix (i.e. HST_IDENTITY), respectively, no memory + * is allocated for it and a NULL pointer can be passed for it + * to the init() functions. */ + QProblemB( int_t _nV, /**< Number of variables. */ + HessianType _hessianType = HST_UNKNOWN, /**< Type of Hessian matrix. */ + BooleanType allocDenseMats = BT_TRUE /**< Enable allocation of dense matrices. */ + ); + + /** Copy constructor (deep copy). */ + QProblemB( const QProblemB& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~QProblemB( ); + + /** Assignment operator (deep copy). */ + virtual QProblemB& operator=( const QProblemB& rhs /**< Rhs object. */ + ); + + + /** Clears all data structures of QProblemB except for QP data. + * \return SUCCESSFUL_RETURN \n + RET_RESET_FAILED */ + virtual returnValue reset( ); + + + /** Initialises a simply bounded QP problem with given QP data and tries to solve it + * using at most nWSR iterations. Depending on the parameter constellation it: \n + * 1. 0, 0, 0 : starts with xOpt = 0, yOpt = 0 and gB empty (or all implicit equality bounds), \n + * 2. xOpt, 0, 0 : starts with xOpt, yOpt = 0 and obtain gB by "clipping", \n + * 3. 0, yOpt, 0 : starts with xOpt = 0, yOpt and obtain gB from yOpt != 0, \n + * 4. 0, 0, gB: starts with xOpt = 0, yOpt = 0 and gB, \n + * 5. xOpt, yOpt, 0 : starts with xOpt, yOpt and obtain gB from yOpt != 0, \n + * 6. xOpt, 0, gB: starts with xOpt, yOpt = 0 and gB, \n + * 7. xOpt, yOpt, gB: starts with xOpt, yOpt and gB (assume them to be consistent!) + * + * Note: This function internally calls solveInitialQP for initialisation! + * + * \return SUCCESSFUL_RETURN \n + RET_INIT_FAILED \n + RET_INIT_FAILED_CHOLESKY \n + RET_INIT_FAILED_HOTSTART \n + RET_INIT_FAILED_INFEASIBILITY \n + RET_INIT_FAILED_UNBOUNDEDNESS \n + RET_MAX_NWSR_REACHED \n + RET_INVALID_ARGUMENTS */ + returnValue init( SymmetricMatrix *_H, /**< Hessian matrix (a shallow copy is made). */ + const real_t* const _g, /**< Gradient vector. */ + const real_t* const _lb, /**< Lower bounds (on variables). \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const _ub, /**< Upper bounds (on variables). \n + If no upper bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations when using initial homotopy. \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP initialisation. \n + Output: CPU time spent for QP initialisation (if pointer passed). */ + const real_t* const xOpt = 0, /**< Optimal primal solution vector. A NULL pointer can be passed. \n + (If a null pointer is passed, the old primal solution is kept!) */ + const real_t* const yOpt = 0, /**< Optimal dual solution vector. A NULL pointer can be passed. \n + (If a null pointer is passed, the old dual solution is kept!) */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, all bounds are assumed inactive!) */ + const real_t* const _R = 0 /**< Pre-computed (upper triangular) Cholesky factor of Hessian matrix. + The Cholesky factor must be stored in a real_t array of size nV*nV + in row-major format. Note: Only used if xOpt/yOpt and gB are NULL! \n + (If a null pointer is passed, Cholesky decomposition is computed internally!) */ + ); + + /** Initialises a simply bounded QP problem with given QP data and tries to solve it + * using at most nWSR iterations. Depending on the parameter constellation it: \n + * 1. 0, 0, 0 : starts with xOpt = 0, yOpt = 0 and gB empty (or all implicit equality bounds), \n + * 2. xOpt, 0, 0 : starts with xOpt, yOpt = 0 and obtain gB by "clipping", \n + * 3. 0, yOpt, 0 : starts with xOpt = 0, yOpt and obtain gB from yOpt != 0, \n + * 4. 0, 0, gB: starts with xOpt = 0, yOpt = 0 and gB, \n + * 5. xOpt, yOpt, 0 : starts with xOpt, yOpt and obtain gB from yOpt != 0, \n + * 6. xOpt, 0, gB: starts with xOpt, yOpt = 0 and gB, \n + * 7. xOpt, yOpt, gB: starts with xOpt, yOpt and gB (assume them to be consistent!) + * + * Note: This function internally calls solveInitialQP for initialisation! + * + * \return SUCCESSFUL_RETURN \n + RET_INIT_FAILED \n + RET_INIT_FAILED_CHOLESKY \n + RET_INIT_FAILED_HOTSTART \n + RET_INIT_FAILED_INFEASIBILITY \n + RET_INIT_FAILED_UNBOUNDEDNESS \n + RET_MAX_NWSR_REACHED \n + RET_INVALID_ARGUMENTS */ + returnValue init( const real_t* const _H, /**< Hessian matrix (a shallow copy is made). \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + const real_t* const _g, /**< Gradient vector. */ + const real_t* const _lb, /**< Lower bounds (on variables). \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const _ub, /**< Upper bounds (on variables). \n + If no upper bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations when using initial homotopy. \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP initialisation. \n + Output: CPU time spent for QP initialisation (if pointer passed). */ + const real_t* const xOpt = 0, /**< Optimal primal solution vector. A NULL pointer can be passed. \n + (If a null pointer is passed, the old primal solution is kept!) */ + const real_t* const yOpt = 0, /**< Optimal dual solution vector. A NULL pointer can be passed. \n + (If a null pointer is passed, the old dual solution is kept!) */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, all bounds are assumed inactive!) */ + const real_t* const _R = 0 /**< Pre-computed (upper triangular) Cholesky factor of Hessian matrix. + The Cholesky factor must be stored in a real_t array of size nV*nV + in row-major format. Note: Only used if xOpt/yOpt and gB are NULL! \n + (If a null pointer is passed, Cholesky decomposition is computed internally!) */ + ); + + /** Initialises a simply bounded QP problem with given QP data to be read from files and solves it + * using at most nWSR iterations. Depending on the parameter constellation it: \n + * 1. 0, 0, 0 : starts with xOpt = 0, yOpt = 0 and gB empty (or all implicit equality bounds), \n + * 2. xOpt, 0, 0 : starts with xOpt, yOpt = 0 and obtain gB by "clipping", \n + * 3. 0, yOpt, 0 : starts with xOpt = 0, yOpt and obtain gB from yOpt != 0, \n + * 4. 0, 0, gB: starts with xOpt = 0, yOpt = 0 and gB, \n + * 5. xOpt, yOpt, 0 : starts with xOpt, yOpt and obtain gB from yOpt != 0, \n + * 6. xOpt, 0, gB: starts with xOpt, yOpt = 0 and gB, \n + * 7. xOpt, yOpt, gB: starts with xOpt, yOpt and gB (assume them to be consistent!) + * + * Note: This function internally calls solveInitialQP for initialisation! + * + * \return SUCCESSFUL_RETURN \n + RET_INIT_FAILED \n + RET_INIT_FAILED_CHOLESKY \n + RET_INIT_FAILED_HOTSTART \n + RET_INIT_FAILED_INFEASIBILITY \n + RET_INIT_FAILED_UNBOUNDEDNESS \n + RET_MAX_NWSR_REACHED \n + RET_UNABLE_TO_READ_FILE */ + returnValue init( const char* const H_file, /**< Name of file where Hessian matrix is stored. \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + const char* const g_file, /**< Name of file where gradient vector is stored. */ + const char* const lb_file, /**< Name of file where lower bound vector. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bound vector. \n + If no upper bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations when using initial homotopy. \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP initialisation. \n + Output: CPU time spent for QP initialisation (if pointer passed). */ + const real_t* const xOpt = 0, /**< Optimal primal solution vector. A NULL pointer can be passed. \n + (If a null pointer is passed, the old primal solution is kept!) */ + const real_t* const yOpt = 0, /**< Optimal dual solution vector. A NULL pointer can be passed. \n + (If a null pointer is passed, the old dual solution is kept!) */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, all bounds are assumed inactive!) */ + const char* const R_file = 0 /**< Name of the file where a pre-computed (upper triangular) Cholesky factor + of the Hessian matrix is stored. \n + (If a null pointer is passed, Cholesky decomposition is computed internally!) */ + ); + + + /** Solves an initialised QP sequence using the online active set strategy. + * By default, QP solution is started from previous solution. If a guess + * for the working set is provided, an initialised homotopy is performed. + * + * Note: This function internally calls solveQP/solveRegularisedQP + * for solving an initialised QP! + * + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS \n + RET_SETUP_AUXILIARYQP_FAILED */ + returnValue hotstart( const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0 /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set is kept!) */ + ); + + /** Solves an initialised QP sequence using the online active set strategy, + * where QP data is read from files. + * By default, QP solution is started from previous solution. If a guess + * for the working set is provided, an initialised homotopy is performed. + * + * Note: This function internally calls solveQP/solveRegularisedQP + * for solving an initialised QP! + * + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS \n + RET_UNABLE_TO_READ_FILE \n + RET_SETUP_AUXILIARYQP_FAILED \n + RET_INVALID_ARGUMENTS */ + returnValue hotstart( const char* const g_file, /**< Name of file where gradient, of neighbouring QP to be solved, is stored. */ + const char* const lb_file, /**< Name of file where lower bounds, of neighbouring QP to be solved, is stored. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bounds, of neighbouring QP to be solved, is stored. \n + If no upper bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0 /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set is kept!) */ + ); + + + /** Writes a vector with the state of the working set + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + virtual returnValue getWorkingSet( real_t* workingSet /** Output: array containing state of the working set. */ + ); + + /** Writes a vector with the state of the working set of bounds + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + virtual returnValue getWorkingSetBounds( real_t* workingSetB /** Output: array containing state of the working set of bounds. */ + ); + + /** Writes a vector with the state of the working set of constraints + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + virtual returnValue getWorkingSetConstraints( real_t* workingSetC /** Output: array containing state of the working set of constraints. */ + ); + + + /** Returns current bounds object of the QP (deep copy). + * \return SUCCESSFUL_RETURN \n + RET_QPOBJECT_NOT_SETUP */ + inline returnValue getBounds( Bounds& _bounds /** Output: Bounds object. */ + ) const; + + + /** Returns the number of variables. + * \return Number of variables. */ + inline int_t getNV( ) const; + + /** Returns the number of free variables. + * \return Number of free variables. */ + inline int_t getNFR( ) const; + + /** Returns the number of fixed variables. + * \return Number of fixed variables. */ + inline int_t getNFX( ) const; + + /** Returns the number of implicitly fixed variables. + * \return Number of implicitly fixed variables. */ + inline int_t getNFV( ) const; + + /** Returns the dimension of null space. + * \return Dimension of null space. */ + virtual int_t getNZ( ) const; + + + /** Returns the optimal objective function value. + * \return finite value: Optimal objective function value (QP was solved) \n + +infinity: QP was not yet solved */ + real_t getObjVal( ) const; + + /** Returns the objective function value at an arbitrary point x. + * \return Objective function value at point x */ + real_t getObjVal( const real_t* const _x /**< Point at which the objective function shall be evaluated. */ + ) const; + + /** Returns the primal solution vector. + * \return SUCCESSFUL_RETURN \n + RET_QP_NOT_SOLVED */ + returnValue getPrimalSolution( real_t* const xOpt /**< Output: Primal solution vector (if QP has been solved). */ + ) const; + + /** Returns the dual solution vector. + * \return SUCCESSFUL_RETURN \n + RET_QP_NOT_SOLVED */ + virtual returnValue getDualSolution( real_t* const yOpt /**< Output: Dual solution vector (if QP has been solved). */ + ) const; + + + /** Returns status of the solution process. + * \return Status of solution process. */ + inline QProblemStatus getStatus( ) const; + + + /** Returns if the QProblem object is initialised. + * \return BT_TRUE: QProblemB initialised \n + BT_FALSE: QProblemB not initialised */ + inline BooleanType isInitialised( ) const; + + /** Returns if the QP has been solved. + * \return BT_TRUE: QProblemB solved \n + BT_FALSE: QProblemB not solved */ + inline BooleanType isSolved( ) const; + + /** Returns if the QP is infeasible. + * \return BT_TRUE: QP infeasible \n + BT_FALSE: QP feasible (or not known to be infeasible!) */ + inline BooleanType isInfeasible( ) const; + + /** Returns if the QP is unbounded. + * \return BT_TRUE: QP unbounded \n + BT_FALSE: QP unbounded (or not known to be unbounded!) */ + inline BooleanType isUnbounded( ) const; + + + /** Returns Hessian type flag (type is not determined due to this call!). + * \return Hessian type. */ + inline HessianType getHessianType( ) const; + + /** Changes the print level. + * \return SUCCESSFUL_RETURN */ + inline returnValue setHessianType( HessianType _hessianType /**< New Hessian type. */ + ); + + /** Returns if the QP has been internally regularised. + * \return BT_TRUE: Hessian is internally regularised for QP solution \n + BT_FALSE: No internal Hessian regularisation is used for QP solution */ + inline BooleanType usingRegularisation( ) const; + + /** Returns current options struct. + * \return Current options struct. */ + inline Options getOptions( ) const; + + /** Overrides current options with given ones. + * \return SUCCESSFUL_RETURN */ + inline returnValue setOptions( const Options& _options /**< New options. */ + ); + + /** Returns the print level. + * \return Print level. */ + inline PrintLevel getPrintLevel( ) const; + + /** Changes the print level. + * \return SUCCESSFUL_RETURN */ + returnValue setPrintLevel( PrintLevel _printlevel /**< New print level. */ + ); + + + /** Returns the current number of QP problems solved. + * \return Number of QP problems solved. */ + inline uint_t getCount( ) const; + + /** Resets QP problem counter (to zero). + * \return SUCCESSFUL_RETURN. */ + inline returnValue resetCounter( ); + + + /** Prints concise list of properties of the current QP. + * \return SUCCESSFUL_RETURN \n */ + virtual returnValue printProperties( ); + + /** Prints a list of all options and their current values. + * \return SUCCESSFUL_RETURN \n */ + returnValue printOptions( ) const; + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const QProblemB& rhs /**< Rhs object. */ + ); + + /** If Hessian type has been set by the user, nothing is done. + * Otherwise the Hessian type is set to HST_IDENTITY, HST_ZERO, or + * HST_POSDEF (default), respectively. + * \return SUCCESSFUL_RETURN \n + RET_HESSIAN_INDEFINITE */ + returnValue determineHessianType( ); + + /** Determines type of existing constraints and bounds (i.e. implicitly fixed, unbounded etc.). + * \return SUCCESSFUL_RETURN \n + RET_SETUPSUBJECTTOTYPE_FAILED */ + virtual returnValue setupSubjectToType( ); + + /** Determines type of new constraints and bounds (i.e. implicitly fixed, unbounded etc.). + * \return SUCCESSFUL_RETURN \n + RET_SETUPSUBJECTTOTYPE_FAILED */ + virtual returnValue setupSubjectToType( const real_t* const lb_new, /**< New lower bounds. */ + const real_t* const ub_new /**< New upper bounds. */ + ); + + /** Computes the Cholesky decomposition of the (simply projected) Hessian + * (i.e. R^T*R = Z^T*H*Z). It only works in the case where Z is a simple + * projection matrix! + * Note: If Hessian turns out not to be positive definite, the Hessian type + * is set to HST_SEMIDEF accordingly. + * \return SUCCESSFUL_RETURN \n + * RET_HESSIAN_NOT_SPD \n + * RET_INDEXLIST_CORRUPTED */ + virtual returnValue computeCholesky( ); + + + /** Computes initial Cholesky decomposition of the (simply projected) Hessian + * making use of the function computeCholesky(). + * \return SUCCESSFUL_RETURN \n + * RET_HESSIAN_NOT_SPD \n + * RET_INDEXLIST_CORRUPTED */ + virtual returnValue setupInitialCholesky( ); + + /** Obtains the desired working set for the auxiliary initial QP in + * accordance with the user specifications + * \return SUCCESSFUL_RETURN \n + RET_OBTAINING_WORKINGSET_FAILED \n + RET_INVALID_ARGUMENTS */ + returnValue obtainAuxiliaryWorkingSet( const real_t* const xOpt, /**< Optimal primal solution vector. + * If a NULL pointer is passed, all entries are assumed to be zero. */ + const real_t* const yOpt, /**< Optimal dual solution vector. + * If a NULL pointer is passed, all entries are assumed to be zero. */ + const Bounds* const guessedBounds, /**< Guessed working set for solution (xOpt,yOpt). */ + Bounds* auxiliaryBounds /**< Input: Allocated bound object. \n + * Output: Working set for auxiliary QP. */ + ) const; + + /** Decides if lower bounds are smaller than upper bounds + * + * \return SUCCESSFUL_RETURN \n + * RET_QP_INFEASIBLE */ + + returnValue areBoundsConsistent(const real_t* const lb, /**< Vector of lower bounds*/ + const real_t* const ub /**< Vector of upper bounds*/ + ) const; + + /** Solves the system Ra = b or R^Ta = b where R is an upper triangular matrix. + * \return SUCCESSFUL_RETURN \n + RET_DIV_BY_ZERO */ + virtual returnValue backsolveR( const real_t* const b, /**< Right hand side vector. */ + BooleanType transposed, /**< Indicates if the transposed system shall be solved. */ + real_t* const a /**< Output: Solution vector */ + ) const; + + /** Solves the system Ra = b or R^Ta = b where R is an upper triangular matrix. \n + * Special variant for the case that this function is called from within "removeBound()". + * \return SUCCESSFUL_RETURN \n + RET_DIV_BY_ZERO */ + virtual returnValue backsolveR( const real_t* const b, /**< Right hand side vector. */ + BooleanType transposed, /**< Indicates if the transposed system shall be solved. */ + BooleanType removingBound, /**< Indicates if function is called from "removeBound()". */ + real_t* const a /**< Output: Solution vector */ + ) const; + + + /** Determines step direction of the shift of the QP data. + * \return SUCCESSFUL_RETURN */ + returnValue determineDataShift( const real_t* const g_new, /**< New gradient vector. */ + const real_t* const lb_new, /**< New lower bounds. */ + const real_t* const ub_new, /**< New upper bounds. */ + real_t* const delta_g, /**< Output: Step direction of gradient vector. */ + real_t* const delta_lb, /**< Output: Step direction of lower bounds. */ + real_t* const delta_ub, /**< Output: Step direction of upper bounds. */ + BooleanType& Delta_bB_isZero/**< Output: Indicates if active bounds are to be shifted. */ + ); + + + /** Sets up internal QP data. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS */ + returnValue setupQPdata( SymmetricMatrix *_H, /**< Hessian matrix.*/ + const real_t* const _g, /**< Gradient vector. */ + const real_t* const _lb, /**< Lower bounds (on variables). \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const _ub /**< Upper bounds (on variables). \n + If no upper bounds exist, a NULL pointer can be passed. */ + ); + + /** Sets up internal QP data. If the current Hessian is trivial + * (i.e. HST_ZERO or HST_IDENTITY) but a non-trivial one is given, + * memory for Hessian is allocated and it is set to the given one. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS \n + RET_NO_HESSIAN_SPECIFIED */ + returnValue setupQPdata( const real_t* const _H, /**< Hessian matrix. \n + If Hessian matrix is trivial,a NULL pointer can be passed. */ + const real_t* const _g, /**< Gradient vector. */ + const real_t* const _lb, /**< Lower bounds (on variables). \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const _ub /**< Upper bounds (on variables). \n + If no upper bounds exist, a NULL pointer can be passed. */ + ); + + /** Sets up internal QP data by loading it from files. If the current Hessian + * is trivial (i.e. HST_ZERO or HST_IDENTITY) but a non-trivial one is given, + * memory for Hessian is allocated and it is set to the given one. + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE \n + RET_UNABLE_TO_READ_FILE \n + RET_INVALID_ARGUMENTS \n + RET_NO_HESSIAN_SPECIFIED */ + returnValue setupQPdataFromFile( const char* const H_file, /**< Name of file where Hessian matrix, of neighbouring QP to be solved, is stored. \n + If Hessian matrix is trivial,a NULL pointer can be passed. */ + const char* const g_file, /**< Name of file where gradient, of neighbouring QP to be solved, is stored. */ + const char* const lb_file, /**< Name of file where lower bounds, of neighbouring QP to be solved, is stored. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file /**< Name of file where upper bounds, of neighbouring QP to be solved, is stored. \n + If no upper bounds exist, a NULL pointer can be passed. */ + ); + + /** Loads new QP vectors from files (internal members are not affected!). + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE \n + RET_UNABLE_TO_READ_FILE \n + RET_INVALID_ARGUMENTS */ + returnValue loadQPvectorsFromFile( const char* const g_file, /**< Name of file where gradient, of neighbouring QP to be solved, is stored. */ + const char* const lb_file, /**< Name of file where lower bounds, of neighbouring QP to be solved, is stored. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bounds, of neighbouring QP to be solved, is stored. \n + If no upper bounds exist, a NULL pointer can be passed. */ + real_t* const g_new, /**< Output: Gradient of neighbouring QP to be solved. */ + real_t* const lb_new, /**< Output: Lower bounds of neighbouring QP to be solved */ + real_t* const ub_new /**< Output: Upper bounds of neighbouring QP to be solved */ + ) const; + + + /** Sets internal infeasibility flag and throws given error in case the far bound + * strategy is not enabled (as QP might actually not be infeasible in this case). + * \return RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_ENSURELI_FAILED_CYCLING \n + RET_ENSURELI_FAILED_NOINDEX */ + returnValue setInfeasibilityFlag( returnValue returnvalue, /**< Returnvalue to be tunneled. */ + BooleanType doThrowError = BT_FALSE /**< Flag forcing to throw an error. */ + ); + + + /** Determines if next QP iteration can be performed within given CPU time limit. + * \return BT_TRUE: CPU time limit is exceeded, stop QP solution. \n + BT_FALSE: Sufficient CPU time for next QP iteration. */ + BooleanType isCPUtimeLimitExceeded( const real_t* const cputime, /**< Maximum CPU time allowed for QP solution. */ + real_t starttime, /**< Start time of current QP solution. */ + int_t nWSR /**< Number of working set recalculations performed so far. */ + ) const; + + + /** Regularise Hessian matrix by adding a scaled identity matrix to it. + * \return SUCCESSFUL_RETURN \n + RET_HESSIAN_ALREADY_REGULARISED */ + returnValue regulariseHessian( ); + + + /** Sets Hessian matrix of the QP. + * \return SUCCESSFUL_RETURN */ + inline returnValue setH( SymmetricMatrix* H_new /**< New Hessian matrix (a shallow copy is made). */ + ); + + /** Sets dense Hessian matrix of the QP. + * If a null pointer is passed and + * a) hessianType is HST_IDENTITY, nothing is done, + * b) hessianType is not HST_IDENTITY, Hessian matrix is set to zero. + * \return SUCCESSFUL_RETURN */ + inline returnValue setH( const real_t* const H_new /**< New dense Hessian matrix (with correct dimension!), a shallow copy is made. */ + ); + + /** Changes gradient vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ + inline returnValue setG( const real_t* const g_new /**< New gradient vector (with correct dimension!). */ + ); + + /** Changes lower bound vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_QPOBJECT_NOT_SETUP */ + inline returnValue setLB( const real_t* const lb_new /**< New lower bound vector (with correct dimension!). */ + ); + + /** Changes single entry of lower bound vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_QPOBJECT_NOT_SETUP \n + * RET_INDEX_OUT_OF_BOUNDS */ + inline returnValue setLB( int_t number, /**< Number of entry to be changed. */ + real_t value /**< New value for entry of lower bound vector. */ + ); + + /** Changes upper bound vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_QPOBJECT_NOT_SETUP */ + inline returnValue setUB( const real_t* const ub_new /**< New upper bound vector (with correct dimension!). */ + ); + + /** Changes single entry of upper bound vector of the QP. + * \return SUCCESSFUL_RETURN \n + * RET_QPOBJECT_NOT_SETUP \n + * RET_INDEX_OUT_OF_BOUNDS */ + inline returnValue setUB( int_t number, /**< Number of entry to be changed. */ + real_t value /**< New value for entry of upper bound vector. */ + ); + + + /** Computes parameters for the Givens matrix G for which [x,y]*G = [z,0] + * \return SUCCESSFUL_RETURN */ + inline void computeGivens( real_t xold, /**< Matrix entry to be normalised. */ + real_t yold, /**< Matrix entry to be annihilated. */ + real_t& xnew, /**< Output: Normalised matrix entry. */ + real_t& ynew, /**< Output: Annihilated matrix entry. */ + real_t& c, /**< Output: Cosine entry of Givens matrix. */ + real_t& s /**< Output: Sine entry of Givens matrix. */ + ) const; + + /** Applies Givens matrix determined by c and s (cf. computeGivens). + * \return SUCCESSFUL_RETURN */ + inline void applyGivens( real_t c, /**< Cosine entry of Givens matrix. */ + real_t s, /**< Sine entry of Givens matrix. */ + real_t nu, /**< Further factor: s/(1+c). */ + real_t xold, /**< Matrix entry to be transformed corresponding to + * the normalised entry of the original matrix. */ + real_t yold, /**< Matrix entry to be transformed corresponding to + * the annihilated entry of the original matrix. */ + real_t& xnew, /**< Output: Transformed matrix entry corresponding to + * the normalised entry of the original matrix. */ + real_t& ynew /**< Output: Transformed matrix entry corresponding to + * the annihilated entry of the original matrix. */ + ) const; + + + + /** Compute relative length of homotopy in data space for termination + * criterion. + * \return Relative length in data space. */ + real_t getRelativeHomotopyLength( const real_t* const g_new, /**< Final gradient. */ + const real_t* const lb_new, /**< Final lower variable bounds. */ + const real_t* const ub_new /**< Final upper variable bounds. */ + ); + + /** Ramping Strategy to avoid ties. Modifies homotopy start without + * changing current active set. + * \return SUCCESSFUL_RETURN */ + virtual returnValue performRamping( ); + + + /** ... */ + returnValue updateFarBounds( real_t curFarBound, /**< ... */ + int_t nRamp, /**< ... */ + const real_t* const lb_new, /**< ... */ + real_t* const lb_new_far, /**< ... */ + const real_t* const ub_new, /**< ... */ + real_t* const ub_new_far /**< ... */ + ) const; + + + /** Performs robustified ratio test yield the maximum possible step length + * along the homotopy path. + * \return SUCCESSFUL_RETURN */ + returnValue performRatioTest( int_t nIdx, /**< Number of ratios to be checked. */ + const int_t* const idxList, /**< Array containing the indices of all ratios to be checked. */ + const SubjectTo* const subjectTo, /**< Bound/Constraint object corresponding to ratios to be checked. */ + const real_t* const num, /**< Array containing all numerators for performing the ratio test. */ + const real_t* const den, /**< Array containing all denominators for performing the ratio test. */ + real_t epsNum, /**< Numerator tolerance. */ + real_t epsDen, /**< Denominator tolerance. */ + real_t& t, /**< Output: Maximum possible step length along the homotopy path. */ + int_t& BC_idx /**< Output: Index of blocking constraint. */ + ) const; + + /** Checks whether given ratio is blocking, i.e. limits the maximum step length + * along the homotopy path to a value lower than given one. + * \return SUCCESSFUL_RETURN */ + inline BooleanType isBlocking( real_t num, /**< Numerator for performing the ratio test. */ + real_t den, /**< Denominator for performing the ratio test. */ + real_t epsNum, /**< Numerator tolerance. */ + real_t epsDen, /**< Denominator tolerance. */ + real_t& t /**< Input: Current maximum step length along the homotopy path, + * Output: Updated maximum possible step length along the homotopy path. */ + ) const; + + + /** Creates a sparse diagonal (square-)matrix which is a given + * multiple of the identity matrix. + * \return Diagonal matrix \n + */ + SymSparseMat* createDiagSparseMat( int_t n, /**< Row/column dimension of matrix to be created. */ + real_t diagVal = 1.0 /**< Value of all diagonal entries. */ + ); + + + /* + * PRIVATE MEMBER FUNCTIONS + */ + private: + /** Solves a QProblemB whose QP data is assumed to be stored in the member variables. + * A guess for its primal/dual optimal solution vectors and the corresponding + * optimal working set can be provided. + * Note: This function is internally called by all init functions! + * \return SUCCESSFUL_RETURN \n + RET_INIT_FAILED \n + RET_INIT_FAILED_CHOLESKY \n + RET_INIT_FAILED_HOTSTART \n + RET_INIT_FAILED_INFEASIBILITY \n + RET_INIT_FAILED_UNBOUNDEDNESS \n + RET_MAX_NWSR_REACHED */ + returnValue solveInitialQP( const real_t* const xOpt, /**< Optimal primal solution vector.*/ + const real_t* const yOpt, /**< Optimal dual solution vector. */ + const Bounds* const guessedBounds, /**< Optimal working set of bounds for solution (xOpt,yOpt). */ + const real_t* const _R, /**< Pre-computed (upper triangular) Cholesky factor of Hessian matrix. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + * Output: Number of performed working set recalculations. */ + real_t* const cputime /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + ); + + /** Solves an initialised QProblemB using online active set strategy. + * Note: This function is internally called by all hotstart functions! + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS */ + returnValue solveQP( const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + int_t nWSRperformed = 0, /**< Number of working set recalculations already performed to solve + this QP within previous solveQP() calls. This number is + always zero, except for successive calls from solveRegularisedQP() + or when using the far bound strategy. */ + BooleanType isFirstCall = BT_TRUE /**< Indicating whether this is the first call for current QP. */ + ); + + + /** Solves an initialised QProblemB using online active set strategy. + * Note: This function is internally called by all hotstart functions! + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS */ + returnValue solveRegularisedQP( const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + int_t nWSRperformed = 0, /**< Number of working set recalculations already performed to solve + this QP within previous solveRegularisedQP() calls. This number is + always zero, except for successive calls when using the far bound strategy. */ + BooleanType isFirstCall = BT_TRUE /**< Indicating whether this is the first call for current QP. */ + ); + + + /** Sets up bound data structure according to auxiliaryBounds. + * (If the working set shall be setup afresh, make sure that + * bounds data structure has been resetted!) + * \return SUCCESSFUL_RETURN \n + RET_SETUP_WORKINGSET_FAILED \n + RET_INVALID_ARGUMENTS \n + RET_UNKNOWN_BUG */ + returnValue setupAuxiliaryWorkingSet( const Bounds* const auxiliaryBounds, /**< Working set for auxiliary QP. */ + BooleanType setupAfresh /**< Flag indicating if given working set shall be + * setup afresh or by updating the current one. */ + ); + + /** Sets up the optimal primal/dual solution of the auxiliary initial QP. + * \return SUCCESSFUL_RETURN */ + returnValue setupAuxiliaryQPsolution( const real_t* const xOpt, /**< Optimal primal solution vector. + * If a NULL pointer is passed, all entries are set to zero. */ + const real_t* const yOpt /**< Optimal dual solution vector. + * If a NULL pointer is passed, all entries are set to zero. */ + ); + + /** Sets up gradient of the auxiliary initial QP for given + * optimal primal/dual solution and given initial working set + * (assumes that members X, Y and BOUNDS have already been initialised!). + * \return SUCCESSFUL_RETURN */ + returnValue setupAuxiliaryQPgradient( ); + + /** Sets up bounds of the auxiliary initial QP for given + * optimal primal/dual solution and given initial working set + * (assumes that members X, Y and BOUNDS have already been initialised!). + * \return SUCCESSFUL_RETURN \n + RET_UNKNOWN_BUG */ + returnValue setupAuxiliaryQPbounds( BooleanType useRelaxation /**< Flag indicating if inactive bounds shall be relaxed. */ + ); + + + protected: + /** Updates QP vectors, working sets and internal data structures in order to + start from an optimal solution corresponding to initial guesses of the working + set for bounds + * \return SUCCESSFUL_RETURN \n + * RET_SETUP_AUXILIARYQP_FAILED */ + virtual returnValue setupAuxiliaryQP( const Bounds* const guessedBounds /**< Initial guess for working set of bounds. */ + ); + + private: + /** Determines step direction of the homotopy path. + * \return SUCCESSFUL_RETURN \n + RET_STEPDIRECTION_FAILED_CHOLESKY */ + returnValue determineStepDirection( const real_t* const delta_g, /**< Step direction of gradient vector. */ + const real_t* const delta_lb, /**< Step direction of lower bounds. */ + const real_t* const delta_ub, /**< Step direction of upper bounds. */ + BooleanType Delta_bB_isZero, /**< Indicates if active bounds are to be shifted. */ + real_t* const delta_xFX, /**< Output: Primal homotopy step direction of fixed variables. */ + real_t* const delta_xFR, /**< Output: Primal homotopy step direction of free variables. */ + real_t* const delta_yFX /**< Output: Dual homotopy step direction of fixed variables' multiplier. */ + ); + + /** Determines the maximum possible step length along the homotopy path + * and performs this step (without changing working set). + * \return SUCCESSFUL_RETURN \n + * RET_QP_INFEASIBLE \n + */ + returnValue performStep( const real_t* const delta_g, /**< Step direction of gradient. */ + const real_t* const delta_lb, /**< Step direction of lower bounds. */ + const real_t* const delta_ub, /**< Step direction of upper bounds. */ + const real_t* const delta_xFX, /**< Primal homotopy step direction of fixed variables. */ + const real_t* const delta_xFR, /**< Primal homotopy step direction of free variables. */ + const real_t* const delta_yFX, /**< Dual homotopy step direction of fixed variables' multiplier. */ + int_t& BC_idx, /**< Output: Index of blocking constraint. */ + SubjectToStatus& BC_status /**< Output: Status of blocking constraint. */ + ); + + /** Updates active set. + * \return SUCCESSFUL_RETURN \n + RET_REMOVE_FROM_ACTIVESET_FAILED \n + RET_ADD_TO_ACTIVESET_FAILED */ + returnValue changeActiveSet( int_t BC_idx, /**< Index of blocking constraint. */ + SubjectToStatus BC_status /**< Status of blocking constraint. */ + ); + + /** Drift correction at end of each active set iteration + * \return SUCCESSFUL_RETURN */ + virtual returnValue performDriftCorrection( ); + + /** Determines if it is more efficient to refactorise the matrices when + * hotstarting or not (i.e. better to update the existing factorisations). + * \return BT_TRUE iff matrices shall be refactorised afresh + */ + BooleanType shallRefactorise( const Bounds* const guessedBounds /**< Guessed new working set. */ + ) const; + + + /** Adds a bound to active set (specialised version for the case where no constraints exist). + * \return SUCCESSFUL_RETURN \n + RET_ADDBOUND_FAILED */ + returnValue addBound( int_t number, /**< Number of bound to be added to active set. */ + SubjectToStatus B_status, /**< Status of new active bound. */ + BooleanType updateCholesky /**< Flag indicating if Cholesky decomposition shall be updated. */ + ); + + /** Removes a bounds from active set (specialised version for the case where no constraints exist). + * \return SUCCESSFUL_RETURN \n + RET_HESSIAN_NOT_SPD \n + RET_REMOVEBOUND_FAILED */ + returnValue removeBound( int_t number, /**< Number of bound to be removed from active set. */ + BooleanType updateCholesky /**< Flag indicating if Cholesky decomposition shall be updated. */ + ); + + + /** Prints concise information on the current iteration. + * \return SUCCESSFUL_RETURN \n */ + returnValue printIteration( int_t iter, /**< Number of current iteration. */ + int_t BC_idx, /**< Index of blocking bound. */ + SubjectToStatus BC_status, /**< Status of blocking bound. */ + real_t homotopyLength, /**< Current homotopy distance. */ + BooleanType isFirstCall = BT_TRUE /**< Indicating whether this is the first call for current QP. */ + ); + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + BooleanType freeHessian; /**< Flag indicating whether the Hessian matrix needs to be de-allocated. */ + SymmetricMatrix* H; /**< Hessian matrix. */ + + real_t* g; /**< Gradient. */ + real_t* lb; /**< Lower bound vector (on variables). */ + real_t* ub; /**< Upper bound vector (on variables). */ + + Bounds bounds; /**< Data structure for problem's bounds. */ + + real_t* R; /**< Cholesky factor of H (i.e. H = R^T*R). */ + BooleanType haveCholesky; /**< Flag indicating whether Cholesky decomposition has already been setup. */ + + real_t* x; /**< Primal solution vector. */ + real_t* y; /**< Dual solution vector. */ + + real_t tau; /**< Last homotopy step length. */ + + QProblemStatus status; /**< Current status of the solution process. */ + + BooleanType infeasible; /**< QP infeasible? */ + BooleanType unbounded; /**< QP unbounded? */ + + HessianType hessianType; /**< Type of Hessian matrix. */ + real_t regVal; /**< Holds the offset used to regularise Hessian matrix (zero by default). */ + + uint_t count; /**< Counts the number of hotstart function calls. */ + + real_t *delta_xFR_TMP; /**< Temporary for determineStepDirection */ + + real_t ramp0; /**< Start value for Ramping Strategy. */ + real_t ramp1; /**< Final value for Ramping Strategy. */ + int_t rampOffset; /**< Offset index for Ramping. */ + + Options options; /**< Struct containing all user-defined options for solving QPs. */ + + Flipper flipper; /**< Struct for making a temporary copy of the matrix factorisations. */ + + TabularOutput tabularOutput; /**< Struct storing information for tabular output (printLevel == PL_TABULAR). */ +}; + + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_QPROBLEMB_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/QProblemB.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/QProblemB.ipp new file mode 100644 index 0000000..6831374 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/QProblemB.ipp @@ -0,0 +1,496 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/QProblemB.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of inlined member functions of the QProblemB class which + * is able to use the newly developed online active set strategy for + * parametric quadratic programming. + */ + + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + +/* + * g e t B o u n d s + */ +inline returnValue QProblemB::getBounds( Bounds& _bounds ) const +{ + int_t nV = getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + _bounds = bounds; + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t N V + */ +inline int_t QProblemB::getNV( ) const +{ + return bounds.getNV( ); +} + + +/* + * g e t N F R + */ +inline int_t QProblemB::getNFR( ) const +{ + return bounds.getNFR( ); +} + + +/* + * g e t N F X + */ +inline int_t QProblemB::getNFX( ) const +{ + return bounds.getNFX( ); +} + + +/* + * g e t N F V + */ +inline int_t QProblemB::getNFV( ) const +{ + return bounds.getNFV( ); +} + + +/* + * g e t S t a t u s + */ +inline QProblemStatus QProblemB::getStatus( ) const +{ + return status; +} + + +/* + * i s I n i t i a l i s e d + */ +inline BooleanType QProblemB::isInitialised( ) const +{ + if ( status == QPS_NOTINITIALISED ) + return BT_FALSE; + else + return BT_TRUE; +} + + +/* + * i s S o l v e d + */ +inline BooleanType QProblemB::isSolved( ) const +{ + if ( status == QPS_SOLVED ) + return BT_TRUE; + else + return BT_FALSE; +} + + +/* + * i s I n f e a s i b l e + */ +inline BooleanType QProblemB::isInfeasible( ) const +{ + return infeasible; +} + + +/* + * i s U n b o u n d e d + */ +inline BooleanType QProblemB::isUnbounded( ) const +{ + return unbounded; +} + + +/* + * g e t H e s s i a n T y p e + */ +inline HessianType QProblemB::getHessianType( ) const +{ + return hessianType; +} + + +/* + * s e t H e s s i a n T y p e + */ +inline returnValue QProblemB::setHessianType( HessianType _hessianType ) +{ + hessianType = _hessianType; + return SUCCESSFUL_RETURN; +} + + +/* + * u s i n g R e g u l a r i s a t i o n + */ +inline BooleanType QProblemB::usingRegularisation( ) const +{ + if ( regVal > ZERO ) + return BT_TRUE; + else + return BT_FALSE; +} + + +/* + * g e t O p t i o n s + */ +inline Options QProblemB::getOptions( ) const +{ + return options; +} + + +/* + * s e t O p t i o n s + */ +inline returnValue QProblemB::setOptions( const Options& _options + ) +{ + options = _options; + options.ensureConsistency( ); + + setPrintLevel( options.printLevel ); + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t P r i n t L e v e l + */ +inline PrintLevel QProblemB::getPrintLevel( ) const +{ + return options.printLevel; +} + + + +/* + * g e t C o u n t + */ +inline uint_t QProblemB::getCount( ) const +{ + return count; +} + + +/* + * r e s e t C o u n t e r + */ +inline returnValue QProblemB::resetCounter( ) +{ + count = 0; + return SUCCESSFUL_RETURN; +} + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * s e t H + */ +inline returnValue QProblemB::setH( SymmetricMatrix* H_new ) +{ + if ( ( freeHessian == BT_TRUE ) && ( H != 0 ) ) + { + delete H; + H = 0; + } + + H = H_new; + freeHessian = BT_FALSE; + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t H + */ +inline returnValue QProblemB::setH( const real_t* const H_new ) +{ + int_t nV = getNV(); + SymDenseMat* dH; + + /* if null pointer is passed, Hessian is set to zero matrix + * (or stays identity matrix) */ + if ( H_new == 0 ) + { + if ( hessianType == HST_IDENTITY ) + return SUCCESSFUL_RETURN; + + hessianType = HST_ZERO; + + if ( ( freeHessian == BT_TRUE ) && ( H != 0 ) ) + delete H; + + H = 0; + freeHessian = BT_FALSE; + } + else + { + if ( ( freeHessian == BT_TRUE ) && ( H != 0 ) ) + delete H; + + H = dH = new SymDenseMat( nV, nV, nV, (real_t*) H_new ); + freeHessian = BT_TRUE; + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t G + */ +inline returnValue QProblemB::setG( const real_t* const g_new ) +{ + uint_t nV = (uint_t)getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + if ( g_new == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + memcpy( g,g_new,nV*sizeof(real_t) ); + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t L B + */ +inline returnValue QProblemB::setLB( const real_t* const lb_new ) +{ + uint_t i; + uint_t nV = (uint_t)getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + if ( lb_new != 0 ) + { + memcpy( lb,lb_new,nV*sizeof(real_t) ); + } + else + { + /* if no lower bounds are specified, set them to -infinity */ + for( i=0; i= 0 ) && ( number < nV ) ) + { + lb[number] = value; + return SUCCESSFUL_RETURN; + } + else + { + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + } +} + + +/* + * s e t U B + */ +inline returnValue QProblemB::setUB( const real_t* const ub_new ) +{ + uint_t i; + uint_t nV = (uint_t)getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + if ( ub_new != 0 ) + { + memcpy( ub,ub_new,nV*sizeof(real_t) ); + } + else + { + /* if no upper bounds are specified, set them to infinity */ + for( i=0; i= 0 ) && ( number < nV ) ) + { + ub[number] = value; + + return SUCCESSFUL_RETURN; + } + else + { + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + } +} + + +/* + * c o m p u t e G i v e n s + */ +inline void QProblemB::computeGivens( real_t xold, real_t yold, real_t& xnew, real_t& ynew, + real_t& c, real_t& s + ) const +{ + real_t t, mu; + + if ( isZero( yold ) == BT_TRUE ) + { + c = 1.0; + s = 0.0; + + xnew = xold; + ynew = yold; + } + else + { + mu = getAbs( xold ); + if ( getAbs( yold ) > mu ) + mu = getAbs( yold ); + + t = mu * getSqrt( (xold/mu)*(xold/mu) + (yold/mu)*(yold/mu) ); + + if ( xold < 0.0 ) + t = -t; + + c = xold/t; + s = yold/t; + xnew = t; + ynew = 0.0; + } + + return; +} + + +/* + * a p p l y G i v e n s + */ +inline void QProblemB::applyGivens( real_t c, real_t s, real_t nu, real_t xold, real_t yold, + real_t& xnew, real_t& ynew + ) const +{ + #ifdef __USE_THREE_MULTS_GIVENS__ + + /* Givens plane rotation requiring only three multiplications, + * cf. Hammarling, S.: A note on modifications to the givens plane rotation. + * J. Inst. Maths Applics, 13:215-218, 1974. */ + xnew = xold*c + yold*s; + ynew = (xnew+xold)*nu - yold; + + #else + + /* Usual Givens plane rotation requiring four multiplications. */ + xnew = c*xold + s*yold; + ynew = -s*xold + c*yold; + + #endif + + return; +} + + +/* + * i s B l o c k i n g + */ +inline BooleanType QProblemB::isBlocking( real_t num, + real_t den, + real_t epsNum, + real_t epsDen, + real_t& t + ) const +{ + if ( ( den >= epsDen ) && ( num >= epsNum ) ) + { + if ( num < t*den ) + return BT_TRUE; + } + + return BT_FALSE; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblem.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblem.hpp new file mode 100644 index 0000000..8cf0250 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblem.hpp @@ -0,0 +1,359 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/SQProblem.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the SQProblem class which is able to use the newly + * developed online active set strategy for parametric quadratic programming + * with varying matrices. + */ + + + +#ifndef QPOASES_SQPROBLEM_HPP +#define QPOASES_SQPROBLEM_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Implements the online active set strategy for QPs with varying matrices. + * + * A class for setting up and solving quadratic programs with varying QP matrices. + * The main feature is the possibily to use the newly developed online active set strategy + * for parametric quadratic programming. + * + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + */ +class SQProblem : public QProblem +{ + /* allow SolutionAnalysis class to access private members */ + friend class SolutionAnalysis; + + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + SQProblem( ); + + /** Constructor which takes the QP dimension and Hessian type + * information. If the Hessian is the zero (i.e. HST_ZERO) or the + * identity matrix (i.e. HST_IDENTITY), respectively, no memory + * is allocated for it and a NULL pointer can be passed for it + * to the init() functions. */ + SQProblem( int_t _nV, /**< Number of variables. */ + int_t _nC, /**< Number of constraints. */ + HessianType _hessianType = HST_UNKNOWN, /**< Type of Hessian matrix. */ + BooleanType allocDenseMats = BT_TRUE /**< Enable allocation of dense matrices. */ + ); + + /** Copy constructor (deep copy). */ + SQProblem( const SQProblem& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~SQProblem( ); + + /** Assignment operator (deep copy). */ + virtual SQProblem& operator=( const SQProblem& rhs /**< Rhs object. */ + ); + + + /** Solves an initialised QP sequence with matrix shift using + * the online active set strategy. + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_MATRIX_SHIFT_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS \n + RET_SETUP_AUXILIARYQP_FAILED */ + returnValue hotstart( SymmetricMatrix *H_new, /**< Hessian matrix of neighbouring QP to be solved (a shallow copy is made). \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + Matrix *A_new, /**< Constraint matrix of neighbouring QP to be solved (a shallow copy is made). \n + If QP sequence does not involve constraints, a NULL pointer can be passed. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const lbA_new, /**< Lower constraints' bounds of neighbouring QP to be solved. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const ubA_new, /**< Upper constraints' bounds of neighbouring QP to be solved. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spen for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of bounds is kept!) */ + const Constraints* const guessedConstraints = 0 /**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of constraints is kept!) */ + ); + + /** Solves an initialised QP sequence with matrix shift using + * the online active set strategy. + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_MATRIX_SHIFT_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS \n + RET_SETUP_AUXILIARYQP_FAILED */ + returnValue hotstart( const real_t* const H_new, /**< Hessian matrix of neighbouring QP to be solved (a shallow copy is made). \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + const real_t* const A_new, /**< Constraint matrix of neighbouring QP to be solved (a shallow copy is made). \n + If QP sequence does not involve constraints, a NULL pointer can be passed. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const lbA_new, /**< Lower constraints' bounds of neighbouring QP to be solved. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const ubA_new, /**< Upper constraints' bounds of neighbouring QP to be solved. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of bounds is kept!) */ + const Constraints* const guessedConstraints = 0 /**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of constraints is kept!) */ + ); + + /** Solves an initialised QP sequence with matrix shift using + * the online active set strategy, where QP data is read from files. + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_MATRIX_SHIFT_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS \n + RET_SETUP_AUXILIARYQP_FAILED \n + RET_UNABLE_TO_READ_FILE \n + RET_INVALID_ARGUMENTS */ + returnValue hotstart( const char* const H_file, /**< Name of file where Hessian matrix is stored. \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + const char* const g_file, /**< Name of file where gradient, of neighbouring QP to be solved, is stored. */ + const char* const A_file, /**< Name of file where constraint matrix is stored. \n + If QP sequence does not involve constraints, a NULL pointer can be passed. */ + const char* const lb_file, /**< Name of file where lower bounds, of neighbouring QP to be solved, is stored. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bounds, of neighbouring QP to be solved, is stored. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const char* const lbA_file, /**< Name of file where lower constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const char* const ubA_file, /**< Name of file where upper constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of bounds is kept!) */ + const Constraints* const guessedConstraints = 0 /**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of constraints is kept!) */ + ); + + /** Solves an initialised QP sequence (without matrix shift) using + * the online active set strategy. + * By default, QP solution is started from previous solution. If a guess + * for the working set is provided, an initialised homotopy is performed. + * + * Note: This functions just forwards to the corresponding + * QProblem::hotstart member function. + * + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS */ + returnValue hotstart( const real_t* const g_new, /**< Gradient of neighbouring QP to be solved. */ + const real_t* const lb_new, /**< Lower bounds of neighbouring QP to be solved. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t* const ub_new, /**< Upper bounds of neighbouring QP to be solved. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const real_t* const lbA_new, /**< Lower constraints' bounds of neighbouring QP to be solved. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t* const ubA_new, /**< Upper constraints' bounds of neighbouring QP to be solved. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of bounds is kept!) */ + const Constraints* const guessedConstraints = 0 /**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of constraints is kept!) */ + ); + + /** Solves an initialised QP sequence (without matrix shift) using + * the online active set strategy, where QP data is read from files. + * By default, QP solution is started from previous solution. If a guess + * for the working set is provided, an initialised homotopy is performed. + * + * Note: This functions just forwards to the corresponding + * QProblem::hotstart member function. + * + * \return SUCCESSFUL_RETURN \n + RET_MAX_NWSR_REACHED \n + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED \n + RET_HOTSTART_FAILED \n + RET_SHIFT_DETERMINATION_FAILED \n + RET_STEPDIRECTION_DETERMINATION_FAILED \n + RET_STEPLENGTH_DETERMINATION_FAILED \n + RET_HOMOTOPY_STEP_FAILED \n + RET_HOTSTART_STOPPED_INFEASIBILITY \n + RET_HOTSTART_STOPPED_UNBOUNDEDNESS \n + RET_UNABLE_TO_READ_FILE \n + RET_INVALID_ARGUMENTS */ + returnValue hotstart( const char* const g_file, /**< Name of file where gradient, of neighbouring QP to be solved, is stored. */ + const char* const lb_file, /**< Name of file where lower bounds, of neighbouring QP to be solved, is stored. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const char* const ub_file, /**< Name of file where upper bounds, of neighbouring QP to be solved, is stored. \n + If no upper bounds exist, a NULL pointer can be passed. */ + const char* const lbA_file, /**< Name of file where lower constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const char* const ubA_file, /**< Name of file where upper constraints' bounds, of neighbouring QP to be solved, is stored. \n + If no upper constraints' bounds exist, a NULL pointer can be passed. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Number of performed working set recalculations. */ + real_t* const cputime = 0, /**< Input: Maximum CPU time allowed for QP solution. \n + Output: CPU time spent for QP solution (or to perform nWSR iterations). */ + const Bounds* const guessedBounds = 0, /**< Optimal working set of bounds for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of bounds is kept!) */ + const Constraints* const guessedConstraints = 0 /**< Optimal working set of constraints for solution (xOpt,yOpt). \n + (If a null pointer is passed, the previous working set of constraints is kept!) */ + ); + + + #ifdef __MATLAB__ + /** Sets pointer of Hessian and constraint matrix to zero. + * QUICK HACK FOR MAKING THE MATLAB INTERFACE RUN! TO BE REMOVED! + * \return SUCCESSFUL_RETURN */ + returnValue resetMatrixPointers( ); + #endif + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + + /** Sets new matrices and calculates their factorisations. If the + * current Hessian is trivial (i.e. HST_ZERO or HST_IDENTITY) but a + * non-trivial one is given, memory for Hessian is allocated and + * it is set to the given one. Afterwards, all QP vectors are + * transformed in order to start from an optimal solution. + * \return SUCCESSFUL_RETURN \n + * RET_MATRIX_FACTORISATION_FAILED \n + * RET_NO_HESSIAN_SPECIFIED */ + virtual returnValue setupNewAuxiliaryQP( SymmetricMatrix *H_new, /**< New Hessian matrix. \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + Matrix *A_new, /**< New constraint matrix. \n + If QP sequence does not involve constraints, a NULL pointer can be passed. */ + const real_t *lb_new, /**< New lower bounds. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t *ub_new, /**< New upper bounds. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t *lbA_new, /**< New lower constraints' bounds. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t *ubA_new /**< New lower constraints' bounds. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + ); + + /** Sets new matrices and calculates their factorisations. If the + * current Hessian is trivial (i.e. HST_ZERO or HST_IDENTITY) but a + * non-trivial one is given, memory for Hessian is allocated and + * it is set to the given one. Afterwards, all QP vectors are + * transformed in order to start from an optimal solution. + * \return SUCCESSFUL_RETURN \n + * RET_MATRIX_FACTORISATION_FAILED \n + * RET_NO_HESSIAN_SPECIFIED */ + virtual returnValue setupNewAuxiliaryQP( const real_t* const H_new, /**< New Hessian matrix. \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + const real_t* const A_new, /**< New constraint matrix. \n + If QP sequence does not involve constraints, a NULL pointer can be passed. */ + const real_t *lb_new, /**< New lower bounds. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t *ub_new, /**< New upper bounds. \n + If no lower bounds exist, a NULL pointer can be passed. */ + const real_t *lbA_new, /**< New lower constraints' bounds. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + const real_t *ubA_new /**< New lower constraints' bounds. \n + If no lower constraints' bounds exist, a NULL pointer can be passed. */ + ); + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + +}; + + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_SQPROBLEM_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblem.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblem.ipp new file mode 100644 index 0000000..518bfc6 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblem.ipp @@ -0,0 +1,51 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/SQProblem.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of inlined member functions of the SQProblem class which + * is able to use the newly developed online active set strategy for + * parametric quadratic programming with varying matrices. + */ + + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +BEGIN_NAMESPACE_QPOASES + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblemSchur.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblemSchur.hpp new file mode 100644 index 0000000..309e903 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblemSchur.hpp @@ -0,0 +1,425 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2014 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/SQProblemSchur.hpp + * \author Andreas Waechter and Dennis Janka, based on QProblem.hpp by Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2012-2017 + * + * Declaration of the SQProblemSchur class which is able to use the newly + * developed online active set strategy for parametric quadratic programming + * with varying matrices and uses a Schur Complement approach to solve + * the linear systems. + */ + + +#ifndef QPOASES_SQPROBLEMSCHUR_HPP +#define QPOASES_SQPROBLEMSCHUR_HPP + + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Implements the online active set strategy for QPs with varying, sparse matrices. + * + * A class for setting up and solving quadratic programs with varying, + * sparse QP matrices. Here, sparsity is exploited by means of a + * Schur complement approach to solve the linear systems. + * + * \author Andreas Waechter, Dennis Janka + * \version 3.2 + * \date 2012-2017 + */ +class SQProblemSchur : public SQProblem +{ + /* allow SolutionAnalysis class to access private members */ + friend class SolutionAnalysis; + + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + SQProblemSchur( ); + + /** Constructor which takes the QP dimension and Hessian type + * information. If the Hessian is the zero (i.e. HST_ZERO) or the + * identity matrix (i.e. HST_IDENTITY), respectively, no memory + * is allocated for it and a NULL pointer can be passed for it + * to the init() functions. */ + SQProblemSchur( int_t _nV, /**< Number of variables. */ + int_t _nC, /**< Number of constraints. */ + HessianType _hessianType = HST_UNKNOWN, /**< Type of Hessian matrix. */ + int_t maxSchurUpdates = 75 /**< Maximal number of Schur updates */ + ); + + /** Copy constructor (deep copy). */ + SQProblemSchur( const SQProblemSchur& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~SQProblemSchur( ); + + /** Assignment operator (deep copy). */ + virtual SQProblemSchur& operator=( const SQProblemSchur& rhs /**< Rhs object. */ + ); + + /** Clears all data structures of QProblem except for QP data. + * \return SUCCESSFUL_RETURN \n + RET_RESET_FAILED */ + virtual returnValue reset( ); + + /** Resets Schur complement. This sets up the KKT matrix for the + current activities, copies the activities, etc. TODO: Return values */ + returnValue resetSchurComplement( BooleanType allowInertiaCorrection ); + + /** Return the total number of sparse matrix factorizations performed so far. */ + inline int_t getNumFactorizations( ) const; + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const SQProblemSchur& rhs /**< Rhs object. */ + ); + + /** Computes the Cholesky decomposition of the projected Hessian (i.e. R^T*R = Z^T*H*Z). + * For the Schur complement version, this function only returns SUCCESSFUL_RETURN. */ + virtual returnValue computeProjectedCholesky( ); + + /** Computes initial Cholesky decomposition of the projected Hessian making + * use of the function setupCholeskyDecomposition() or setupCholeskyDecompositionProjected(). + * For the Schur complement version, this function only returns SUCCESSFUL_RETURN. */ + virtual returnValue computeInitialCholesky( ); + + /** Initialises TQ factorisation of A (i.e. A*Q = [0 T]) if NO constraint is active. + * For the Schur complement version, this function only returns SUCCESSFUL_RETURN. */ + virtual returnValue setupTQfactorisation( ); + + /** This method is overloaded from SQProblem. + * Sets new matrices and calculates their factorisations. If the + * current Hessian is trivial (i.e. HST_ZERO or HST_IDENTITY) but a + * non-trivial one is given, memory for Hessian is allocated and + * it is set to the given one. Afterwards, all QP vectors are + * transformed in order to start from an optimal solution. + * \return SUCCESSFUL_RETURN \n + * RET_MATRIX_FACTORISATION_FAILED \n + * RET_NO_HESSIAN_SPECIFIED */ + virtual returnValue setupAuxiliaryQP( SymmetricMatrix *H_new, /**< New Hessian matrix. \n + If Hessian matrix is trivial, a NULL pointer can be passed. */ + Matrix *A_new, /**< New constraint matrix. \n + If QP sequence does not involve constraints, a NULL pointer can be passed. */ + const real_t *lb_new, + const real_t *ub_new, + const real_t *lbA_new, + const real_t *ubA_new + ); + + /** Setup bounds and constraints data structures according to auxiliaryBounds/Constraints. + * Calls the sparse solver to obtain the factorization for the initial active set. + * \return SUCCESSFUL_RETURN \n + RET_SETUP_WORKINGSET_FAILED \n + RET_INVALID_ARGUMENTS \n + RET_UNKNOWN_BUG */ + virtual returnValue setupAuxiliaryWorkingSet( const Bounds* const auxiliaryBounds, + const Constraints* const auxiliaryConstraints, + BooleanType setupAfresh + ); + + + /** Adds a constraint to active set. + * \return SUCCESSFUL_RETURN \n + RET_ADDCONSTRAINT_FAILED \n + RET_ADDCONSTRAINT_FAILED_INFEASIBILITY \n + RET_ENSURELI_FAILED */ + virtual returnValue addConstraint( int_t number, /**< Number of constraint to be added to active set. */ + SubjectToStatus C_status, /**< Status of new active constraint. */ + BooleanType updateCholesky, /**< Flag indicating if Cholesky decomposition shall be updated. */ + BooleanType ensureLI = BT_TRUE /**< Ensure linear independence by exchange rules by default. */ + ); + + /** Checks if new active constraint to be added is linearly dependent from + * from row of the active constraints matrix. + * \return RET_LINEARLY_DEPENDENT \n + RET_LINEARLY_INDEPENDENT \n + RET_INDEXLIST_CORRUPTED */ + virtual returnValue addConstraint_checkLI( int_t number /**< Number of constraint to be added to active set. */ + ); + + /** Ensures linear independence of constraint matrix when a new constraint is added. + * To this end a bound or constraint is removed simultaneously if necessary. + * \return SUCCESSFUL_RETURN \n + RET_LI_RESOLVED \n + RET_ENSURELI_FAILED \n + RET_ENSURELI_FAILED_TQ \n + RET_ENSURELI_FAILED_NOINDEX \n + RET_REMOVE_FROM_ACTIVESET */ + virtual returnValue addConstraint_ensureLI( int_t number, /**< Number of constraint to be added to active set. */ + SubjectToStatus C_status /**< Status of new active bound. */ + ); + + /** Adds a bound to active set. + * \return SUCCESSFUL_RETURN \n + RET_ADDBOUND_FAILED \n + RET_ADDBOUND_FAILED_INFEASIBILITY \n + RET_ENSURELI_FAILED */ + virtual returnValue addBound( int_t number, /**< Number of bound to be added to active set. */ + SubjectToStatus B_status, /**< Status of new active bound. */ + BooleanType updateCholesky, /**< Flag indicating if Cholesky decomposition shall be updated. */ + BooleanType ensureLI = BT_TRUE /**< Ensure linear independence by exchange rules by default. */ + ); + + /** Checks if new active bound to be added is linearly dependent from + * from row of the active constraints matrix. + * \return RET_LINEARLY_DEPENDENT \n + RET_LINEARLY_INDEPENDENT */ + virtual returnValue addBound_checkLI( int_t number /**< Number of bound to be added to active set. */ + ); + + /** Ensures linear independence of constraint matrix when a new bound is added. + * To this end a bound or constraint is removed simultaneously if necessary. + * \return SUCCESSFUL_RETURN \n + RET_LI_RESOLVED \n + RET_ENSURELI_FAILED \n + RET_ENSURELI_FAILED_TQ \n + RET_ENSURELI_FAILED_NOINDEX \n + RET_REMOVE_FROM_ACTIVESET */ + virtual returnValue addBound_ensureLI( int_t number, /**< Number of bound to be added to active set. */ + SubjectToStatus B_status /**< Status of new active bound. */ + ); + + /** Removes a constraint from active set. + * \return SUCCESSFUL_RETURN \n + RET_CONSTRAINT_NOT_ACTIVE \n + RET_REMOVECONSTRAINT_FAILED \n + RET_HESSIAN_NOT_SPD */ + virtual returnValue removeConstraint( int_t number, /**< Number of constraint to be removed from active set. */ + BooleanType updateCholesky, /**< Flag indicating if Cholesky decomposition shall be updated. */ + BooleanType allowFlipping = BT_FALSE, /**< Flag indicating if flipping bounds are allowed. */ + BooleanType ensureNZC = BT_FALSE /**< Flag indicating if non-zero curvature is ensured by exchange rules. */ + ); + + /** Removes a bounds from active set. + * \return SUCCESSFUL_RETURN \n + RET_BOUND_NOT_ACTIVE \n + RET_HESSIAN_NOT_SPD \n + RET_REMOVEBOUND_FAILED */ + virtual returnValue removeBound( int_t number, /**< Number of bound to be removed from active set. */ + BooleanType updateCholesky, /**< Flag indicating if Cholesky decomposition shall be updated. */ + BooleanType allowFlipping = BT_FALSE, /**< Flag indicating if flipping bounds are allowed. */ + BooleanType ensureNZC = BT_FALSE /**< Flag indicating if non-zero curvature is ensured by exchange rules. */ + ); + + /** Solves the system Ta = b or T^Ta = b where T is a reverse upper triangular matrix. + * This must not be called for the Schur complement version. */ + virtual returnValue backsolveT( const real_t* const b, /**< Right hand side vector. */ + BooleanType transposed, /**< Indicates if the transposed system shall be solved. */ + real_t* const a /**< Output: Solution vector */ + ) const; + + /** Solves the system Ra = b or R^Ta = b where R is an upper triangular matrix. + * This must not be called for the Schur complement version. */ + virtual returnValue backsolveR( const real_t* const b, /**< Right hand side vector. */ + BooleanType transposed, /**< Indicates if the transposed system shall be solved. */ + real_t* const a /**< Output: Solution vector */ + ) const; + + /** Solves the system Ra = b or R^Ta = b where R is an upper triangular matrix. \n + * This must not be called for the Schur complement version. */ + virtual returnValue backsolveR( const real_t* const b, /**< Right hand side vector. */ + BooleanType transposed, /**< Indicates if the transposed system shall be solved. */ + BooleanType removingBound, /**< Indicates if function is called from "removeBound()". */ + real_t* const a /**< Output: Solution vector */ + ) const; + + + /** Determines step direction of the homotopy path. + * \return SUCCESSFUL_RETURN \n + RET_STEPDIRECTION_FAILED_TQ \n + RET_STEPDIRECTION_FAILED_CHOLESKY */ + virtual returnValue determineStepDirection( const real_t* const delta_g, /**< Step direction of gradient vector. */ + const real_t* const delta_lbA, /**< Step direction of lower constraints' bounds. */ + const real_t* const delta_ubA, /**< Step direction of upper constraints' bounds. */ + const real_t* const delta_lb, /**< Step direction of lower bounds. */ + const real_t* const delta_ub, /**< Step direction of upper bounds. */ + BooleanType Delta_bC_isZero, /**< Indicates if active constraints' bounds are to be shifted. */ + BooleanType Delta_bB_isZero, /**< Indicates if active bounds are to be shifted. */ + real_t* const delta_xFX, /**< Output: Primal homotopy step direction of fixed variables. */ + real_t* const delta_xFR, /**< Output: Primal homotopy step direction of free variables. */ + real_t* const delta_yAC, /**< Output: Dual homotopy step direction of active constraints' multiplier. */ + real_t* const delta_yFX /**< Output: Dual homotopy step direction of fixed variables' multiplier. */ + ); + + virtual returnValue determineStepDirection2( const real_t* const delta_g, /**< Step direction of gradient vector. */ + const real_t* const delta_lbA, /**< Step direction of lower constraints' bounds. */ + const real_t* const delta_ubA, /**< Step direction of upper constraints' bounds. */ + const real_t* const delta_lb, /**< Step direction of lower bounds. */ + const real_t* const delta_ub, /**< Step direction of upper bounds. */ + BooleanType Delta_bC_isZero, /**< Indicates if active constraints' bounds are to be shifted. */ + BooleanType Delta_bB_isZero, /**< Indicates if active bounds are to be shifted. */ + real_t* const delta_xFX, /**< Output: Primal homotopy step direction of fixed variables. */ + real_t* const delta_xFR, /**< Output: Primal homotopy step direction of free variables. */ + real_t* const delta_yAC, /**< Output: Dual homotopy step direction of active constraints' multiplier. */ + real_t* const delta_yFX /**< Output: Dual homotopy step direction of fixed variables' multiplier. */ + ); + + /* + * PRIVATE MEMBER FUNCTION + */ + private: + /** Checks if new active bound to be added is linearly dependent from + * from row of the active constraints matrix. This version computes + * the multipliers in the (full) test. + * \return RET_LINEARLY_DEPENDENT \n + RET_LINEARLY_INDEPENDENT */ + returnValue addBound_checkLISchur( int_t number, /**< Number of bound to be added to active set. */ + real_t* const xiC, /**< Output: Multipliers in linear independence test for active constraints. */ + real_t* const xiX /**< Output: Multipliers in linear independence test for fixed variables. */ + ); + + /** Checks if new active bound to be added is linearly dependent from + * from row of the active constraints matrix. This version computes + * the multipliers in the (full) test. + * \return RET_LINEARLY_DEPENDENT \n + RET_LINEARLY_INDEPENDENT */ + returnValue addConstraint_checkLISchur( int_t number, /**< Number of bound to be added to active set. */ + real_t* const xiC, /**< Output: Multipliers in linear independence test for active constraints. */ + real_t* const xiX /**< Output: Multipliers in linear independence test for fixed variables. */ + ); + + /** Compute product of "M" matrix (additional columns in KKT + matrix) with vector. y = alpha * M * x + beta * y */ + returnValue computeMTimes( real_t alpha, const real_t* const x, real_t beta, real_t* const y ); + + /** Compute product of transpose of "M" matrix (additional columns in KKT + matrix) with vector. y = alpha * M^T * x + beta * y */ + returnValue computeMTransTimes( real_t alpha, const real_t* const x, real_t beta, real_t* const y ); + + /** Add a row/column to the Schur complement. */ + returnValue addToSchurComplement( int_t number, SchurUpdateType update, int_t numNonzerosM, const sparse_int_t* M_pos, const real_t* const M_vals, int_t numNonzerosN, const sparse_int_t* Npos, const real_t* const Nvals, real_t N_diag ); + + /** Remove a row/column from the Schur complement. */ + returnValue deleteFromSchurComplement( int_t idx, BooleanType allowUndo = BT_FALSE ); + + /** Undo the last deletion from the Schur complement by moving the nS+1th row/column to position idx. */ + returnValue undoDeleteFromSchurComplement( int_t idx ); + + /** Compute determinant of new nS*nS Schur complement from old factorization */ + real_t calcDetSchur( int_t idxDel ); + + /** Update QR factorization and determinant of Schur complement after a row and column have been added or removed */ + returnValue updateSchurQR( int_t idxDel ); + + /** Compute the solution to QRx = rhs and store it in sol */ + returnValue backsolveSchurQR( int_t dimS, const real_t* const rhs, int_t dimRhs, real_t* const sol ); + + /** If negative curvature is discovered in the reduced Hessian, add bounds until all eigenvalues are positive */ + returnValue correctInertia(); + + /** If the KKT matrix is declared singular during refactorization, remove linearly dependent constraints or add bounds */ + returnValue repairSingularWorkingSet( ); + + returnValue stepCalcRhs( int_t nFR, int_t nFX, int_t nAC, int_t* FR_idx, int_t* FX_idx, int_t* AC_idx, real_t& rhs_max, const real_t* const delta_g, + const real_t* const delta_lbA, const real_t* const delta_ubA, + const real_t* const delta_lb, const real_t* const delta_ub, + BooleanType Delta_bC_isZero, BooleanType Delta_bB_isZero, + real_t* const delta_xFX, real_t* const delta_xFR, + real_t* const delta_yAC, real_t* const delta_yFX + ); + + returnValue stepCalcReorder(int_t nFR, int_t nAC, int_t* FR_idx, int_t* AC_idx, int_t nFRStart, int_t nACStart, + int_t* FR_idxStart, int_t* AC_idxStart, int_t* FR_iSort, int_t* FR_iSortStart, + int_t* AC_iSort, int_t* AC_iSortStart, real_t* rhs + ); + + returnValue stepCalcBacksolveSchur( int_t nFR, int_t nFX, int_t nAC, int_t* FR_idx, int_t* FX_idx, int_t* AC_idx, + int_t dim, real_t* rhs, real_t* sol + ); + + returnValue stepCalcReorder2( int_t nFR, int_t nAC, int_t* FR_idx, int_t* AC_idx, int_t nFRStart, int_t nACStart, + int_t* FR_idxStart, int_t* AC_idxStart, int_t* FR_iSort, int_t* FR_iSortStart, + int_t* AC_iSort, int_t* AC_iSortStart, real_t* sol, real_t* const delta_xFR, real_t* const delta_yAC + ); + + returnValue stepCalcResid( int_t nFR, int_t nFX, int_t nAC, int_t* FR_idx, int_t* FX_idx, int_t* AC_idx, + BooleanType Delta_bC_isZero, real_t* const delta_xFX, real_t* const delta_xFR, + real_t* const delta_yAC, const real_t* const delta_g, + const real_t* const delta_lbA, const real_t* const delta_ubA, real_t& rnrm + ); + + returnValue stepCalcDeltayFx( int_t nFR, int_t nFX, int_t nAC, int_t* FX_idx, const real_t* const delta_g, + real_t* const delta_xFX, real_t* const delta_xFR, real_t* const delta_yAC, real_t* const delta_yFX + ); + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + SparseSolver* sparseSolver; /**< Interface to the sparse linear solver. */ + + real_t* S; /**< Schur complement matrix. (This is actually the negative of the Schur complement!) */ + int_t nS; /**< Current size of Schur complement matrix. -1 means that the Schur complement has not yet been initialized. */ + int_t nSmax; /**< Maximum size of Schur complement matrix. */ + + real_t* Q_; /**< QR factorization of S: orthogonal matrix Q */ + real_t* R_; /**< QR factorization of S: upper triangular matrix R */ + real_t detS; /**< Determinant of Schur complement */ + real_t rcondS; /**< Reciprocal of condition number of S (estimate) */ + int_t numFactorizations; /**< Total number of factorizations performed */ + + int_t* schurUpdateIndex; /**< Indices of variables or constraints for each update in Schur complement. */ + SchurUpdateType* schurUpdate; /**< Type of update for each update in Schur complement. */ + + int_t M_physicallength; /**< Allocated size of the M_vals and M_ir arrays. */ + real_t* M_vals; /**< Values of the sparse M matrix containing the vectors with the additional rows defining the Schur complement (length). */ + sparse_int_t* M_ir; /**< Row indices (length). */ + sparse_int_t* M_jc; /**< Indices in M to first entry of columns (nS+1). */ + + Indexlist boundsFreeStart; /**< Index list for free bounds when major iteration started. */ + Indexlist constraintsActiveStart; /**< Index list for active constraints when major iteration started. */ +}; + + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_QPROBLEMSCHUR_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblemSchur.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblemSchur.ipp new file mode 100644 index 0000000..cda165a --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/SQProblemSchur.ipp @@ -0,0 +1,57 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2013 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/SQProblemSchur.ipp + * \author Andreas Waechter, Dennis Janka + * \version 3.2 + * \date 2012-2017 + * + * Implementation of inlined member functions of the SQProblemSchur class which + * is able to use the newly developed online active set strategy for + * parametric quadratic programming. + */ + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + +/* + * g e t N u m F a c t o r i z a t i o n s + */ +inline int_t SQProblemSchur::getNumFactorizations( ) const +{ + return numFactorizations; +} + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/SparseSolver.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/SparseSolver.hpp new file mode 100644 index 0000000..689f425 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/SparseSolver.hpp @@ -0,0 +1,573 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/SparseSolver.hpp + * \author Andreas Waechter, Dennis Janka + * \version 3.2 + * \date 2012-2017 + * + * Interfaces to sparse linear solvers that are used in a Schur-complement + * implementation in qpOASES. + */ + +#ifndef QPOASES_SPARSESOLVER_HPP +#define QPOASES_SPARSESOLVER_HPP +#include +#include + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Base class for linear solvers that are used in a Schur-complement + * implementation in qpOASES. + * + * \author Andreas Waechter, Dennis Janka + * \version 3.2 + * \date 2012-2017 + */ +class SparseSolver +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + SparseSolver( ); + + /** Copy constructor (deep copy). */ + SparseSolver( const SparseSolver& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~SparseSolver( ); + + /** Assignment operator (deep copy). */ + virtual SparseSolver& operator=( const SparseSolver& rhs /**< Rhs object. */ + ); + + /** Set new matrix data. The matrix is to be provided + in the Harwell-Boeing format. Only the lower + triangular part should be set. */ + virtual returnValue setMatrixData( int_t dim, /**< Dimension of the linear system. */ + int_t numNonzeros, /**< Number of nonzeros in the matrix. */ + const int_t* const airn, /**< Row indices for each matrix entry. */ + const int_t* const acjn, /**< Column indices for each matrix entry. */ + const real_t* const avals /**< Values for each matrix entry. */ + ) = 0; + + /** Compute factorization of current matrix. This method must be called before solve.*/ + virtual returnValue factorize( ) = 0; + + /** Solve linear system with most recently set matrix data. */ + virtual returnValue solve( int_t dim, /**< Dimension of the linear system. */ + const real_t* const rhs, /**< Values for the right hand side. */ + real_t* const sol /**< Solution of the linear system. */ + ) = 0; + + /** Clears all data structures. */ + virtual returnValue reset( ); + + /** Return the number of negative eigenvalues. */ + virtual int_t getNegativeEigenvalues( ); + + /** Return the rank after a factorization */ + virtual int_t getRank( ); + + /** Returns the zero pivots in case the matrix is rank deficient */ + virtual returnValue getZeroPivots( int_t *&zeroPivots ); + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const SparseSolver& rhs /**< Rhs object. */ + ); + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: +}; + + +#ifdef SOLVER_MA27 + +/** + * \brief Implementation of the linear solver interface using Harwell's MA27. + * + * \author Andreas Waechter, Dennis Janka + * \version 3.2 + * \date 2012-2017 + */ +class Ma27SparseSolver: public SparseSolver +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + Ma27SparseSolver( ); + + /** Copy constructor (deep copy). */ + Ma27SparseSolver( const Ma27SparseSolver& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~Ma27SparseSolver( ); + + /** Assignment operator (deep copy). */ + virtual Ma27SparseSolver& operator=( const SparseSolver& rhs /**< Rhs object. */ + ); + + /** Set new matrix data. The matrix is to be provided + in the Harwell-Boeing format. Only the lower + triangular part should be set. */ + virtual returnValue setMatrixData( int_t dim, /**< Dimension of the linear system. */ + int_t numNonzeros, /**< Number of nonzeros in the matrix. */ + const int_t* const airn, /**< Row indices for each matrix entry. */ + const int_t* const acjn, /**< Column indices for each matrix entry. */ + const real_t* const avals /**< Values for each matrix entry. */ + ); + + /** Compute factorization of current matrix. This method must be called before solve.*/ + virtual returnValue factorize( ); + + /** Solve linear system with most recently set matrix data. */ + virtual returnValue solve( int_t dim, /**< Dimension of the linear system. */ + const real_t* const rhs, /**< Values for the right hand side. */ + real_t* const sol /**< Solution of the linear system. */ + ); + + /** Clears all data structures. */ + virtual returnValue reset( ); + + /** Return the number of negative eigenvalues. */ + virtual int_t getNegativeEigenvalues( ); + + /** Return the rank after a factorization */ + virtual int getRank( ); + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const Ma27SparseSolver& rhs /**< Rhs object. */ + ); + + /* + * PRIVATE MEMBER FUNCTIONS + */ + private: + /* + * PRIVATE MEMBER VARIABLES + */ + private: + fint_t dim; /**< Dimension of the current linear system. */ + + fint_t numNonzeros; /**< Number of nonzeros in the current linear system. */ + + fint_t la_ma27; /**< size of a_ma27 (LA in MA27) */ + + double* a_ma27; /**< matrix/factor for MA27 (A in MA27). If have_factorization is false, it contains the matrix entries (and has length numNonzeros), otherwise the factor (and has length la_ma27). */ + + fint_t* irn_ma27; /**< Row entries of matrix (IRN in MA27) */ + + fint_t* jcn_ma27; /**< Column entries of matrix (JCN in MA27) */ + + fint_t icntl_ma27[30]; /**< integer control values (ICNRL in MA27) */ + + double cntl_ma27[5]; /**< real control values (CNRL in MA27) */ + + fint_t liw_ma27; /**< length of integer work space (LIW in MA27) */ + + fint_t* iw_ma27; /**< integer work space (IW in MA27) */ + + fint_t* ikeep_ma27; /**< IKEEP in MA27 */ + + fint_t nsteps_ma27; /**< NSTEPS in MA27 */ + + fint_t maxfrt_ma27; /**< MAXFRT in MA27 */ + + bool have_factorization; /**< flag indicating whether factorization for current matrix has already been computed */ + + fint_t neig; /**< number of negative eigenvalues */ + + fint_t rank; /**< rank of matrix */ +}; + +#endif /* SOLVER_MA27 */ + + +#ifdef SOLVER_MA57 + +/** + * \brief Implementation of the linear solver interface using Harwell's MA57. + * + * \author Andreas Waechter, Dennis Janka + * \version 3.2 + * \date 2013-2017 + */ +class Ma57SparseSolver: public SparseSolver +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + Ma57SparseSolver( ); + + /** Copy constructor (deep copy). */ + Ma57SparseSolver( const Ma57SparseSolver& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~Ma57SparseSolver( ); + + /** Assignment operator (deep copy). */ + virtual Ma57SparseSolver& operator=( const SparseSolver& rhs /**< Rhs object. */ + ); + + /** Set new matrix data. The matrix is to be provided + in the Harwell-Boeing format. Only the lower + triangular part should be set. */ + virtual returnValue setMatrixData( int_t dim, /**< Dimension of the linear system. */ + int_t numNonzeros, /**< Number of nonzeros in the matrix. */ + const int_t* const airn, /**< Row indices for each matrix entry. */ + const int_t* const acjn, /**< Column indices for each matrix entry. */ + const real_t* const avals /**< Values for each matrix entry. */ + ); + + /** Compute factorization of current matrix. This method must be called before solve.*/ + virtual returnValue factorize( ); + + /** Solve linear system with most recently set matrix data. */ + virtual returnValue solve( int_t dim, /**< Dimension of the linear system. */ + const real_t* const rhs, /**< Values for the right hand side. */ + real_t* const sol /**< Solution of the linear system. */ + ); + + /** Clears all data structures. */ + virtual returnValue reset( ); + + /** Return the number of negative eigenvalues. */ + virtual int_t getNegativeEigenvalues( ); + + /** Return the rank after a factorization */ + virtual int_t getRank( ); + + /** Returns the zero pivots in case the matrix is rank deficient */ + virtual returnValue getZeroPivots( int_t* &zeroPivots /**< ... */ + ); + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const Ma57SparseSolver& rhs /**< Rhs object. */ + ); + + /* + * PRIVATE MEMBER FUNCTIONS + */ + private: + /* + * PRIVATE MEMBER VARIABLES + */ + private: + fint_t dim; /**< Dimension of the current linear system. */ + + fint_t numNonzeros; /**< Number of nonzeros in the current linear system. */ + + double* a_ma57; /**< matrix for MA57 (A in MA57) */ + + fint_t* irn_ma57; /**< Row entries of matrix (IRN in MA57) */ + + fint_t* jcn_ma57; /**< Column entries of matrix (JCN in MA57) */ + + fint_t icntl_ma57[30]; /**< integer control values (ICNRL in MA57) */ + + double cntl_ma57[5]; /**< real control values (CNRL in MA57) */ + + double* fact_ma57; /**< array for storing the factors */ + + fint_t lfact_ma57; /**< length of fact_ma57 */ + + fint_t* ifact_ma57; /**< indexing information about the factors */ + + fint_t lifact_ma57; /**< length of ifact_ma57 */ + + bool have_factorization;/**< flag indicating whether factorization for current matrix has already been computed */ + + fint_t neig; /**< number of negative eigenvalues */ + + fint_t rank; /**< rank of matrix */ + + fint_t* pivots; /**< sequence of pivots used in factorization */ +}; + +#endif /* SOLVER_MA57 */ + + +#ifdef SOLVER_MUMPS + +/** + * \brief Implementation of the linear solver interface using MUMPS. + * + * \author Andrea Zanelli + * \version 3.2 + * \date 2022 + */ +class MumpsSparseSolver: public SparseSolver +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + MumpsSparseSolver( ); + + /** Copy constructor (deep copy). */ + MumpsSparseSolver( const MumpsSparseSolver& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~MumpsSparseSolver( ); + + /** Assignment operator (deep copy). */ + virtual MumpsSparseSolver& operator=( const SparseSolver& rhs /**< Rhs object. */ + ); + + /** Set new matrix data. The matrix is to be provided + in the Harwell-Boeing format. Only the lower + triangular part should be set. */ + virtual returnValue setMatrixData( int_t dim, /**< Dimension of the linear system. */ + int_t numNonzeros, /**< Number of nonzeros in the matrix. */ + const int_t* const airn, /**< Row indices for each matrix entry. */ + const int_t* const acjn, /**< Column indices for each matrix entry. */ + const real_t* const avals /**< Values for each matrix entry. */ + ); + + /** Compute factorization of current matrix. This method must be called before solve.*/ + virtual returnValue factorize( ); + + /** Solve linear system with most recently set matrix data. */ + virtual returnValue solve( int_t dim, /**< Dimension of the linear system. */ + const real_t* const rhs, /**< Values for the right hand side. */ + real_t* const sol /**< Solution of the linear system. */ + ); + + /** Clears all data structures. */ + virtual returnValue reset( ); + + /** Return the number of negative eigenvalues. */ + virtual int_t getNegativeEigenvalues( ); + + /** Return the rank after a factorization */ + virtual int_t getRank( ); + + /** Returns the zero pivots in case the matrix is rank deficient */ + virtual returnValue getZeroPivots( int_t* &zeroPivots /**< ... */ + ); + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const MumpsSparseSolver& rhs /**< Rhs object. */ + ); + + /* + * PRIVATE MEMBER FUNCTIONS + */ + private: + /* + * PRIVATE MEMBER VARIABLES + */ + private: + + + void* mumps_ptr_; /** Primary MUMPS data structure */ + + int dim; /**< Dimension of the current linear system. */ + + int numNonzeros; /**< Number of nonzeros in the current linear system. */ + + double* a_mumps; /**< matrix for MUMPS (A in MUMPS) */ + + int* irn_mumps; /**< Row entries of matrix (IRN in MUMPS) */ + + int* jcn_mumps; /**< Column entries of matrix (JCN in MUMPS) */ + + bool have_factorization; /**< flag indicating whether factorization for current matrix has already been computed */ + + int negevals_; /**< number of negative eigenvalues */ + + int mumps_pivot_order_; /* pivot order*/ + + bool initialized_; + /** Flag indicating if the matrix has to be refactorized because + * the pivot tolerance has been changed. + */ + bool pivtol_changed_; + /** Flag that is true if we just requested the values of the + * matrix again (SYMSOLVER_CALL_AGAIN) and have to factorize + * again. + */ + bool refactorize_; + ///@} + + /** @name Solver specific data/options */ + ///@{ + /** Pivot tolerance */ + double pivtol_; + + /** Maximal pivot tolerance */ + double pivtolmax_; + + /** Percent increase in memory */ + int mem_percent_; + + /** Permutation and scaling method in MUMPS */ + int mumps_permuting_scaling_; + + /** Scaling in MUMPS */ + int mumps_scaling_; + + /** Threshold in MUMPS to state that a constraint is linearly dependent */ + double mumps_dep_tol_; + + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. + */ + bool warm_start_same_structure_; + ///@} + + /** Flag indicating if symbolic factorization has already been called */ + bool have_symbolic_factorization_; +}; + +template +inline void ComputeMemIncrease( + T& len, ///< current length on input, new length on output + double recommended, ///< recommended size + T min, ///< minimal size that should ensured + const char* context ///< context from where this function is called - used to setup message for exception +) +{ + if( recommended >= std::numeric_limits::max() ) + { + // increase len to the maximum possible, if that is still an increase + if( len < std::numeric_limits::max() ) + { + len = std::numeric_limits::max(); + } + else + { + std::stringstream what; + what << "Cannot allocate more than " << std::numeric_limits::max()*sizeof(T) << " bytes for " << context << " due to limitation on integer type"; + throw std::overflow_error(what.str()); + } + } + else + { + len = std::max(min, (T) recommended); + } +} + +#endif /* SOLVER_MUMPS */ + + + +#ifdef SOLVER_NONE + +/** + * \brief Implementation of a dummy sparse solver. An error is thrown if a factorization is attempted. + * + * \author Dennis Janka + * \version 3.2 + * \date 2015-2017 + */ +class DummySparseSolver: public SparseSolver +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Set new matrix data. The matrix is to be provided + in the Harwell-Boeing format. Only the lower + triangular part should be set. */ + virtual returnValue setMatrixData( int_t dim, /**< Dimension of the linear system. */ + int_t numNonzeros, /**< Number of nonzeros in the matrix. */ + const int_t* const airn, /**< Row indices for each matrix entry. */ + const int_t* const acjn, /**< Column indices for each matrix entry. */ + const real_t* const avals /**< Values for each matrix entry. */ + ); + + /** Compute factorization of current matrix. This method must be called before solve.*/ + virtual returnValue factorize( ); + + /** Solve linear system with most recently set matrix data. */ + virtual returnValue solve( int_t dim, /**< Dimension of the linear system. */ + const real_t* const rhs, /**< Values for the right hand side. */ + real_t* const sol /**< Solution of the linear system. */ + ); +}; + +#endif /* SOLVER_NONE */ + + +END_NAMESPACE_QPOASES + +#endif /* QPOASES_SPARSESOLVER_HPP */ + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/SubjectTo.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/SubjectTo.hpp new file mode 100644 index 0000000..062aa11 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/SubjectTo.hpp @@ -0,0 +1,229 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/SubjectTo.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of the SubjectTo class designed to manage working sets of + * constraints and bounds within a QProblem. + */ + + +#ifndef QPOASES_SUBJECTTO_HPP +#define QPOASES_SUBJECTTO_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Base class for managing working sets of bounds and constraints. + * + * This class manages working sets of bounds and constraints by storing + * index sets and other status information. + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + */ +class SubjectTo +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + SubjectTo( ); + + /** Constructor which takes the number of constraints or bounds. */ + SubjectTo( int_t _n /**< Number of constraints or bounds. */ + ); + + /** Copy constructor (deep copy). */ + SubjectTo( const SubjectTo& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + virtual ~SubjectTo( ); + + /** Assignment operator (deep copy). */ + SubjectTo& operator=( const SubjectTo& rhs /**< Rhs object. */ + ); + + + /** Initialises object with given number of constraints or bounds. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS */ + returnValue init( int_t _n = 0 /**< Number of constraints or bounds. */ + ); + + + /** Returns number of constraints/bounds with given SubjectTo type. + * \return Number of constraints/bounds with given type. */ + inline int_t getNumberOfType( SubjectToType _type /**< Type of (constraints') bound. */ + ) const; + + + /** Returns type of (constraints') bound. + * \return Type of (constraints') bound \n + RET_INDEX_OUT_OF_BOUNDS */ + inline SubjectToType getType( int_t i /**< Number of (constraints') bound. */ + ) const; + + /** Returns status of (constraints') bound. + * \return Status of (constraints') bound \n + ST_UNDEFINED */ + inline SubjectToStatus getStatus( int_t i /**< Number of (constraints') bound. */ + ) const; + + + /** Sets type of (constraints') bound. + * \return SUCCESSFUL_RETURN \n + RET_INDEX_OUT_OF_BOUNDS */ + inline returnValue setType( int_t i, /**< Number of (constraints') bound. */ + SubjectToType value /**< Type of (constraints') bound. */ + ); + + /** Sets status of (constraints') bound. + * \return SUCCESSFUL_RETURN \n + RET_INDEX_OUT_OF_BOUNDS */ + inline returnValue setStatus( int_t i, /**< Number of (constraints') bound. */ + SubjectToStatus value /**< Status of (constraints') bound. */ + ); + + + /** Sets status of lower (constraints') bounds. */ + inline void setNoLower( BooleanType _status /**< Status of lower (constraints') bounds. */ + ); + + /** Sets status of upper (constraints') bounds. */ + inline void setNoUpper( BooleanType _status /**< Status of upper (constraints') bounds. */ + ); + + + /** Returns status of lower (constraints') bounds. + * \return BT_TRUE if there is no lower (constraints') bound on any variable. */ + inline BooleanType hasNoLower( ) const; + + /** Returns status of upper bounds. + * \return BT_TRUE if there is no upper (constraints') bound on any variable. */ + inline BooleanType hasNoUpper( ) const; + + + /** Shifts forward type and status of all constraints/bounds by a given + * offset. This offset has to lie within the range [0,n/2] and has to + * be an integer divisor of the total number of constraints/bounds n. + * Type and status of the first \ constraints/bounds is thrown away, + * type and status of the last \ constraints/bounds is doubled, + * e.g. for offset = 2: \n + * shift( {c/b1,c/b2,c/b3,c/b4,c/b5,c/b6} ) = {c/b3,c/b4,c/b5,c/b6,c/b5,c/b6} + * \return SUCCESSFUL_RETURN \n + RET_INDEX_OUT_OF_BOUNDS \n + RET_INVALID_ARGUMENTS \n + RET_SHIFTING_FAILED */ + virtual returnValue shift( int_t offset /**< Shift offset within the range [0,n/2] and integer divisor of n. */ + ) = 0; + + /** Rotates forward type and status of all constraints/bounds by a given + * offset. This offset has to lie within the range [0,n]. + * Example for offset = 2: \n + * rotate( {c/b1,c/b2,c/b3,c/b4,c/b5,c/b6} ) = {c/b3,c/b4,c/b5,c/b6,c/b1,c/b2} + * \return SUCCESSFUL_RETURN \n + RET_INDEX_OUT_OF_BOUNDS \n + RET_ROTATING_FAILED */ + virtual returnValue rotate( int_t offset /**< Rotation offset within the range [0,n]. */ + ) = 0; + + + /* + * PROTECTED MEMBER FUNCTIONS + */ + protected: + /** Frees all allocated memory. + * \return SUCCESSFUL_RETURN */ + returnValue clear( ); + + /** Copies all members from given rhs object. + * \return SUCCESSFUL_RETURN */ + returnValue copy( const SubjectTo& rhs /**< Rhs object. */ + ); + + + /** Adds the index of a new constraint or bound to index set. + * \return SUCCESSFUL_RETURN \n + RET_ADDINDEX_FAILED \n + RET_INVALID_ARGUMENTS */ + returnValue addIndex( Indexlist* const indexlist, /**< Index list to which the new index shall be added. */ + int_t newnumber, /**< Number of new constraint or bound. */ + SubjectToStatus newstatus /**< Status of new constraint or bound. */ + ); + + /** Removes the index of a constraint or bound from index set. + * \return SUCCESSFUL_RETURN \n + RET_REMOVEINDEX_FAILED \n + RET_INVALID_ARGUMENTS */ + returnValue removeIndex( Indexlist* const indexlist, /**< Index list from which the new index shall be removed. */ + int_t removenumber /**< Number of constraint or bound to be removed. */ + ); + + /** Swaps the indices of two constraints or bounds within the index set. + * \return SUCCESSFUL_RETURN \n + RET_SWAPINDEX_FAILED \n + RET_INVALID_ARGUMENTS */ + returnValue swapIndex( Indexlist* const indexlist, /**< Index list in which the indices shold be swapped. */ + int_t number1, /**< Number of first constraint or bound. */ + int_t number2 /**< Number of second constraint or bound. */ + ); + + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + int_t n; /**< Total number of constraints/bounds. */ + + SubjectToType* type; /**< Type of constraints/bounds. */ + SubjectToStatus* status; /**< Status of constraints/bounds. */ + + BooleanType noLower; /**< This flag indicates if there is no lower bound on any variable. */ + BooleanType noUpper; /**< This flag indicates if there is no upper bound on any variable. */ +}; + + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_SUBJECTTO_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/SubjectTo.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/SubjectTo.ipp new file mode 100644 index 0000000..b409b38 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/SubjectTo.ipp @@ -0,0 +1,158 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/SubjectTo.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the inlined member functions of the SubjectTo class + * designed to manage working sets of constraints and bounds within a QProblem. + */ + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * g e t N u m b e r O f T y p e + */ +inline int_t SubjectTo::getNumberOfType( SubjectToType _type ) const +{ + int_t i; + int_t numberOfType = 0; + + if ( type != 0 ) + { + for( i=0; i= 0 ) && ( i < n ) ) + return type[i]; + + return ST_UNKNOWN; +} + + +/* + * g e t S t a t u s + */ +inline SubjectToStatus SubjectTo::getStatus( int_t i ) const +{ + if ( ( i >= 0 ) && ( i < n ) ) + return status[i]; + + return ST_UNDEFINED; +} + + +/* + * s e t T y p e + */ +inline returnValue SubjectTo::setType( int_t i, SubjectToType value ) +{ + if ( ( i >= 0 ) && ( i < n ) ) + { + type[i] = value; + return SUCCESSFUL_RETURN; + } + else + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); +} + + +/* + * s e t S t a t u s + */ +inline returnValue SubjectTo::setStatus( int_t i, SubjectToStatus value ) +{ + if ( ( i >= 0 ) && ( i < n ) ) + { + status[i] = value; + return SUCCESSFUL_RETURN; + } + else + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); +} + + +/* + * s e t N o L o w e r + */ +inline void SubjectTo::setNoLower( BooleanType _status ) +{ + noLower = _status; +} + + +/* + * s e t N o U p p e r + */ +inline void SubjectTo::setNoUpper( BooleanType _status ) +{ + noUpper = _status; +} + + +/* + * h a s N o L o w e r + */ +inline BooleanType SubjectTo::hasNoLower( ) const +{ + return noLower; +} + + +/* + * h a s N o U p p p e r + */ +inline BooleanType SubjectTo::hasNoUpper( ) const +{ + return noUpper; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Types.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Types.hpp new file mode 100644 index 0000000..9d52cee --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Types.hpp @@ -0,0 +1,348 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Types.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of all non-built-in types (except for classes). + */ + + +#ifndef QPOASES_TYPES_HPP +#define QPOASES_TYPES_HPP + + +/* If your compiler does not support the snprintf() function, + * uncomment the following line and try to compile again. */ +/* #define __NO_SNPRINTF__ */ + + +/* Uncomment the following line for setting the __DSPACE__ flag. */ +/* #define __DSPACE__ */ + +/* Uncomment the following line for setting the __XPCTARGET__ flag. */ +/* #define __XPCTARGET__ */ + + +/* Uncomment the following line for setting the __NO_FMATH__ flag. */ +/* #define __NO_FMATH__ */ + +/* Uncomment the following line to enable debug information. */ +/* #define __DEBUG__ */ + +/* Uncomment the following line to enable suppress any kind of console output. */ +/* #define __SUPPRESSANYOUTPUT__ */ + + +/** Forces to always include all implicitly fixed bounds and all equality constraints + * into the initial working set when setting up an auxiliary QP. */ +#define __ALWAYS_INITIALISE_WITH_ALL_EQUALITIES__ + + +/* Uncomment the following line to activate the use of an alternative Givens + * plane rotation requiring only three multiplications. */ +/* #define __USE_THREE_MULTS_GIVENS__ */ + +/* Uncomment the following line to activate the use of single precision arithmetic. */ +/* #define __USE_SINGLE_PRECISION__ */ + + + +/* Work-around for Borland BCC 5.5 compiler. */ +#ifdef __BORLANDC__ +#if __BORLANDC__ < 0x0561 + #define __STDC__ 1 +#endif +#endif + + +/* Work-around for Microsoft compilers. */ +#ifdef _MSC_VER + #define __NO_SNPRINTF__ + #pragma warning( disable : 4061 4100 4250 4514 4996 ) +#endif + + +#ifdef __DSPACE__ + + /** Macro for switching on/off the beginning of the qpOASES namespace definition. */ + #define BEGIN_NAMESPACE_QPOASES + + /** Macro for switching on/off the end of the qpOASES namespace definition. */ + #define END_NAMESPACE_QPOASES + + /** Macro for switching on/off the use of the qpOASES namespace. */ + #define USING_NAMESPACE_QPOASES + + /** Macro for switching on/off references to the qpOASES namespace. */ + #define REFER_NAMESPACE_QPOASES :: + +#else + + /** Macro for switching on/off the beginning of the qpOASES namespace definition. */ + #define BEGIN_NAMESPACE_QPOASES namespace qpOASES { + + /** Macro for switching on/off the end of the qpOASES namespace definition. */ + #define END_NAMESPACE_QPOASES } + + /** Macro for switching on/off the use of the qpOASES namespace. */ + #define USING_NAMESPACE_QPOASES using namespace qpOASES; + + /** Macro for switching on/off references to the qpOASES namespace. */ + #define REFER_NAMESPACE_QPOASES qpOASES:: + +#endif + + +/* Avoid any printing on embedded platforms. */ +#if defined(__DSPACE__) || defined(__XPCTARGET__) + #define __SUPPRESSANYOUTPUT__ + #define __NO_SNPRINTF__ +#endif + + +#ifdef __NO_SNPRINTF__ + #if (!defined(_MSC_VER)) || defined(__DSPACE__) || defined(__XPCTARGET__) + /* If snprintf is not available, provide an empty implementation... */ + int snprintf( char* s, size_t n, const char* format, ... ); + #else + /* ... or substitute snprintf by _snprintf for Microsoft compilers. */ + #define snprintf _snprintf + #endif +#endif /* __NO_SNPRINTF__ */ + + + +/** Macro for accessing the Cholesky factor R. */ +#define RR( I,J ) R[(I)+nV*(J)] + +/** Macro for accessing the orthonormal matrix Q of the QT factorisation. */ +#define QQ( I,J ) Q[(I)+nV*(J)] + +/** Macro for accessing the triangular matrix T of the QT factorisation. */ +#define TT( I,J ) T[(I)*sizeT+(J)] + + +/* If neither MA57 nor MA27 nor MUMPS are selected, activate the dummy solver */ +#if !defined(SOLVER_MA27) && !defined(SOLVER_MA57) && !defined(SOLVER_MUMPS) && !defined(SOLVER_NONE) +#define SOLVER_NONE +#endif + + +/** + * Defined integer type for calling BLAS/LAPACK. Should usually be + * "(unsigned) int", currently set to "(unsigned) long" for backwards + * compatibility. This will change in a future release. + */ +typedef long la_int_t; +typedef unsigned long la_uint_t; + + +BEGIN_NAMESPACE_QPOASES + +/** Defines real_t for facilitating switching between double and float. */ +#ifdef __USE_SINGLE_PRECISION__ +typedef float real_t; +#else +typedef double real_t; +#endif /* __USE_SINGLE_PRECISION__ */ + + +/** Defines int_t for facilitating switching between int and long int. */ +#ifdef __USE_LONG_INTEGERS__ +typedef long int_t; +typedef unsigned long uint_t; +#else +typedef int int_t; +typedef unsigned int uint_t; +#endif /* __USE_LONG_INTEGERS__ */ + + +/** Defines FORTRAN integer type. Might be platform dependent! */ +#ifdef __USE_LONG_FINTS__ +typedef long fint_t; +#else +typedef int fint_t; +#endif /* __USE_LONG_FINTS__ */ + + +/** + * Integer type for sparse matrix row/column entries. Make this "int" + * for 32 bit entries, and "long" for 64-bit entries on x86_64 platform. + * + * Most sparse codes still assume 32-bit entries here (HSL, BQPD, ...) + */ +typedef int_t sparse_int_t; + + +/** Summarises all possible logical values. */ +enum BooleanType +{ + BT_FALSE, /**< Logical value for "false". */ + BT_TRUE /**< Logical value for "true". */ +}; + + +/** Summarises all possible print levels. Print levels are used to describe + * the desired amount of output during runtime of qpOASES. */ +enum PrintLevel +{ + PL_DEBUG_ITER = -2, /**< Full tabular debugging output. */ + PL_TABULAR, /**< Normal tabular output. */ + PL_NONE, /**< No output. */ + PL_LOW, /**< Print error messages only. */ + PL_MEDIUM, /**< Print error and warning messages as well as concise info messages. */ + PL_HIGH /**< Print all messages with full details. */ +}; + + +/** Defines visibility status of a message. */ +enum VisibilityStatus +{ + VS_HIDDEN, /**< Message not visible. */ + VS_VISIBLE /**< Message visible. */ +}; + + +/** Summarises all possible states of the (S)QProblem(B) object during the +solution process of a QP sequence. */ +enum QProblemStatus +{ + QPS_NOTINITIALISED, /**< QProblem object is freshly instantiated or reset. */ + QPS_PREPARINGAUXILIARYQP, /**< An auxiliary problem is currently setup, either at the very beginning + * via an initial homotopy or after changing the QP matrices. */ + QPS_AUXILIARYQPSOLVED, /**< An auxilary problem was solved, either at the very beginning + * via an initial homotopy or after changing the QP matrices. */ + QPS_PERFORMINGHOMOTOPY, /**< A homotopy according to the main idea of the online active + * set strategy is performed. */ + QPS_HOMOTOPYQPSOLVED, /**< An intermediate QP along the homotopy path was solved. */ + QPS_SOLVED /**< The solution of the actual QP was found. */ +}; + + +/** Summarises all possible types of the QP's Hessian matrix. */ +enum HessianType +{ + HST_ZERO, /**< Hessian is zero matrix (i.e. LP formulation). */ + HST_IDENTITY, /**< Hessian is identity matrix. */ + HST_POSDEF, /**< Hessian is (strictly) positive definite. */ + HST_POSDEF_NULLSPACE, /**< Hessian is positive definite on null space of active bounds/constraints. */ + HST_SEMIDEF, /**< Hessian is positive semi-definite. */ + HST_INDEF, /**< Hessian is indefinite. */ + HST_UNKNOWN /**< Hessian type is unknown. */ +}; + + +/** Summarises all possible types of bounds and constraints. */ +enum SubjectToType +{ + ST_UNBOUNDED, /**< Bound/constraint is unbounded. */ + ST_BOUNDED, /**< Bound/constraint is bounded but not fixed. */ + ST_EQUALITY, /**< Bound/constraint is fixed (implicit equality bound/constraint). */ + ST_DISABLED, /**< Bound/constraint is disabled (i.e. ignored when solving QP). */ + ST_UNKNOWN /**< Type of bound/constraint unknown. */ +}; + + +/** Summarises all possible states of bounds and constraints. */ +enum SubjectToStatus +{ + ST_LOWER = -1, /**< Bound/constraint is at its lower bound. */ + ST_INACTIVE, /**< Bound/constraint is inactive. */ + ST_UPPER, /**< Bound/constraint is at its upper bound. */ + ST_INFEASIBLE_LOWER, /**< (to be documented) */ + ST_INFEASIBLE_UPPER, /**< (to be documented) */ + ST_UNDEFINED /**< Status of bound/constraint undefined. */ +}; + +/** Flag indicating which type of update generated column in Schur complement. */ +enum SchurUpdateType +{ + SUT_VarFixed, /**< Free variable gets fixed. */ + SUT_VarFreed, /**< Fixed variable gets freed. */ + SUT_ConAdded, /**< Constraint becomes active. */ + SUT_ConRemoved, /**< Constraint becomes inactive. */ + SUT_UNDEFINED /**< Type of Schur update is undefined. */ +}; + +/** + * \brief Stores internal information for tabular (debugging) output. + * + * Struct storing internal information for tabular (debugging) output + * when using the (S)QProblem(B) objects. + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2013-2017 + */ +struct TabularOutput { + int_t idxAddB; /**< Index of bound that has been added to working set. */ + int_t idxRemB; /**< Index of bound that has been removed from working set. */ + int_t idxAddC; /**< Index of constraint that has been added to working set. */ + int_t idxRemC; /**< Index of constraint that has been removed from working set. */ + int_t excAddB; /**< Flag indicating whether a bound has been added to working set to keep a regular projected Hessian. */ + int_t excRemB; /**< Flag indicating whether a bound has been removed from working set to keep a regular projected Hessian. */ + int_t excAddC; /**< Flag indicating whether a constraint has been added to working set to keep a regular projected Hessian. */ + int_t excRemC; /**< Flag indicating whether a constraint has been removed from working set to keep a regular projected Hessian. */ +}; + + + +/** + * \brief Struct containing the variable header for mat file. + * + * Struct storing the header of a variable to be stored in + * Matlab's binary format (using the outdated Level 4 variant + * for simplictiy). + * + * Note, this code snippet has been inspired from the document + * "Matlab(R) MAT-file Format, R2013b" by MathWorks + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2013-2017 + */ +typedef struct { + long numericFormat; /**< Flag indicating numerical format. */ + long nRows; /**< Number of rows. */ + long nCols; /**< Number of rows. */ + long imaginaryPart; /**< (to be documented) */ + long nCharName; /**< Number of character in name. */ +} MatMatrixHeader; + + + + +END_NAMESPACE_QPOASES + + +#endif /* QPOASES_TYPES_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/UnitTesting.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/UnitTesting.hpp new file mode 100644 index 0000000..c6c9674 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/UnitTesting.hpp @@ -0,0 +1,79 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/UnitTesting.hpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Definition of auxiliary functions/macros for unit testing. + */ + + +#ifndef QPOASES_UNIT_TESTING_HPP +#define QPOASES_UNIT_TESTING_HPP + + +#ifndef TEST_TOL_FACTOR +#define TEST_TOL_FACTOR 1 +#endif + + +/** Return value for tests that passed. */ +#define TEST_PASSED 0 + +/** Return value for tests that failed. */ +#define TEST_FAILED 1 + +/** Return value for tests that could not run due to missing external data. */ +#define TEST_DATA_NOT_FOUND 99 + + +/** Macro verifying that two numerical values are equal in order to pass unit test. */ +#define QPOASES_TEST_FOR_EQUAL( x,y ) if ( REFER_NAMESPACE_QPOASES isEqual( (x),(y) ) == BT_FALSE ) { return TEST_FAILED; } + +/** Macro verifying that two numerical values are close to each other in order to pass unit test. */ +#define QPOASES_TEST_FOR_NEAR( x,y ) if ( REFER_NAMESPACE_QPOASES getAbs((x)-(y)) / REFER_NAMESPACE_QPOASES getMax( 1.0,REFER_NAMESPACE_QPOASES getAbs(x) ) >= 1e-10 ) { return TEST_FAILED; } + +/** Macro verifying that first quantity is lower or equal than second one in order to pass unit test. */ +#define QPOASES_TEST_FOR_TOL( x,tol ) if ( (x) > (tol)*(TEST_TOL_FACTOR) ) { return TEST_FAILED; } + +/** Macro verifying that a logical expression holds in order to pass unit test. */ +#define QPOASES_TEST_FOR_TRUE( x ) if ( (x) == false ) { return TEST_FAILED; } + + + +BEGIN_NAMESPACE_QPOASES + + +END_NAMESPACE_QPOASES + + +#endif /* QPOASES_UNIT_TESTING_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Utils.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/Utils.hpp new file mode 100644 index 0000000..160fd5f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Utils.hpp @@ -0,0 +1,366 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/Utils.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of some utility functions for working with qpOASES. + */ + + +#ifndef QPOASES_UTILS_HPP +#define QPOASES_UTILS_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** Prints a (possibly named) vector. + * \return SUCCESSFUL_RETURN */ +returnValue print( const real_t* const v, /**< Vector to be printed. */ + int_t n, /**< Length of vector. */ + const char* name = 0 /**< Name of vector. */ + ); + +/** Prints a (possibly named) permuted vector. + * \return SUCCESSFUL_RETURN */ +returnValue print( const real_t* const v, /**< Vector to be printed. */ + int_t n, /**< Length of vector. */ + const int_t* const V_idx, /**< Pemutation vector. */ + const char* name = 0 /**< Name of vector. */ + ); + +/** Prints a (possibly named) matrix. + * \return SUCCESSFUL_RETURN */ +returnValue print( const real_t* const M, /**< Matrix to be printed. */ + int_t nrow, /**< Row number of matrix. */ + int_t ncol, /**< Column number of matrix. */ + const char* name = 0 /**< Name of matrix. */ + ); + +/** Prints a (possibly named) permuted matrix. + * \return SUCCESSFUL_RETURN */ +returnValue print( const real_t* const M, /**< Matrix to be printed. */ + int_t nrow, /**< Row number of matrix. */ + int_t ncol , /**< Column number of matrix. */ + const int_t* const ROW_idx, /**< Row pemutation vector. */ + const int_t* const COL_idx, /**< Column pemutation vector. */ + const char* name = 0 /**< Name of matrix. */ + ); + +/** Prints a (possibly named) index array. + * \return SUCCESSFUL_RETURN */ +returnValue print( const int_t* const index, /**< Index array to be printed. */ + int_t n, /**< Length of index array. */ + const char* name = 0 /**< Name of index array. */ + ); + + +/** Prints a string to desired output target (useful also for MATLAB output!). + * \return SUCCESSFUL_RETURN */ +returnValue myPrintf( const char* s /**< String to be written. */ + ); + + +/** Prints qpOASES copyright notice. + * \return SUCCESSFUL_RETURN */ +returnValue printCopyrightNotice( ); + + +/** Reads a real_t matrix from file. + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE \n + RET_UNABLE_TO_READ_FILE */ +returnValue readFromFile( real_t* data, /**< Matrix to be read from file. */ + int_t nrow, /**< Row number of matrix. */ + int_t ncol, /**< Column number of matrix. */ + const char* datafilename /**< Data file name. */ + ); + +/** Reads a real_t vector from file. + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE \n + RET_UNABLE_TO_READ_FILE */ +returnValue readFromFile( real_t* data, /**< Vector to be read from file. */ + int_t n, /**< Length of vector. */ + const char* datafilename /**< Data file name. */ + ); + +/** Reads an integer (column) vector from file. + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE \n + RET_UNABLE_TO_READ_FILE */ +returnValue readFromFile( int_t* data, /**< Vector to be read from file. */ + int_t n, /**< Length of vector. */ + const char* datafilename /**< Data file name. */ + ); + + +/** Writes a real_t matrix into a file. + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE */ +returnValue writeIntoFile( const real_t* const data, /**< Matrix to be written into file. */ + int_t nrow, /**< Row number of matrix. */ + int_t ncol, /**< Column number of matrix. */ + const char* datafilename, /**< Data file name. */ + BooleanType append = BT_FALSE /**< Indicates if data shall be appended if the file already exists (otherwise it is overwritten). */ + ); + +/** Writes a real_t vector into a file. + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE */ +returnValue writeIntoFile( const real_t* const data, /**< Vector to be written into file. */ + int_t n, /**< Length of vector. */ + const char* datafilename, /**< Data file name. */ + BooleanType append = BT_FALSE /**< Indicates if data shall be appended if the file already exists (otherwise it is overwritten). */ + ); + +/** Writes an integer (column) vector into a file. + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_OPEN_FILE */ +returnValue writeIntoFile( const int_t* const integer, /**< Integer vector to be written into file. */ + int_t n, /**< Length of vector. */ + const char* datafilename, /**< Data file name. */ + BooleanType append = BT_FALSE /**< Indicates if integer shall be appended if the file already exists (otherwise it is overwritten). */ + ); + +/** Writes a real_t matrix/vector into a Matlab binary file. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS + RET_UNABLE_TO_WRITE_FILE */ +returnValue writeIntoMatFile( FILE* const matFile, /**< Pointer to Matlab binary file. */ + const real_t* const data, /**< Data to be written into file. */ + int_t nRows, /**< Row number of matrix. */ + int_t nCols, /**< Column number of matrix. */ + const char* name /**< Matlab name of matrix/vector to be stored. */ + ); + +/** Writes in integer matrix/vector into a Matlab binary file. + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS + RET_UNABLE_TO_WRITE_FILE */ +returnValue writeIntoMatFile( FILE* const matFile, /**< Pointer to Matlab binary file. */ + const int_t* const data, /**< Data to be written into file. */ + int_t nRows, /**< Row number of matrix. */ + int_t nCols, /**< Column number of matrix. */ + const char* name /**< Matlab name of matrix/vector to be stored. */ + ); + + +/** Returns the current system time. + * \return current system time */ +real_t getCPUtime( ); + + +/** Returns the N-norm of a vector. + * \return >= 0.0: successful */ +real_t getNorm( const real_t* const v, /**< Vector. */ + int_t n, /**< Vector's dimension. */ + int_t type = 2 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ); + + +/** Tests whether two real_t-valued arguments are (numerically) equal. + * \return BT_TRUE: arguments differ not more than TOL \n + BT_FALSE: arguments differ more than TOL */ +inline BooleanType isEqual( real_t x, /**< First real number. */ + real_t y, /**< Second real number. */ + real_t TOL = ZERO /**< Tolerance for comparison. */ + ); + + +/** Tests whether a real-valued argument is (numerically) zero. + * \return BT_TRUE: argument differs from 0.0 not more than TOL \n + BT_FALSE: argument differs from 0.0 more than TOL */ +inline BooleanType isZero( real_t x, /**< Real number. */ + real_t TOL = ZERO /**< Tolerance for comparison. */ + ); + + +/** Returns sign of a real-valued argument. + * \return 1.0: argument is non-negative \n + -1.0: argument is negative */ +inline real_t getSign( real_t arg /**< real-valued argument whose sign is to be determined. */ + ); + + +/** Returns maximum of two integers. + * \return Maximum of two integers */ +inline int_t getMax( int_t x, /**< First integer. */ + int_t y /**< Second integer. */ + ); + +/** Returns minimum of two integers. + * \return Minimum of two integers */ +inline int_t getMin( int_t x, /**< First integer. */ + int_t y /**< Second integer. */ + ); + + +/** Returns maximum of two reals. + * \return Maximum of two reals */ +inline real_t getMax( real_t x, /**< First real number. */ + real_t y /**< Second real number. */ + ); + +/** Returns minimum of two reals. + * \return Minimum of two reals */ +inline real_t getMin( real_t x, /**< First real number. */ + real_t y /**< Second real number. */ + ); + +/** Returns the absolute value of a real number. + * \return Absolute value of a real number */ +inline real_t getAbs( real_t x /**< Real number. */ + ); + +/** Returns the square-root of a real number. + * \return Square-root of a real number */ +inline real_t getSqrt( real_t x /**< Non-negative real number. */ + ); + + +/** Computes the maximum violation of the KKT optimality conditions + * of given iterate for given QP data. */ +returnValue getKktViolation( int_t nV, /**< Number of variables. */ + int_t nC, /**< Number of constraints. */ + const real_t* const H, /**< Hessian matrix (may be NULL if Hessian is zero or identity matrix). */ + const real_t* const g, /**< Gradient vector. */ + const real_t* const A, /**< Constraint matrix. */ + const real_t* const lb, /**< Lower bound vector (on variables). */ + const real_t* const ub, /**< Upper bound vector (on variables). */ + const real_t* const lbA, /**< Lower constraints' bound vector. */ + const real_t* const ubA, /**< Upper constraints' bound vector. */ + const real_t* const x, /**< Primal trial vector. */ + const real_t* const y, /**< Dual trial vector. */ + real_t& stat, /**< Output: maximum value of stationarity condition residual. */ + real_t& feas, /**< Output: maximum value of primal feasibility violation. */ + real_t& cmpl, /**< Output: maximum value of complementarity residual. */ + const real_t* const workingSetB = 0, /**< Working set of bounds (used to determine active bounds). */ + const real_t* const workingSetC = 0, /**< Working set of constraints (used to determine active constraints). */ + BooleanType hasIdentityHessian = BT_FALSE /**< Indicating whether Hessian matrix is identity matrix or not if NULL pointer is passed. */ + ); + +/** Computes the maximum violation of the KKT optimality conditions + * of given iterate for given QP data. */ +returnValue getKktViolation( int_t nV, /**< Number of variables. */ + const real_t* const H, /**< Hessian matrix (may be NULL if Hessian is zero or identity matrix). */ + const real_t* const g, /**< Gradient vector. */ + const real_t* const lb, /**< Lower bound vector (on variables). */ + const real_t* const ub, /**< Upper bound vector (on variables). */ + const real_t* const x, /**< Primal trial vector. */ + const real_t* const y, /**< Dual trial vector. */ + real_t& stat, /**< Output: maximum value of stationarity condition residual. */ + real_t& feas, /**< Output: maximum value of primal feasibility violation. */ + real_t& cmpl, /**< Output: maximum value of complementarity residual. */ + const real_t* const workingSetB = 0, /**< Working set of bounds (used to determine active bounds). */ + BooleanType hasIdentityHessian = BT_FALSE /**< Indicating whether Hessian matrix is identity matrix or not if NULL pointer is passed */ + ); + + +/** Writes a value of BooleanType into a string. + * \return SUCCESSFUL_RETURN */ +returnValue convertBooleanTypeToString( BooleanType value, /**< Value to be written. */ + char* const string /**< Input: String of sufficient size, \n + Output: String containing value. */ + ); + +/** Writes a value of SubjectToStatus into a string. + * \return SUCCESSFUL_RETURN */ +returnValue convertSubjectToStatusToString( SubjectToStatus value, /**< Value to be written. */ + char* const string /**< Input: String of sufficient size, \n + Output: String containing value. */ + ); + +/** Writes a value of PrintLevel into a string. + * \return SUCCESSFUL_RETURN */ +returnValue convertPrintLevelToString( PrintLevel value, /**< Value to be written. */ + char* const string /**< Input: String of sufficient size, \n + Output: String containing value. */ + ); + + +/** Converts a returnValue from an (S)QProblem(B) object into a more + * simple status flag. + * + * \return 0: QP problem solved + * 1: QP could not be solved within given number of iterations + * -1: QP could not be solved due to an internal error + * -2: QP is infeasible (and thus could not be solved) + * -3: QP is unbounded (and thus could not be solved) + */ +int_t getSimpleStatus( returnValue returnvalue, /**< ReturnValue to be analysed. */ + BooleanType doPrintStatus = BT_FALSE /**< Flag indicating whether simple status shall be printed to screen. */ + ); + + +/** Normalises QP constraints. + * \return SUCCESSFUL_RETURN \n + * RET_INVALID_ARGUMENTS */ +returnValue normaliseConstraints( int_t nV, /**< Number of variables. */ + int_t nC, /**< Number of constraints. */ + real_t* A, /**< Input: Constraint matrix, \n + Output: Normalised constraint matrix. */ + real_t* lbA, /**< Input: Constraints' lower bound vector, \n + Output: Normalised constraints' lower bound vector. */ + real_t* ubA, /**< Input: Constraints' upper bound vector, \n + Output: Normalised constraints' upper bound vector. */ + int_t type = 1 /**< Norm type, 1: one-norm, 2: Euclidean norm. */ + ); + + +#ifdef __DEBUG__ +/** Writes matrix with given dimension into specified file. */ +extern "C" void gdb_printmat( const char *fname, /**< File name. */ + real_t *M, /**< Matrix to be written. */ + int_t n, /**< Number of rows. */ + int_t m, /**< Number of columns. */ + int_t ldim /**< Leading dimension. */ + ); +#endif /* __DEBUG__ */ + + +#if defined(__DSPACE__) || defined(__XPCTARGET__) || defined(__C_WRAPPER__) +extern "C" void __cxa_pure_virtual( void ); +#endif /* __DSPACE__ || __XPCTARGET__*/ + + + +END_NAMESPACE_QPOASES + + +#include + +#endif /* QPOASES_UTILS_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/Utils.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/Utils.ipp new file mode 100644 index 0000000..3f8bdc3 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/Utils.ipp @@ -0,0 +1,174 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + + +/** + * \file include/qpOASES/Utils.ipp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of some inlined utilities for working with the different QProblem classes. + */ + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/* + * i s E q u a l + */ +inline BooleanType isEqual( real_t x, + real_t y, + real_t TOL + ) +{ + if ( getAbs(x-y) <= TOL ) + return BT_TRUE; + else + return BT_FALSE; +} + + +/* + * i s Z e r o + */ +inline BooleanType isZero( real_t x, + real_t TOL + ) +{ + if ( getAbs(x) <= TOL ) + return BT_TRUE; + else + return BT_FALSE; +} + + +/* + * g e t S i g n + */ +inline real_t getSign( real_t arg + ) +{ + if ( arg >= 0.0 ) + return 1.0; + else + return -1.0; +} + + + +/* + * g e t M a x + */ +inline int_t getMax( int_t x, + int_t y + ) +{ + return (yx) ? x : y; +} + + + +/* + * g e t M a x + */ +inline real_t getMax( real_t x, + real_t y + ) +{ + #ifdef __NO_FMATH__ + return (yx) ? x : y; + #else + return (y>x) ? x : y; + //return fmin(x,y); /* seems to be slower */ + #endif +} + + +/* + * g e t A b s + */ +inline real_t getAbs( real_t x + ) +{ + #ifdef __NO_FMATH__ + return (x>=0.0) ? x : -x; + #else + return fabs(x); + #endif +} + + +/* + * g e t S q r t + */ +inline real_t getSqrt( real_t x + ) +{ + #ifdef __NO_FMATH__ + return sqrt(x); /* put your custom sqrt-replacement here */ + #else + return sqrt(x); + #endif +} + + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/extras/OQPinterface.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/extras/OQPinterface.hpp new file mode 100644 index 0000000..30a4e56 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/extras/OQPinterface.hpp @@ -0,0 +1,250 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/extras/OQPinterface.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Declaration of an interface comprising several utility functions + * for solving test problems from the Online QP Benchmark Collection + * (This collection is no longer maintained, see + * http://www.qpOASES.org/onlineQP for a backup). + */ + + +#ifndef QPOASES_OQPINTERFACE_HPP +#define QPOASES_OQPINTERFACE_HPP + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** Reads dimensions of an Online QP Benchmark problem from file. + * + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_READ_FILE \n + RET_FILEDATA_INCONSISTENT */ +returnValue readOqpDimensions( const char* path, /**< Full path of the data files (without trailing slash!). */ + int_t& nQP, /**< Output: Number of QPs. */ + int_t& nV, /**< Output: Number of variables. */ + int_t& nC, /**< Output: Number of constraints. */ + int_t& nEC /**< Output: Number of equality constraints. */ + ); + +/** Reads data of an Online QP Benchmark problem from file. + * This function allocates the required memory for all data; after successfully calling it, + * you have to free this memory yourself! + * + * \return SUCCESSFUL_RETURN \n + RET_INVALID_ARGUMENTS \n + RET_UNABLE_TO_READ_FILE \n + RET_FILEDATA_INCONSISTENT */ +returnValue readOqpData( const char* path, /**< Full path of the data files (without trailing slash!). */ + int_t& nQP, /**< Output: Number of QPs. */ + int_t& nV, /**< Output: Number of variables. */ + int_t& nC, /**< Output: Number of constraints. */ + int_t& nEC, /**< Output: Number of equality constraints. */ + real_t** H, /**< Output: Hessian matrix. */ + real_t** g, /**< Output: Sequence of gradient vectors. */ + real_t** A, /**< Output: Constraint matrix. */ + real_t** lb, /**< Output: Sequence of lower bound vectors (on variables). */ + real_t** ub, /**< Output: Sequence of upper bound vectors (on variables). */ + real_t** lbA, /**< Output: Sequence of lower constraints' bound vectors. */ + real_t** ubA, /**< Output: Sequence of upper constraints' bound vectors. */ + real_t** xOpt, /**< Output: Sequence of primal solution vectors + * (not read if a null pointer is passed). */ + real_t** yOpt, /**< Output: Sequence of dual solution vectors + * (not read if a null pointer is passed). */ + real_t** objOpt /**< Output: Sequence of optimal objective function values + * (not read if a null pointer is passed). */ + ); + + +/** Solves an Online QP Benchmark problem as specified by the arguments. + * The maximum deviations from the given optimal solution as well as the + * maximum CPU time to solve each QP are determined. + * + * Note: This variant is outdated and only kept to ensure + * backwards-compatibility! + * + * \return SUCCESSFUL_RETURN \n + RET_BENCHMARK_ABORTED */ +returnValue solveOqpBenchmark( int_t nQP, /**< Number of QPs. */ + int_t nV, /**< Number of variables. */ + int_t nC, /**< Number of constraints. */ + int_t nEC, /**< Number of equality constraints. */ + const real_t* const _H, /**< Hessian matrix. */ + const real_t* const g, /**< Sequence of gradient vectors. */ + const real_t* const _A, /**< Constraint matrix. */ + const real_t* const lb, /**< Sequence of lower bound vectors (on variables). */ + const real_t* const ub, /**< Sequence of upper bound vectors (on variables). */ + const real_t* const lbA, /**< Sequence of lower constraints' bound vectors. */ + const real_t* const ubA, /**< Sequence of upper constraints' bound vectors. */ + BooleanType isSparse, /**< Shall convert matrices to sparse format before solution? */ + const Options& options, /**< QP solver options to be used while solving benchmark problems. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Maximum number of performed working set recalculations. */ + real_t& maxCPUtime, /**< Output: Maximum CPU time required for solving each QP. */ + real_t& maxStationarity, /**< Output: Maximum residual of stationarity condition. */ + real_t& maxFeasibility, /**< Output: Maximum residual of primal feasibility condition. */ + real_t& maxComplementarity /**< Output: Maximum residual of complementarity condition. */ + ); + +/** Solves an Online QP Benchmark problem as specified by the arguments. + * The maximum deviations from the given optimal solution as well as the + * maximum CPU time to solve each QP are determined. + * + * \return SUCCESSFUL_RETURN \n + RET_BENCHMARK_ABORTED */ +returnValue solveOqpBenchmark( int_t nQP, /**< Number of QPs. */ + int_t nV, /**< Number of variables. */ + int_t nC, /**< Number of constraints. */ + int_t nEC, /**< Number of equality constraints. */ + const real_t* const _H, /**< Hessian matrix. */ + const real_t* const g, /**< Sequence of gradient vectors. */ + const real_t* const _A, /**< Constraint matrix. */ + const real_t* const lb, /**< Sequence of lower bound vectors (on variables). */ + const real_t* const ub, /**< Sequence of upper bound vectors (on variables). */ + const real_t* const lbA, /**< Sequence of lower constraints' bound vectors. */ + const real_t* const ubA, /**< Sequence of upper constraints' bound vectors. */ + BooleanType isSparse, /**< Shall convert matrices to sparse format before solution? */ + BooleanType useHotstarts, /**< Shall QP solution be hotstarted? */ + const Options& options, /**< QP solver options to be used while solving benchmark problems. */ + int_t maxAllowedNWSR, /**< Maximum number of working set recalculations to be performed. */ + real_t& maxNWSR, /**< Output: Maximum number of performed working set recalculations. */ + real_t& avgNWSR, /**< Output: Average number of performed working set recalculations. */ + real_t& maxCPUtime, /**< Output: Maximum CPU time required for solving each QP. */ + real_t& avgCPUtime, /**< Output: Average CPU time required for solving each QP. */ + real_t& maxStationarity, /**< Output: Maximum residual of stationarity condition. */ + real_t& maxFeasibility, /**< Output: Maximum residual of primal feasibility condition. */ + real_t& maxComplementarity /**< Output: Maximum residual of complementarity condition. */ + ); + + +/** Solves an Online QP Benchmark problem (without constraints) as specified + * by the arguments. The maximum deviations from the given optimal solution + * as well as the maximum CPU time to solve each QP are determined. + * + * Note: This variant is outdated and only kept to ensure + * backwards-compatibility! + * + * \return SUCCESSFUL_RETURN \n + RET_BENCHMARK_ABORTED */ +returnValue solveOqpBenchmark( int_t nQP, /**< Number of QPs. */ + int_t nV, /**< Number of variables. */ + const real_t* const _H, /**< Hessian matrix. */ + const real_t* const g, /**< Sequence of gradient vectors. */ + const real_t* const lb, /**< Sequence of lower bound vectors (on variables). */ + const real_t* const ub, /**< Sequence of upper bound vectors (on variables). */ + BooleanType isSparse, /**< Shall convert matrices to sparse format before solution? */ + const Options& options, /**< QP solver options to be used while solving benchmark problems. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Maximum number of performed working set recalculations. */ + real_t& maxCPUtime, /**< Output: Maximum CPU time required for solving each QP. */ + real_t& maxStationarity, /**< Output: Maximum residual of stationarity condition. */ + real_t& maxFeasibility, /**< Output: Maximum residual of primal feasibility condition. */ + real_t& maxComplementarity /**< Output: Maximum residual of complementarity condition. */ + ); + +/** Solves an Online QP Benchmark problem (without constraints) as specified + * by the arguments. The maximum deviations from the given optimal solution + * as well as the maximum CPU time to solve each QP are determined. + * + * \return SUCCESSFUL_RETURN \n + RET_BENCHMARK_ABORTED */ +returnValue solveOqpBenchmark( int_t nQP, /**< Number of QPs. */ + int_t nV, /**< Number of variables. */ + const real_t* const _H, /**< Hessian matrix. */ + const real_t* const g, /**< Sequence of gradient vectors. */ + const real_t* const lb, /**< Sequence of lower bound vectors (on variables). */ + const real_t* const ub, /**< Sequence of upper bound vectors (on variables). */ + BooleanType isSparse, /**< Shall convert matrices to sparse format before solution? */ + BooleanType useHotstarts, /**< Shall QP solution be hotstarted? */ + const Options& options, /**< QP solver options to be used while solving benchmark problems. */ + int_t maxAllowedNWSR, /**< Maximum number of working set recalculations to be performed. */ + real_t& maxNWSR, /**< Output: Maximum number of performed working set recalculations. */ + real_t& avgNWSR, /**< Output: Average number of performed working set recalculations. */ + real_t& maxCPUtime, /**< Output: Maximum CPU time required for solving each QP. */ + real_t& avgCPUtime, /**< Output: Average CPU time required for solving each QP. */ + real_t& maxStationarity, /**< Output: Maximum residual of stationarity condition. */ + real_t& maxFeasibility, /**< Output: Maximum residual of primal feasibility condition. */ + real_t& maxComplementarity /**< Output: Maximum residual of complementarity condition. */ + ); + + +/** Runs an Online QP Benchmark problem and determines the maximum + * violation of the KKT optimality conditions as well as the + * maximum CPU time to solve each QP. + * + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_READ_BENCHMARK \n + RET_BENCHMARK_ABORTED */ +returnValue runOqpBenchmark( const char* path, /**< Full path of the benchmark files (without trailing slash!). */ + BooleanType isSparse, /**< Shall convert matrices to sparse format before solution? */ + const Options& options, /**< QP solver options to be used while solving benchmark problems. */ + int_t& nWSR, /**< Input: Maximum number of working set recalculations; \n + Output: Maximum number of performed working set recalculations. */ + real_t& maxCPUtime, /**< Output: Maximum CPU time required for solving each QP. */ + real_t& maxStationarity, /**< Output: Maximum residual of stationarity condition. */ + real_t& maxFeasibility, /**< Output: Maximum residual of primal feasibility condition. */ + real_t& maxComplementarity /**< Output: Maximum residual of complementarity condition. */ + ); + + +/** Runs an Online QP Benchmark problem and determines the maximum + * violation of the KKT optimality conditions as well as the + * maximum and average number of iterations and CPU time to solve + * each QP. + * + * \return SUCCESSFUL_RETURN \n + RET_UNABLE_TO_READ_BENCHMARK \n + RET_BENCHMARK_ABORTED */ +returnValue runOqpBenchmark( const char* path, /**< Full path of the benchmark files (without trailing slash!). */ + BooleanType isSparse, /**< Shall convert matrices to sparse format before solution? */ + BooleanType useHotstarts, /**< Shall QP solution be hotstarted? */ + const Options& options, /**< QP solver options to be used while solving benchmark problems. */ + int_t maxAllowedNWSR, /**< Maximum number of working set recalculations to be performed. */ + real_t& maxNWSR, /**< Output: Maximum number of performed working set recalculations. */ + real_t& avgNWSR, /**< Output: Average number of performed working set recalculations. */ + real_t& maxCPUtime, /**< Output: Maximum CPU time required for solving each QP. */ + real_t& avgCPUtime, /**< Output: Average CPU time required for solving each QP. */ + real_t& maxStationarity, /**< Output: Maximum residual of stationarity condition. */ + real_t& maxFeasibility, /**< Output: Maximum residual of primal feasibility condition. */ + real_t& maxComplementarity /**< Output: Maximum residual of complementarity condition. */ + ); + +END_NAMESPACE_QPOASES + + +#endif /* QPOASES_OQPINTERFACE_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/extras/SolutionAnalysis.hpp b/locomotion/src/third_party/qpOASES/include/qpOASES/extras/SolutionAnalysis.hpp new file mode 100644 index 0000000..ea4855d --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/extras/SolutionAnalysis.hpp @@ -0,0 +1,166 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/extras/SolutionAnalysis.hpp + * \author Hans Joachim Ferreau (thanks to Boris Houska) + * \version 3.2 + * \date 2008-2017 + * + * Declaration of the SolutionAnalysis class designed to perform + * additional analysis after solving a QP with qpOASES. + */ + + +#ifndef QPOASES_SOLUTIONANALYSIS_HPP +#define QPOASES_SOLUTIONANALYSIS_HPP + + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + +/** + * \brief Provides additional tools for analysing QP solutions. + * + * This class is intended to provide additional tools for analysing + * a QP solution obtained with qpOASES. + * + * \author Hans Joachim Ferreau (thanks to Boris Houska) + * \version 3.2 + * \date 2008-2017 + */ +class SolutionAnalysis +{ + /* + * PUBLIC MEMBER FUNCTIONS + */ + public: + /** Default constructor. */ + SolutionAnalysis( ); + + /** Copy constructor (deep copy). */ + SolutionAnalysis( const SolutionAnalysis& rhs /**< Rhs object. */ + ); + + /** Destructor. */ + ~SolutionAnalysis( ); + + /** Assignment operator (deep copy). */ + SolutionAnalysis& operator=( const SolutionAnalysis& rhs /**< Rhs object. */ + ); + + + /** Computes the maximum violation of the KKT optimality conditions + * of the current iterate within the QProblemB object. + * \return Maximum violation of the KKT conditions (or INFTY on error). */ + real_t getKktViolation( QProblemB* const qp, /**< QProblemB to be analysed. */ + real_t* const maxStat = 0, /**< Output: maximum value of stationarity condition residual. */ + real_t* const maxFeas = 0, /**< Output: maximum value of primal feasibility violation. */ + real_t* const maxCmpl = 0 /**< Output: maximum value of complementarity residual. */ + ) const; + + /** Computes the maximum violation of the KKT optimality conditions + * of the current iterate within the QProblem object. + * \return Maximum violation of the KKT conditions (or INFTY on error). */ + real_t getKktViolation( QProblem* const qp, /**< QProblem to be analysed. */ + real_t* const maxStat = 0, /**< Output: maximum value of stationarity condition residual. */ + real_t* const maxFeas = 0, /**< Output: maximum value of primal feasibility violation. */ + real_t* const maxCmpl = 0 /**< Output: maximum value of complementarity residual. */ + ) const; + + /** Computes the maximum violation of the KKT optimality conditions + * of the current iterate within the SQProblem object. + * \return Maximum violation of the KKT conditions (or INFTY on error). */ + real_t getKktViolation( SQProblem* const qp, /**< SQProblem to be analysed. */ + real_t* const maxStat = 0, /**< Output: maximum value of stationarity condition residual. */ + real_t* const maxFeas = 0, /**< Output: maximum value of primal feasibility violation. */ + real_t* const maxCmpl = 0 /**< Output: maximum value of complementarity residual. */ + ) const; + + + /** Computes the variance-covariance matrix of the QP output for uncertain + inputs. + * \return SUCCESSFUL_RETURN \n + RET_HOTSTART_FAILED \n + RET_STEPDIRECTION_FAILED_TQ \n + RET_STEPDIRECTION_FAILED_CHOLESKY */ + returnValue getVarianceCovariance( QProblemB* const qp, /**< QProblemB to be analysed. */ + const real_t* const g_b_bA_VAR, /**< Input: Variance-covariance of g, the bounds lb and ub, + * and lbA and ubA respectively. Dimension: 2nV x 2nV */ + real_t* const Primal_Dual_VAR /**< Output: The result for the variance-covariance of the primal + * and dual variables. Dimension: 2nV x 2nV */ + ) const; + + /** Computes the variance-covariance matrix of the QP output for uncertain + inputs. + * \return SUCCESSFUL_RETURN \n + RET_HOTSTART_FAILED \n + RET_STEPDIRECTION_FAILED_TQ \n + RET_STEPDIRECTION_FAILED_CHOLESKY */ + returnValue getVarianceCovariance( QProblem* const qp, /**< QProblem to be analysed. */ + const real_t* const g_b_bA_VAR, /**< Input: Variance-covariance of g, the bounds lb and ub, + * and lbA and ubA respectively. Dimension: (2nV+nC) x (2nV+nC) */ + real_t* const Primal_Dual_VAR /**< Output: The result for the variance-covariance of the primal + * and dual variables. Dimension: (2nV+nC) x (2nV+nC) */ + ) const; + + /** Computes the variance-covariance matrix of the QP output for uncertain + inputs. + * \return SUCCESSFUL_RETURN \n + RET_HOTSTART_FAILED \n + RET_STEPDIRECTION_FAILED_TQ \n + RET_STEPDIRECTION_FAILED_CHOLESKY */ + returnValue getVarianceCovariance( SQProblem* const qp, /**< SQProblem to be analysed. */ + const real_t* const g_b_bA_VAR, /**< Input: Variance-covariance of g, the bounds lb and ub, + * and lbA and ubA respectively. Dimension: (2nV+nC) x (2nV+nC) */ + real_t* const Primal_Dual_VAR /**< Output: The result for the variance-covariance of the primal + * and dual variables. Dimension: (2nV+nC) x (2nV+nC) */ + ) const; + + /** Checks if a direction of negative curvature shows up if we remove all bounds that just recently became active */ + returnValue checkCurvatureOnStronglyActiveConstraints( SQProblemSchur* qp ); + returnValue checkCurvatureOnStronglyActiveConstraints( SQProblem* qp ); + + /* + * PROTECTED MEMBER VARIABLES + */ + protected: + +}; + + +END_NAMESPACE_QPOASES + +#include + +#endif /* QPOASES_SOLUTIONANALYSIS_HPP */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/include/qpOASES/extras/SolutionAnalysis.ipp b/locomotion/src/third_party/qpOASES/include/qpOASES/extras/SolutionAnalysis.ipp new file mode 100644 index 0000000..cd89776 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/include/qpOASES/extras/SolutionAnalysis.ipp @@ -0,0 +1,51 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file include/qpOASES/extras/SolutionAnalysis.ipp + * \author Hans Joachim Ferreau (thanks to Boris Houska) + * \version 3.2 + * \date 2008-2017 + * + * Implementation of inlined member functions of the SolutionAnalysis class + * designed to perform additional analysis after solving a QP with qpOASES. + * + */ + + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +BEGIN_NAMESPACE_QPOASES + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/CUTEst/Makefile b/locomotion/src/third_party/qpOASES/interfaces/CUTEst/Makefile new file mode 100644 index 0000000..e1fbef0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/CUTEst/Makefile @@ -0,0 +1,79 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: cutestDriver/Makefile +## Author: Dennis Janka +## Version: 3.2 +## Date: 2015-2017 +## + +# include directories, relative +IDIR = ../../include +SRCDIR = ../../src +BINDIR = ../../bin +CUTESTLIBPATH = ${CUTEST}/objects/${MYARCH}/double + +# don't change that (for now) ... +PROBLEMPATH = ./prob + +# file extensions +CPP = g++ +CPPFLAGS = -Wall -pedantic -Wshadow -O0 -finline-functions -fPIC -DLINUX -g +FF = gfortran +FFLAGS = + +#link against CUTEst library, qpOASES library and compiled test problem +LINKOPTS = -L${CUTESTLIBPATH} -L${PROBLEMPATH} -Wl,-rpath=${PROBLEMPATH} \ + -L${BINDIR} -Wl,-rpath=${BINDIR} -lqpOASES \ + -lcutest -llapack -lm -lgfortran -lprob + +IFLAGS = -I${IDIR} \ + -I${CUTEST}/include + +QPOASES_EXES = \ + qpoasesCutest + +## +## targets +## + +all: ${QPOASES_EXES} + +qpoasesCutest: qpoasesCutest.o + @echo "Creating" $@ + ${CPP} -o $@ ${CPPFLAGS} $< ${LINKOPTS} + +clean: + rm -f *.o ${QPOASES_EXES} + +clobber: clean + +%.o: %.cpp + @echo "Creating" $@ + @${CPP} -c ${IFLAGS} ${CPPFLAGS} $< -o $@ + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/interfaces/CUTEst/makeprob b/locomotion/src/third_party/qpOASES/interfaces/CUTEst/makeprob new file mode 100755 index 0000000..237a895 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/CUTEst/makeprob @@ -0,0 +1,28 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo Usage: $0 problemname + exit +fi + +PROBLEMPATH="./prob" +mkdir -p $PROBLEMPATH +cd $PROBLEMPATH + +# Call sifdecoder (additional parameter for problem size can be passed) +if [ -z "$2" ]; then + sifdecoder $MASTSIF/$1 +else + sifdecoder -param N=$2 $MASTSIF/$1 +fi + +# Compile objects +gfortran -c RANGE.f -fPIC -o RANGE.o +gfortran -c ELFUN.f -fPIC -o ELFUN.o +gfortran -c GROUP.f -fPIC -o GROUP.o + +# Build shared library +gfortran -shared -o libprob.so RANGE.o ELFUN.o GROUP.o + +cd ../ + diff --git a/locomotion/src/third_party/qpOASES/interfaces/CUTEst/qpoasesCutest.cpp b/locomotion/src/third_party/qpOASES/interfaces/CUTEst/qpoasesCutest.cpp new file mode 100644 index 0000000..97a3368 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/CUTEst/qpoasesCutest.cpp @@ -0,0 +1,498 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/CUTEst/qpoasesCutest.cpp + * \author Dennis Janka + * \version 3.2 + * \date 2015-2017 + * + * Solve the CUTEst problem in prob/ subdirectory + */ + +/* Choose one or more methods to solve the QP */ +#define SOLVE_DENSE 0 /* Standard qpOASES, matrices passed dense */ +#define SOLVE_SPARSE 0 /* Standard qpOASES, matrices passed sparse */ +#define SOLVE_SCHUR 1 /* Schur complement qpOASES */ + + +#include +#include + +extern "C" { /* To prevent C++ compilers from mangling symbols */ +#include +} + + +int convertTripletToHbf( int m, int n, int nnz, + double *vals, int *iRow, int *jCol, + double *vals_hbf, int *iRow_hbf, int *jCol_hbf ) +{ + int i, ii, j, k; + + /* Initialize output arrays */ + for( k=0; k-1; k-- ) + jCol_hbf[k] = jCol_hbf[k+1] - jCol_hbf[k]; + + /* Put row indices and values at the right places, use jCol_hbf[j] to track elements of the jth column */ + for( k=0; k0; k-- ) + jCol_hbf[k] = jCol_hbf[k-1]; + jCol_hbf[0] = 0; + + return 0; +} + + + +int main( ) +{ + /* + * PART I: Extract CUTEst problemdata: + * + * - problem dimension + * - variable and constraint bounds + * - objective gradient + * - sparse and dense Jacobian + * - sparse and dense Hessian + * - initial values for x and y + */ + + /* From CUTEst generic c package */ + char *fname = "prob/OUTSDIF.d"; /* CUTEst data file */ + int funit = 42; /* FORTRAN unit number for OUTSDIF.d */ + int iout = 6; /* FORTRAN unit number for error output */ + int io_buffer = 11; /* FORTRAN unit internal input/output */ + int ierr; /* Exit flag from OPEN and CLOSE */ + int status; /* Exit flag from CUTEst tools */ + int e_order = 0, l_order = 0, v_order = 0; + + + /* Problem description: the following variables will be set for qpOASES call */ + int nVar; /* number of variables */ + int nCon; /* number of constraints */ + double *lb, *ub; /* lower and upper bounds for variables */ + double *lbA, *ubA; /* lower and upper bounds for constraints */ + double *g; /* objective gradient */ +#if SOLVE_DENSE + double *hesDense, *jacDense; /* dense Hessian and Jacobian */ +#endif +#if SOLVE_SCHUR || SOLVE_SPARSE + /* Sparse Hessian and Jacobian in Harwell-Boeing format: */ + int nnzj, nnzh; /* number of nonzero elements in Jacobian and Hessian */ + double *hesVal, *jacVal; /* nonzero elements of Hessian and Jacobian */ + int *hesIndCol, *hesIndRow; /* column and row indices of Hessian */ + int *jacIndCol, *jacIndRow; /* column and row indices of Jacobian */ +#endif + + /* Additional problem description: these variables are set and may also be used by qpOASES */ + double obj; /* constant objective offset */ + double *xInit; /* initial values for primal variables */ + double *yInit; /* initial values for dual variables */ + logical *isEq; /* logical array to mark equality constraints */ + + + /* Open problem description file OUTSDIF.d */ + ierr = 0; + FORTRAN_open( &funit, fname, &ierr ); + if( ierr ) { + printf("Error opening file OUTSDIF.d.\nAborting.\n"); + exit(1); + } + + /* Determine problem size */ + CUTEST_cdimen( &status, &funit, &nVar, &nCon ); + if( status ) { + printf("** CUTEst error, status = %d, aborting\n", status); + exit(status); + } + + /* Reserve memory for variables, bounds, and multipliers */ + /* and call appropriate initialization routine for CUTEst */ + logical *isLinear; + xInit = new double[nVar]; + yInit = new double[nCon]; + lb = new double[nVar]; + ub = new double[nVar]; + lbA = new double[nCon]; + ubA = new double[nCon]; + isEq = new logical[nCon]; + isLinear = new logical[nCon]; + + CUTEST_csetup( &status, &funit, &iout, &io_buffer, + &nVar, &nCon, xInit, lb, ub, + yInit, lbA, ubA, isEq, isLinear, + &e_order, &l_order, &v_order ); + if( status ) { + printf("** CUTEst_csetup: error, status = %d, aborting\n", status); + exit(status); + } + + /* Evaluate gradient and objective at x=0 to get g */ + logical grad = 1; + g = new double[nVar]; + double *xZero = new double[nVar]; + for( int k=0; k 0 ) + { + /* Evaluate sparse constraints at x=0 to get the rhs of equality constraints (they are not set by csetup!) */ + CUTEST_ccfsg( &status, &nVar, &nCon, xZero, cVal, &nnzj, &lj, J_val, J_var, J_fun, &grad ); + if( status ) { + printf("** CUTEst_ccfsg: error, status = %d, aborting\n", status); + exit(status); + } + + for( int k=0; k 0 ) + { + /* Evaluate dense constraints at x=0 to get the rhs of equality constraints (they are not set by csetup!) */ + logical trans = 1; + jacDense = new double[nCon*nVar]; + CUTEST_ccfg( &status, &nVar, &nCon, xZero, cVal, &trans, &nVar, &nCon, jacDense, &grad ); + } + + /* Evaluate dense Hessian */ + hesDense = new double[nVar*nVar]; + CUTEST_cdh( &status, &nVar, &nCon, xInit, yInit, &nVar, hesDense ); + if( status ) { + printf("** CUTEst_cdh: error, status = %d, aborting\n", status); + exit(status); + } +#endif + delete[] xZero; + + /* + * End of CUTEst stuff + */ + + + /* + * PART II: qpOASES + */ + + USING_NAMESPACE_QPOASES + + Options opts; +#if SOLVE_DENSE + SymDenseMat *H_d; + DenseMatrix *A_d; +#endif +#if SOLVE_SCHUR || SOLVE_SPARSE + SymSparseMat *H_s; + SparseMatrix *A_s; +#endif + Bounds bInit( nVar ); + Constraints cInit( nCon ); + double *xOpt = new double[nVar]; + double *yOpt = new double[nVar+nCon]; + Bounds bOpt( nVar ); + Constraints cOpt( nCon ); + +#if SOLVE_DENSE + A_d = new DenseMatrix( nCon, nVar, nVar, jacDense ); + H_d = new SymDenseMat( nVar, nVar, nVar, hesDense ); +#endif +#if SOLVE_SCHUR || SOLVE_SPARSE + A_s = new SparseMatrix( nCon, nVar, jacIndRow, jacIndCol, jacVal ); + H_s = new SymSparseMat( nVar, nVar, hesIndRow, hesIndCol, hesVal ); + H_s->createDiagInfo(); +#endif + + /* Set initial working set depending on initial values for x and y */ + /// \todo I have not tested this + double eps = 2.0e-16; + for( int k=0; k 0 ) + { + delete[] jacVal; + delete[] jacIndRow; + delete[] jacIndCol; + } +#endif +#if SOLVE_DENSE + delete[] hesDense; + if( nCon > 0 ) + delete[] jacDense; +#endif + + return ret; +} + diff --git a/locomotion/src/third_party/qpOASES/interfaces/CUTEst/readme.txt b/locomotion/src/third_party/qpOASES/interfaces/CUTEst/readme.txt new file mode 100644 index 0000000..2983489 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/CUTEst/readme.txt @@ -0,0 +1,39 @@ +CUTEst interface for qpOASES +by Dennis Janka + +==================================================== + +0.) Files included: + + - qpoasesCutest.cpp + - Makefile + - makeprob + - readme.txt + +1.) Download and install CUTEst from + + http://ccpforge.cse.rl.ac.uk/gf/project/cutest/wiki/ + + Make sure all environment variables are set as instructed. + (in particular $CUTEST, $MYARCH and $MASTSIF) + +2.) To decode and compile a problem, type: + + ./makeprob + + For problems that come in different sizes (e.g. NCVXQP[1-9]) the size + parameter ( N= ) may be passed as a second argument: + + ./makeprob + + This calls "sifdecoder" to decode the .sif file and creates a shared + library libprob.so in prob/ that will be linked against the + qpOASES CUTEst interface. + +3.) Finally, call "make" to compile and link qpoasesCutest. + You may have to set the correct paths for the qpOASES library and + header files in the makefile. + +4.) The command ./qpoasesCutest runs qpOASES with the latest compiled + .sif problem. For solving further problems, only the appropriate + "./makeprob" call is required. diff --git a/locomotion/src/third_party/qpOASES/interfaces/c/Makefile b/locomotion/src/third_party/qpOASES/interfaces/c/Makefile new file mode 100644 index 0000000..f7774a1 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/c/Makefile @@ -0,0 +1,129 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: interfaces/c/Makefile +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2014-2017 +## + + +include ../../make.mk + +## +## flags +## + +IFLAGS = -I. \ + -I${IDIR} \ + -I${SRCDIR} + +QPOASES_WRAPPER_OBJECTS = \ + ${SRCDIR}/SQProblem.${OBJEXT} \ + ${SRCDIR}/QProblem.${OBJEXT} \ + ${SRCDIR}/QProblemB.${OBJEXT} \ + ${SRCDIR}/Bounds.${OBJEXT} \ + ${SRCDIR}/Constraints.${OBJEXT} \ + ${SRCDIR}/SubjectTo.${OBJEXT} \ + ${SRCDIR}/Indexlist.${OBJEXT} \ + ${SRCDIR}/Flipper.${OBJEXT} \ + ${SRCDIR}/Utils.${OBJEXT} \ + ${SRCDIR}/Options.${OBJEXT} \ + ${SRCDIR}/Matrices.${OBJEXT} \ + ${SRCDIR}/MessageHandling.${OBJEXT} \ + qpOASES_wrapper.${OBJEXT} + +QPOASES_DEPENDS = \ + ${IDIR}/qpOASES.hpp \ + ${IDIR}/qpOASES/LapackBlasReplacement.hpp \ + ${IDIR}/qpOASES/SQProblem.hpp \ + ${IDIR}/qpOASES/QProblem.hpp \ + ${IDIR}/qpOASES/Flipper.hpp \ + ${IDIR}/qpOASES/QProblemB.hpp \ + ${IDIR}/qpOASES/Bounds.hpp \ + ${IDIR}/qpOASES/Constraints.hpp \ + ${IDIR}/qpOASES/SubjectTo.hpp \ + ${IDIR}/qpOASES/Indexlist.hpp \ + ${IDIR}/qpOASES/Utils.hpp \ + ${IDIR}/qpOASES/Constants.hpp \ + ${IDIR}/qpOASES/Types.hpp \ + ${IDIR}/qpOASES/Options.hpp \ + ${IDIR}/qpOASES/Matrices.hpp \ + ${IDIR}/qpOASES/MessageHandling.hpp \ + qpOASES_wrapper.h + +QPOASES_C_EXAMPLES = \ + ${BINDIR}/c_example1${EXE} \ + ${BINDIR}/c_example1a${EXE} \ + ${BINDIR}/c_example1b${EXE} + + +## +## targets +## + +all: ${LINK_DEPENDS_WRAPPER} ${QPOASES_C_EXAMPLES} + + +${BINDIR}/libqpOASES_wrapper.${LIBEXT}: ${QPOASES_WRAPPER_OBJECTS} + @${ECHO} "Creating" $@ + @${AR} r $@ qpOASES_wrapper.${OBJEXT} + +${BINDIR}/libqpOASES_wrapper.${DLLEXT}: ${QPOASES_WRAPPER_OBJECTS} + @${ECHO} "Creating" $@ + ${CC} ${SHARED} ${DEF_TARGET} qpOASES_wrapper.${OBJEXT} ${LINK_LIBRARIES_WRAPPER} + +clean: + @${ECHO} "Cleaning up (interfaces/c)" + @${RM} -f *.${OBJEXT} ${BINDIR}/*.${LIBEXT} ${BINDIR}/*.${DLLEXT} ${BINDIR}/c_example*${EXE} + +clobber: clean + + +%.${OBJEXT}: %.cpp ${QPOASES_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} -c ${IFLAGS} ${CPPFLAGS} -D__C_WRAPPER__ $< + +c_example1.${OBJEXT}: c_example1.c ${LINK_DEPENDS_WRAPPER} + @${ECHO} "Creating" $@ + @${CC} ${DEF_TARGET} -c ${IFLAGS} ${CPPFLAGS} $< + +c_example1a.${OBJEXT}: c_example1a.c ${LINK_DEPENDS_WRAPPER} + @${ECHO} "Creating" $@ + @${CC} ${DEF_TARGET} -c ${IFLAGS} ${CPPFLAGS} $< + +c_example1b.${OBJEXT}: c_example1b.c ${LINK_DEPENDS_WRAPPER} + @${ECHO} "Creating" $@ + @${CC} ${DEF_TARGET} -c ${IFLAGS} ${CPPFLAGS} $< + + +${BINDIR}/%${EXE}: %.${OBJEXT} ${LINK_DEPENDS_WRAPPER} + @${ECHO} "Creating" $@ + ${CC} ${DEF_TARGET} ${IFLAGS} ${CPPFLAGS} $< ${QPOASES_LINK_WRAPPER} ${LINK_LIBRARIES_WRAPPER} + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/interfaces/c/c_example1.c b/locomotion/src/third_party/qpOASES/interfaces/c/c_example1.c new file mode 100644 index 0000000..9a917ee --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/c/c_example1.c @@ -0,0 +1,104 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/c/c_example1.c + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Very simple example for testing qpOASES (using QProblem class through C interface). + */ + +#include + +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + int nWSR; + qpOASES_Options options; + + real_t xOpt[2]; + real_t yOpt[2+1]; + real_t obj; + int status; + + qpOASES_Options_init( &options,0 ); + options.printLevel = PL_MEDIUM; + + + QProblem_setup( 2,1,HST_UNKNOWN ); + + /* Solve first QP. */ + nWSR = 10; + QProblem_init( H,g,A,lb,ub,lbA,ubA, + (int_t* const)&nWSR,0,&options, + xOpt,yOpt,&obj,(int_t* const)&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2], obj ); + + + /* Solve second QP. */ + nWSR = 10; + QProblem_hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, + (int_t* const)&nWSR,0, + xOpt,yOpt,&obj,(int_t* const)&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2], obj ); + + + QProblem_cleanup(); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/c/c_example1a.c b/locomotion/src/third_party/qpOASES/interfaces/c/c_example1a.c new file mode 100644 index 0000000..f341837 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/c/c_example1a.c @@ -0,0 +1,105 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/c/c_example1a.c + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Very simple example for testing qpOASES (using SQProblem class through C interface). + */ + +#include + +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t H_new[2*2] = { 1.0, 0.5, 0.5, 0.5 }; + real_t A_new[1*2] = { 1.0, 5.0 }; + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + int nWSR; + + real_t xOpt[2]; + real_t yOpt[2+1]; + real_t obj; + int status; + + qpOASES_Options options; + qpOASES_Options_init( &options,0 ); + + + SQProblem_setup( 2,1,HST_UNKNOWN ); + + /* Solve first QP. */ + nWSR = 10; + SQProblem_init( H,g,A,lb,ub,lbA,ubA, + (int_t* const)&nWSR,0,&options, + xOpt,yOpt,&obj,(int_t* const)&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2], obj ); + + + /* Solve second QP. */ + nWSR = 10; + SQProblem_hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, + (int_t* const)&nWSR,0, + xOpt,yOpt,&obj,(int_t* const)&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2], obj ); + + + SQProblem_cleanup(); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/c/c_example1b.c b/locomotion/src/third_party/qpOASES/interfaces/c/c_example1b.c new file mode 100644 index 0000000..701c7e5 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/c/c_example1b.c @@ -0,0 +1,102 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/c/example1b.c + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Very simple example for testing qpOASES (using QProblemB class through C interface). + */ + +#include + +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + + int nWSR; + qpOASES_Options options; + + real_t xOpt[2]; + real_t yOpt[2]; + real_t obj; + int status; + + qpOASES_Options_init( &options,0 ); + /*options.enableFlippingBounds = 0; */ + options.initialStatusBounds = ST_INACTIVE; + options.numRefinementSteps = 1; + options.enableCholeskyRefactorisation = 1; + + + QProblemB_setup( 2,HST_UNKNOWN ); + + /* Solve first QP. */ + nWSR = 10; + QProblemB_init( H,g,lb,ub, + (int_t* const)&nWSR,0,&options, + xOpt,yOpt,&obj,(int_t* const)&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1], obj ); + + + /* Solve second QP. */ + nWSR = 10; + QProblemB_hotstart( g_new,lb_new,ub_new, + (int_t* const)&nWSR,0, + xOpt,yOpt,&obj,(int_t* const)&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1], obj ); + + + QProblemB_cleanup(); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/c/qpOASES_wrapper.cpp b/locomotion/src/third_party/qpOASES/interfaces/c/qpOASES_wrapper.cpp new file mode 100644 index 0000000..4b5e5b4 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/c/qpOASES_wrapper.cpp @@ -0,0 +1,576 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/c/qpOASES_wrapper.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Interface that enables to call qpOASES from plain C. + * + */ + + +#include + +USING_NAMESPACE_QPOASES + + +extern "C" { +#include "qpOASES_wrapper.h" +} + + + + +/* + * q p O A S E S _ O p t i o n s _ i n i t + */ +int_t qpOASES_Options_init( qpOASES_Options* const options, + int_t mode + ) +{ + if ( ( mode < 0 ) || ( mode > 2 ) ) + return -1; + + if ( options == 0 ) + return -1; + + + /* setup default */ + options->printLevel = PL_MEDIUM; + #ifdef __DEBUG__ + options->printLevel = PL_HIGH; + #endif + #ifdef __SUPPRESSANYOUTPUT__ + options->printLevel = PL_NONE; + #endif + + options->enableRamping = BT_TRUE; + options->enableFarBounds = BT_TRUE; + options->enableFlippingBounds = BT_TRUE; + options->enableRegularisation = BT_FALSE; + options->enableFullLITests = BT_FALSE; + options->enableNZCTests = BT_TRUE; + options->enableDriftCorrection = 1; + options->enableCholeskyRefactorisation = 0; + options->enableEqualities = BT_FALSE; + + #ifdef __USE_SINGLE_PRECISION__ + options->terminationTolerance = 1.0e2 * EPS; + options->boundTolerance = 1.0e2 * EPS; + #else + options->terminationTolerance = 5.0e6 * EPS; + options->boundTolerance = 1.0e6 * EPS; + #endif + options->boundRelaxation = 1.0e4; + #ifdef __USE_SINGLE_PRECISION__ + options->epsNum = -1.0e2 * EPS; + options->epsDen = 1.0e2 * EPS; + #else + options->epsNum = -1.0e3 * EPS; + options->epsDen = 1.0e3 * EPS; + #endif + options->maxPrimalJump = 1.0e8; + options->maxDualJump = 1.0e8; + + options->initialRamping = 0.5; + options->finalRamping = 1.0; + options->initialFarBounds = 1.0e6; + options->growFarBounds = 1.0e3; + options->initialStatusBounds = ST_LOWER; + #ifdef __USE_SINGLE_PRECISION__ + options->epsFlipping = 5.0e1 * EPS; + #else + options->epsFlipping = 1.0e3 * EPS; + #endif + options->numRegularisationSteps = 0; + #ifdef __USE_SINGLE_PRECISION__ + options->epsRegularisation = 2.0e1 * EPS; + options->numRefinementSteps = 2; + #else + options->epsRegularisation = 1.0e3 * EPS; + options->numRefinementSteps = 1; + #endif + options->epsIterRef = 1.0e2 * EPS; + #ifdef __USE_SINGLE_PRECISION__ + options->epsLITests = 5.0e1 * EPS; + options->epsNZCTests = 1.0e2 * EPS; + #else + options->epsLITests = 1.0e5 * EPS; + options->epsNZCTests = 3.0e3 * EPS; + #endif + + options->enableDropInfeasibles = BT_FALSE; + options->dropBoundPriority = 1; + options->dropEqConPriority = 1; + options->dropIneqConPriority = 1; + + + switch ( mode ) + { + case 0: + /* default, already set */ + break; + + + case 1: + /* reliable */ + options->enableFullLITests = BT_TRUE; + options->enableCholeskyRefactorisation = 1; + + #ifdef __USE_SINGLE_PRECISION__ + options->numRefinementSteps = 3; + #else + options->numRefinementSteps = 2; + #endif + + + case 2: + /* MPC */ + options->enableRamping = BT_FALSE; + options->enableFarBounds = BT_TRUE; + options->enableFlippingBounds = BT_FALSE; + options->enableRegularisation = BT_TRUE; + options->enableNZCTests = BT_FALSE; + options->enableDriftCorrection = 0; + options->enableEqualities = BT_TRUE; + + #ifdef __USE_SINGLE_PRECISION__ + options->terminationTolerance = 1.0e3 * EPS; + #else + options->terminationTolerance = 1.0e9 * EPS; + #endif + + options->initialStatusBounds = ST_INACTIVE; + options->numRegularisationSteps = 1; + #ifdef __USE_SINGLE_PRECISION__ + options->numRefinementSteps = 2; + #else + options->numRefinementSteps = 0; + #endif + } + + return 0; +} + + +/* + * q p O A S E S _ O p t i o n s _ c o p y + */ +int_t qpOASES_Options_copy( const qpOASES_Options* const from, + Options* const to + ) +{ + if ( ( from == 0 ) || ( to == 0 ) ) + return -1; + + + to->printLevel = (PrintLevel)(from->printLevel); + + to->enableRamping = (BooleanType)(from->enableRamping); + to->enableFarBounds = (BooleanType)(from->enableFarBounds); + to->enableFlippingBounds = (BooleanType)(from->enableFlippingBounds); + to->enableRegularisation = (BooleanType)(from->enableRegularisation); + to->enableFullLITests = (BooleanType)(from->enableFullLITests); + to->enableNZCTests = (BooleanType)(from->enableNZCTests); + to->enableDriftCorrection = from->enableDriftCorrection; + to->enableCholeskyRefactorisation = from->enableCholeskyRefactorisation; + to->enableEqualities = (BooleanType)(from->enableEqualities); + + to->terminationTolerance = from->terminationTolerance; + to->boundTolerance = from->boundTolerance; + to->boundRelaxation = from->boundRelaxation; + to->epsNum = from->epsNum; + to->epsDen = from->epsDen; + to->maxPrimalJump = from->maxPrimalJump; + to->maxDualJump = from->maxDualJump; + + to->initialRamping = from->initialRamping; + to->finalRamping = from->finalRamping; + to->initialFarBounds = from->initialFarBounds; + to->growFarBounds = from->growFarBounds; + to->initialStatusBounds = (SubjectToStatus)(from->initialStatusBounds); + to->epsFlipping = from->epsFlipping; + to->numRegularisationSteps = from->numRegularisationSteps; + to->epsRegularisation = from->epsRegularisation; + to->numRefinementSteps = from->numRefinementSteps; + to->epsIterRef = from->epsIterRef; + to->epsLITests = from->epsLITests; + to->epsNZCTests = from->epsNZCTests; + + to->enableDropInfeasibles = (BooleanType)(from->enableDropInfeasibles); + to->dropBoundPriority = from->dropBoundPriority; + to->dropEqConPriority = from->dropEqConPriority; + to->dropIneqConPriority = from->dropIneqConPriority; + + return 0; +} + + + +/* + * q p O A S E S _ o b t a i n O u t p u t s + */ +int_t qpOASES_obtainOutputs( const QProblemB* const globalQpObject, + returnValue returnvalue, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ) +{ + if ( globalQpObject == 0 ) + return -1; + + globalQpObject->getPrimalSolution( x ); + globalQpObject->getDualSolution( y ); + *obj = globalQpObject->getObjVal( ); + *status = getSimpleStatus( returnvalue ); + + return 0; +} + + + +/* + * Q P r o b l e m _ s e t u p + */ +int_t QProblem_setup( int_t nV, + int_t nC, + int_t hessianType + ) +{ + if ( ( nV < 1 ) || ( nC < 0 ) ) + return -1; + + if ( ( hessianType < 0 ) || ( hessianType > 6 ) ) + return -1; + + if ( QProblem_cleanup() != 0 ) + return -1; + + globalQProblemObject = new QProblem( nV,nC,(HessianType)hessianType ); + + return 0; +} + + +/* + * Q P r o b l e m _ i n i t + */ +int_t QProblem_init( const real_t* const H, + const real_t* const g, + const real_t* const A, + const real_t* const lb, + const real_t* const ub, + const real_t* const lbA, + const real_t* const ubA, + int_t* const nWSR, + real_t* const cputime, + const qpOASES_Options* const options, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ) +{ + /* abort if QProblem_setup has not been called */ + if ( globalQProblemObject == 0 ) + return -1; + + /* adjust options if provided */ + if ( options != 0 ) + { + qpOASES_Options_copy( options,&globalOptionsObject ); + globalQProblemObject->setOptions( globalOptionsObject ); + } + + /* actually call solver */ + returnValue returnvalue = globalQProblemObject->init( H,g,A,lb,ub,lbA,ubA, *nWSR,cputime ); + + /* assign lhs arguments */ + return qpOASES_obtainOutputs( globalQProblemObject,returnvalue, x,y,obj,status ); +} + + +/* + * Q P r o b l e m _ h o t s t a r t + */ +int_t QProblem_hotstart( const real_t* const g, + const real_t* const lb, + const real_t* const ub, + const real_t* const lbA, + const real_t* const ubA, + int_t* const nWSR, + real_t* const cputime, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ) +{ + /* abort if QProblem_setup has not been called */ + if ( globalQProblemObject == 0 ) + return -1; + + /* actually call solver */ + returnValue returnvalue = globalQProblemObject->hotstart( g,lb,ub,lbA,ubA, *nWSR,cputime ); + + /* assign lhs arguments */ + return qpOASES_obtainOutputs( globalQProblemObject,returnvalue, x,y,obj,status ); + + return 0; +} + + +/* + * Q P r o b l e m _ c l e a n u p + */ +int_t QProblem_cleanup( ) +{ + if ( globalQProblemObject != 0 ) + { + delete globalQProblemObject; + globalQProblemObject = 0; + } + + return 0; +} + + + +/* + * Q P r o b l e m B _ s e t u p + */ +int_t QProblemB_setup( int_t nV, + int_t hessianType + ) +{ + if ( nV < 1 ) + return -1; + + if ( ( hessianType < 0 ) || ( hessianType > 6 ) ) + return -1; + + if ( QProblemB_cleanup() != 0 ) + return -1; + + globalQProblemBObject = new QProblemB( nV,(HessianType)hessianType ); + + return 0; +} + + +/* + * Q P r o b l e m B _ i n i t + */ +int_t QProblemB_init( const real_t* const H, + const real_t* const g, + const real_t* const lb, + const real_t* const ub, + int_t* const nWSR, + real_t* const cputime, + const qpOASES_Options* const options, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ) +{ + /* abort if QProblemB_setup has not been called */ + if ( globalQProblemBObject == 0 ) + return -1; + + /* adjust options if provided */ + if ( options != 0 ) + { + qpOASES_Options_copy( options,&globalOptionsObject ); + globalQProblemBObject->setOptions( globalOptionsObject ); + } + + /* actually call solver */ + returnValue returnvalue = globalQProblemBObject->init( H,g,lb,ub, *nWSR,cputime ); + + /* assign lhs arguments */ + return qpOASES_obtainOutputs( globalQProblemBObject,returnvalue, x,y,obj,status ); +} + + +/* + * Q P r o b l e m B _ h o t s t a r t + */ +int_t QProblemB_hotstart( const real_t* const g, + const real_t* const lb, + const real_t* const ub, + int_t* const nWSR, + real_t* const cputime, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ) +{ + /* abort if QProblemB_setup has not been called */ + if ( globalQProblemBObject == 0 ) + return -1; + + /* actually call solver */ + returnValue returnvalue = globalQProblemBObject->hotstart( g,lb,ub, *nWSR,cputime ); + + /* assign lhs arguments */ + return qpOASES_obtainOutputs( globalQProblemBObject,returnvalue, x,y,obj,status ); + + return 0; +} + + +/* + * Q P r o b l e m B _ c l e a n u p + */ +int_t QProblemB_cleanup( ) +{ + if ( globalQProblemBObject != 0 ) + { + delete globalQProblemBObject; + globalQProblemBObject = 0; + } + + return 0; +} + + + +/* + * S Q P r o b l e m _ s e t u p + */ +int_t SQProblem_setup( int_t nV, + int_t nC, + int_t hessianType + ) +{ + if ( ( nV < 1 ) || ( nC < 0 ) ) + return -1; + + if ( ( hessianType < 0 ) || ( hessianType > 6 ) ) + return -1; + + if ( SQProblem_cleanup() != 0 ) + return -1; + + globalSQProblemObject = new SQProblem( nV,nC,(HessianType)hessianType ); + + return 0; +} + + +/* + * S Q P r o b l e m _ i n i t + */ +int_t SQProblem_init( const real_t* const H, + const real_t* const g, + const real_t* const A, + const real_t* const lb, + const real_t* const ub, + const real_t* const lbA, + const real_t* const ubA, + int_t* const nWSR, + real_t* const cputime, + const qpOASES_Options* const options, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ) +{ + /* abort if SQProblem_setup has not been called */ + if ( globalSQProblemObject == 0 ) + return -1; + + /* adjust options if provided */ + if ( options != 0 ) + { + qpOASES_Options_copy( options,&globalOptionsObject ); + globalSQProblemObject->setOptions( globalOptionsObject ); + } + + /* actually call solver */ + returnValue returnvalue = globalSQProblemObject->init( H,g,A,lb,ub,lbA,ubA, *nWSR,cputime ); + + /* assign lhs arguments */ + return qpOASES_obtainOutputs( globalSQProblemObject,returnvalue, x,y,obj,status ); +} + + +/* + * S Q P r o b l e m _ h o t s t a r t + */ +int_t SQProblem_hotstart( const real_t* const H, + const real_t* const g, + const real_t* const A, + const real_t* const lb, + const real_t* const ub, + const real_t* const lbA, + const real_t* const ubA, + int_t* const nWSR, + real_t* const cputime, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ) +{ + /* abort if SQProblem_setup has not been called */ + if ( globalSQProblemObject == 0 ) + return -1; + + /* actually call solver */ + returnValue returnvalue = globalSQProblemObject->hotstart( H,g,A,lb,ub,lbA,ubA, *nWSR,cputime ); + + /* assign lhs arguments */ + return qpOASES_obtainOutputs( globalSQProblemObject,returnvalue, x,y,obj,status ); + + return 0; +} + + +/* + * S Q P r o b l e m _ c l e a n u p + */ +int_t SQProblem_cleanup( ) +{ + if ( globalSQProblemObject != 0 ) + { + delete globalSQProblemObject; + globalSQProblemObject = 0; + } + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/c/qpOASES_wrapper.h b/locomotion/src/third_party/qpOASES/interfaces/c/qpOASES_wrapper.h new file mode 100644 index 0000000..e975523 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/c/qpOASES_wrapper.h @@ -0,0 +1,316 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/c/qpOASES_wrapper.h + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Interface that enables to call qpOASES from plain C. + * + */ + + +#ifndef QPOASES_WRAPPER_H +#define QPOASES_WRAPPER_H + + +#ifndef QPOASES_TYPES_HPP + + /** + * Defined integer type for calling BLAS/LAPACK. Should usually be + * "(unsigned) int", currently set to "(unsigned) long" for backwards + * compatibility. This will change in a future release. + */ + typedef long la_int_t; + typedef unsigned long la_uint_t; + + /** Defines real_t for facilitating switching between double and float. */ + #ifdef __USE_SINGLE_PRECISION__ + typedef float real_t; + #else + typedef double real_t; + #endif /* __USE_SINGLE_PRECISION__ */ + + /** Defines int_t for facilitating switching between int and long int. */ + #ifdef __USE_LONG_INTEGERS__ + typedef long int_t; + typedef unsigned long uint_t; + #else + typedef int int_t; + typedef unsigned int uint_t; + #endif /* __USE_LONG_INTEGERS__ */ + + /** Defines FORTRAN integer type. Might be platform dependent! */ + #ifdef __USE_LONG_FINTS__ + typedef long fint_t; + #else + typedef int fint_t; + #endif /* __USE_LONG_FINTS__ */ + + /** + * Integer type for sparse matrix row/column entries. Make this "int" + * for 32 bit entries, and "long" for 64-bit entries on x86_64 platform. + * + * Most sparse codes still assume 32-bit entries here (HSL, BQPD, ...) + */ + typedef int_t sparse_int_t; + + /* dummy definitions, not used when calling from C */ + #define QProblemBClass int_t + #define OptionsClass int_t + #define returnValue int_t + + /* HessianType */ + #define HST_ZERO 0 + #define HST_IDENTITY 1 + #define HST_POSDEF 2 + #define HST_POSDEF_NULLSPACE 3 + #define HST_SEMIDEF 4 + #define HST_INDEF 5 + #define HST_UNKNOWN 6 + + /* SubjectToStatus */ + #define ST_LOWER -1 + #define ST_INACTIVE 0 + #define ST_UPPER 1 + #define ST_INFEASIBLE_LOWER 2 + #define ST_INFEASIBLE_UPPER 3 + #define ST_UNDEFINED 4 + + /* PrintLevel */ + #define PL_DEBUG_ITER -2 + #define PL_TABULAR -1 + #define PL_NONE 0 + #define PL_LOW 1 + #define PL_MEDIUM 2 + #define PL_HIGH 3 + +#else + + #define QProblemBClass QProblemB + #define OptionsClass REFER_NAMESPACE_QPOASES Options + + /* only declare when compiling C++ library */ + static QProblem* globalQProblemObject = 0; + static QProblemB* globalQProblemBObject = 0; + static SQProblem* globalSQProblemObject = 0; + static Options globalOptionsObject; + +#endif /* QPOASES_TYPES_HPP */ + + + +/** + * \brief Manages all user-specified options for solving QPs. + * + * This struct manages all user-specified options used for solving + * quadratic programs. + * + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + */ +typedef struct +{ + int_t printLevel; /**< Print level. */ + + int_t enableRamping; /**< Specifies whether ramping shall be enabled or not. */ + int_t enableFarBounds; /**< Specifies whether far bounds shall be used or not. */ + int_t enableFlippingBounds; /**< Specifies whether flipping bounds shall be used or not. */ + int_t enableRegularisation; /**< Specifies whether Hessian matrix shall be regularised in case semi-definiteness is detected. */ + int_t enableFullLITests; /**< Specifies whether condition-hardened LI test shall be used or not. */ + int_t enableNZCTests; /**< Specifies whether nonzero curvature tests shall be used. */ + int_t enableDriftCorrection; /**< Specifies the frequency of drift corrections (0 = off). */ + int_t enableCholeskyRefactorisation; /**< Specifies the frequency of full refactorisation of proj. Hessian (otherwise updates). */ + int_t enableEqualities; /**< Specifies whether equalities shall be always treated as active constraints. */ + + real_t terminationTolerance; /**< Termination tolerance. */ + real_t boundTolerance; /**< Lower/upper (constraints') bound tolerance (an inequality constraint whose lower and + upper bounds differ by less is regarded to be an equality constraint). */ + real_t boundRelaxation; /**< Offset for relaxing (constraints') bounds at beginning of an initial homotopy. It is also as initial value for far bounds. */ + real_t epsNum; /**< Numerator tolerance for ratio tests. */ + real_t epsDen; /**< Denominator tolerance for ratio tests. */ + real_t maxPrimalJump; /**< Maximum allowed jump in primal variables in nonzero curvature tests. */ + real_t maxDualJump; /**< Maximum allowed jump in dual variables in linear independence tests. */ + + real_t initialRamping; /**< Start value for Ramping Strategy. */ + real_t finalRamping; /**< Final value for Ramping Strategy. */ + real_t initialFarBounds; /**< Initial size of Far Bounds. */ + real_t growFarBounds; /**< Factor to grow Far Bounds. */ + int_t initialStatusBounds; /**< Initial status of bounds at first iteration. */ + real_t epsFlipping; /**< Tolerance of squared Cholesky diagonal factor which triggers flipping bound. */ + int_t numRegularisationSteps; /**< Maximum number of successive regularisation steps. */ + real_t epsRegularisation; /**< Scaling factor of identity matrix used for Hessian regularisation. */ + int_t numRefinementSteps; /**< Maximum number of iterative refinement steps. */ + real_t epsIterRef; /**< Early termination tolerance for iterative refinement. */ + real_t epsLITests; /**< Tolerance for linear independence tests. */ + real_t epsNZCTests; /**< Tolerance for nonzero curvature tests. */ + + real_t rcondSMin; /**< Minimum reciprocal condition number of S before refactorization is triggered */ + int_t enableInertiaCorrection; /**< Specifies whether the working set should be repaired when negative curvature is discovered during hotstart. */ + + int_t enableDropInfeasibles; /**< ... */ + int_t dropBoundPriority; /**< ... */ + int_t dropEqConPriority; /**< ... */ + int_t dropIneqConPriority; /**< ... */ + int_t printResiduals; /**< If true, it will print the internal qpOASES residuals and other information per iteration */ + +} qpOASES_Options; + + +int_t qpOASES_Options_init( qpOASES_Options* const options, + int_t mode + ); + +int_t qpOASES_Options_copy( const qpOASES_Options* const from, + OptionsClass* const to + ); + + +int_t qpOASES_obtainOutputs( const QProblemBClass* const globalQpObject, + returnValue returnvalue, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ); + + +int_t QProblem_setup( int_t nV, + int_t nC, + int_t hessianType + ); + +int_t QProblem_init( const real_t* const H, + const real_t* const g, + const real_t* const A, + const real_t* const lb, + const real_t* const ub, + const real_t* const lbA, + const real_t* const ubA, + int_t* const nWSR, + real_t* const cputime, + const qpOASES_Options* const options, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ); + +int_t QProblem_hotstart( const real_t* const g, + const real_t* const lb, + const real_t* const ub, + const real_t* const lbA, + const real_t* const ubA, + int_t* const nWSR, + real_t* const cputime, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ); + +int_t QProblem_cleanup( ); + + + +int_t QProblemB_setup( int_t nV, + int_t hessianType + ); + +int_t QProblemB_init( const real_t* const H, + const real_t* const g, + const real_t* const lb, + const real_t* const ub, + int_t* const nWSR, + real_t* const cputime, + const qpOASES_Options* const options, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ); + +int_t QProblemB_hotstart( const real_t* const g, + const real_t* const lb, + const real_t* const ub, + int_t* const nWSR, + real_t* const cputime, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ); + +int_t QProblemB_cleanup( ); + + + +int_t SQProblem_setup( int_t nV, + int_t nC, + int_t hessianType + ); + +int_t SQProblem_init( const real_t* const H, + const real_t* const g, + const real_t* const A, + const real_t* const lb, + const real_t* const ub, + const real_t* const lbA, + const real_t* const ubA, + int_t* const nWSR, + real_t* const cputime, + const qpOASES_Options* const options, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ); + +int_t SQProblem_hotstart( const real_t* const H, + const real_t* const g, + const real_t* const A, + const real_t* const lb, + const real_t* const ub, + const real_t* const lbA, + const real_t* const ubA, + int_t* const nWSR, + real_t* const cputime, + real_t* const x, + real_t* const y, + real_t* const obj, + int_t* const status + ); + +int_t SQProblem_cleanup( ); + + +#endif /* QPOASES_WRAPPER_H */ + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/Makefile b/locomotion/src/third_party/qpOASES/interfaces/matlab/Makefile new file mode 100644 index 0000000..9371ab0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/Makefile @@ -0,0 +1,85 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: src/interfaces/matlab/Makefile +## Author: Christian Kirches, Hans Joachim Ferreau, Andreas Potschka +## Version: 3.2 +## Date: 2007-2017 +## + +include ../../make.mk + +## +## flags +## + +IDIR = ../../include + +IFLAGS = -I. \ + -I${IDIR} \ + -I${MATLAB_IDIR} + +LINK_MATLAB_LIBS = -L${MATLAB_LIBDIR} -lmex -lmat -lmx + +EXTRAFLAGS = -largeArrayDims -O -D__cpluplus -D__MATLAB__ -fexceptions + +QPOASES_OBJECT = qpOASES.${OBJEXT} +QPOASES_SEQUENCE_OBJECT = qpOASES_sequence.${OBJEXT} + +## +## targets +## + +all: ${BINDIR}/qpOASES.${MEXEXT} ${BINDIR}/qpOASES_sequence.${MEXEXT} copyMs + +${BINDIR}/qpOASES.${MEXEXT}: ${QPOASES_OBJECT} + @${ECHO} "Creating" $@ + @${CPP} -shared -o $@ $? ${QPOASES_LINK} ${LINK_LIBRARIES} ${LINK_MATLAB_LIBS} + +${BINDIR}/qpOASES_sequence.${MEXEXT}: ${QPOASES_SEQUENCE_OBJECT} + @${ECHO} "Creating" $@ + @${CPP} -shared -o $@ $? ${QPOASES_LINK} ${LINK_LIBRARIES} ${LINK_MATLAB_LIBS} + +copyMs: + @${ECHO} "Copying M files ..." + @${CP} qpOASES.m ${BINDIR} + @${CP} qpOASES_options.m ${BINDIR} + @${CP} qpOASES_sequence.m ${BINDIR} + +#@${CP} qpOASES_sequenceVM.m ${BINDIR} + +clean: + @${RM} -f *.${OBJEXT} *.mex* + +clobber: clean + +%.${OBJEXT}: %.cpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} -c ${IFLAGS} ${EXTRAFLAGS} ${CPPFLAGS} $< + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/example1.mat b/locomotion/src/third_party/qpOASES/interfaces/matlab/example1.mat new file mode 100644 index 0000000000000000000000000000000000000000..c0bd0d2ed4364ebaf2b16eeb1791b99510164d60 GIT binary patch literal 790 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQgHY2i?A@$QE)CwO)N=GQOM7; zQV7W?Rq#(PQBW{ZFtoHXwy-iZQZOA%wc4c5GZW8!2gYzq2v=QA4sbvTq}xwN{M9( rdcH+H=e>2)6PUUhjxboKF`MIYAV|YGPpF2pgrpzeL4oIZl~o4-!Xx*U literal 0 HcmV?d00001 diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/example1a.mat b/locomotion/src/third_party/qpOASES/interfaces/matlab/example1a.mat new file mode 100644 index 0000000000000000000000000000000000000000..48c784fcb7c53eedc3b3124e3577f8d0822e1cb2 GIT binary patch literal 896 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQgHY2i?A@$QE)CwO)N=GQOM7; zQV7W?Rq#(PQBW{ZFtoHXwzM)dRWLFzFjpWIFfe-h@-r|n=m2rWoX5!t2^A%wc4c5GZW8!2gYzq2v=QA4sbvTq}xwN{M9( zdcH+H=e>2)6PUUhjxboKF`MIYAV|YGPpF2pgrpzeL4oIZl~o6%$pCIk2ePk#sWRk@ zvYq}`8INM7jZDluH5=M5@Ec?>oIk~G0n(=h*N5UdV9K1r)@ga{`O<04M`r+2CliB_ HDN`x{YE&BX literal 0 HcmV?d00001 diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/example1b.mat b/locomotion/src/third_party/qpOASES/interfaces/matlab/example1b.mat new file mode 100644 index 0000000000000000000000000000000000000000..b45b4f74c6a935c350dac6de0673396f20801338 GIT binary patch literal 549 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQgHY2i?A@$QE)CwO)N=GQOM7; zQV7W?Rq#(PQBW{ZFtoHXwy-iXRWLFzFjpWIFfe-h@-r|n=m2rWoX5!t2^Gx%BvR z(CJ1KbpdXJ0|(fvIsP7&V$n literal 0 HcmV?d00001 diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/make.m b/locomotion/src/third_party/qpOASES/interfaces/matlab/make.m new file mode 100644 index 0000000..37c02c2 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/make.m @@ -0,0 +1,254 @@ +function [] = make( varargin ) +%MAKE Compiles the Matlab interface of qpOASES. +% +%Type make to compile all interfaces that +% have been modified, +%type make clean to delete all compiled interfaces, +%type make clean all to first delete and then compile +% all interfaces, +%type make 'name' to compile only the interface with +% the given name (if it has been modified), +%type make 'opt' to compile all interfaces using the +% given compiler options. +% +%Copyright (C) 2013-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. + +%% +%% This file is part of qpOASES. +%% +%% qpOASES -- An Implementation of the Online Active Set Strategy. +%% Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%% Christian Kirches et al. All rights reserved. +%% +%% qpOASES is free software; you can redistribute it and/or +%% modify it under the terms of the GNU Lesser General Public +%% License as published by the Free Software Foundation; either +%% version 2.1 of the License, or (at your option) any later version. +%% +%% qpOASES is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%% See the GNU Lesser General Public License for more details. +%% +%% You should have received a copy of the GNU Lesser General Public +%% License along with qpOASES; if not, write to the Free Software +%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +%% + +%% +%% Filename: interfaces/matlab/make.m +%% Author: Hans Joachim Ferreau, Andreas Potschka, Christian Kirches +%% Version: 3.2 +%% Date: 2007-2017 +%% + + + %% consistency check + if ( exist( [pwd, '/make.m'],'file' ) == 0 ) + error( ['ERROR (',mfilename '.m): Run this make script directly within the directory ', ... + '/interfaces/matlab, please.'] ); + end + + + if ( nargin > 2 ) + error( ['ERROR (',mfilename '.m): At most two make arguments supported!'] ); + else + [ doClean,fcnNames,userFlags ] = analyseMakeArguments( nargin,varargin ); + end + + + %% define compiler settings + QPOASESPATH = '../../'; + + DEBUGFLAGS = ' '; + %DEBUGFLAGS = ' -v -g CXXDEBUGFLAGS=''$CXXDEBUGFLAGS -Wall -pedantic -Wshadow'' '; + + IFLAGS = [ '-I. -I',QPOASESPATH,'include',' -I',QPOASESPATH,'src',' ' ]; + CPPFLAGS = [ IFLAGS, DEBUGFLAGS, '-largeArrayDims -D__cpluplus -D__MATLAB__ -D__AVOID_LA_NAMING_CONFLICTS__ -D__SINGLE_OBJECT__',' ' ]; + defaultFlags = '-O -D__NO_COPYRIGHT__ '; %% -D__SUPPRESSANYOUTPUT__ + + if ( ispc() == 0 ) + CPPFLAGS = [ CPPFLAGS, '-DLINUX -lmwblas',' ' ]; + else + CPPFLAGS = [ CPPFLAGS, '-DWIN32',' ' ]; + end + + if ( isempty(userFlags) > 0 ) + CPPFLAGS = [ CPPFLAGS, defaultFlags,' ' ]; + else + CPPFLAGS = [ CPPFLAGS, userFlags,' ' ]; + end + + %% determine if MA57 is available for sparse linear algebra + isoctave = exist('OCTAVE_VERSION', 'builtin') ~= 0; + if isoctave + warning('Sparse linear algebra is currently not available for qpOASES in Octave. Passing sparse matrices works but will likely be slow.') + SPARSEFLAGS = ''; + elseif verLessThan('matlab', '7.8') + warning('Sparse linear algebra is currently available for qpOASES only for Matlab versions 7.8 and later. Passing sparse matrices works but will likely be slow.') + SPARSEFLAGS = ''; + else + if ( ispc() == 0 ) + SPARSEFLAGS = '-largeArrayDims -D__USE_LONG_INTEGERS__ -D__USE_LONG_FINTS__ -DSOLVER_MA57 -lmwma57 '; + else + SPARSEFLAGS = '-largeArrayDims -D__USE_LONG_INTEGERS__ -D__USE_LONG_FINTS__ '; + end + end + + mexExt = eval('mexext'); + + + %% ensure copyright notice is displayed + if ~isempty( strfind( CPPFLAGS,'-D__NO_COPYRIGHT__' ) ) + printCopyrightNotice( ); + end + + + %% clean if desired + if ( doClean > 0 ) + + eval( 'delete *.o;' ); + eval( ['delete *.',mexExt,'*;'] ); + disp( [ 'INFO (',mfilename '.m): Cleaned all compiled files.'] ); + pause( 0.2 ); + + end + + + if ( ~isempty(userFlags) ) + disp( [ 'INFO (',mfilename '.m): Compiling all files with user-defined compiler flags (''',userFlags,''')...'] ); + end + + + %% call mex compiler + for ii=1:length(fcnNames) + + cmd = [ 'mex -output ', fcnNames{ii}, ' ', CPPFLAGS, SPARSEFLAGS, [fcnNames{ii},'.cpp'] ]; + + if ( exist( [fcnNames{ii},'.',mexExt],'file' ) == 0 ) + + eval( cmd ); + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' successfully created.'] ); + + else + + % check modification time of source/Make files and compiled mex file + cppFile = dir( [pwd,'/',fcnNames{ii},'.cpp'] ); + cppFileTimestamp = getTimestamp( cppFile ); + + utilsFile = dir( [pwd,'/qpOASES_matlab_utils.cpp'] ); + utilsFileTimestamp = getTimestamp( utilsFile ); + + makeFile = dir( [pwd,'/make.m'] ); + makeFileTimestamp = getTimestamp( makeFile ); + + mexFile = dir( [pwd,'/',fcnNames{ii},'.',mexExt] ); + if ( isempty(mexFile) == 0 ) + mexFileTimestamp = getTimestamp( mexFile ); + else + mexFileTimestamp = 0; + end + + if ( ( cppFileTimestamp >= mexFileTimestamp ) || ... + ( utilsFileTimestamp >= mexFileTimestamp ) || ... + ( makeFileTimestamp >= mexFileTimestamp ) ) + eval( cmd ); + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' successfully created.'] ); + else + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' already exists.'] ); + end + + end + + end + + %% add qpOASES directory to path + path( path,pwd ); + +end + + +function [ doClean,fcnNames,userIFlags ] = analyseMakeArguments( nArgs,args ) + + doClean = 0; + fcnNames = []; + userIFlags = []; + + switch ( nArgs ) + + case 1 + if ( strcmp( args{1},'all' ) > 0 ) + fcnNames = { 'qpOASES','qpOASES_sequence' }; + elseif ( strcmp( args{1},'qpOASES' ) > 0 ) + fcnNames = { 'qpOASES' }; + elseif ( strcmp( args{1},'qpOASES_sequence' ) > 0 ) + fcnNames = { 'qpOASES_sequence' }; + elseif ( strcmp( args{1},'clean' ) > 0 ) + doClean = 1; + elseif ( strcmp( args{1}(1),'-' ) > 0 ) + % make clean all with user-specified compiler flags + userIFlags = args{1}; + doClean = 1; + fcnNames = { 'qpOASES','qpOASES_sequence' }; + else + error( ['ERROR (',mfilename '.m): Invalid first argument (''',args{1},''')!'] ); + end + + case 2 + if ( strcmp( args{1},'clean' ) > 0 ) + doClean = 1; + else + error( ['ERROR (',mfilename '.m): First argument must be ''clean'' if two arguments are provided!'] ); + end + + if ( strcmp( args{2},'all' ) > 0 ) + fcnNames = { 'qpOASES','qpOASES_sequence' }; + elseif ( strcmp( args{2},'qpOASES' ) > 0 ) + fcnNames = { 'qpOASES' }; + elseif ( strcmp( args{2},'qpOASES_sequence' ) > 0 ) + fcnNames = { 'qpOASES_sequence' }; + else + error( ['ERROR (',mfilename '.m): Invalid second argument (''',args{2},''')!'] ); + end + + otherwise + fcnNames = { 'qpOASES','qpOASES_sequence' }; + + end + +end + + +function [ timestamp ] = getTimestamp( dateString ) + + try + timestamp = dateString.datenum; + catch + timestamp = Inf; + end + +end + + +function [ ] = printCopyrightNotice( ) + + disp( ' ' ); + disp( 'qpOASES -- An Implementation of the Online Active Set Strategy.' ); + disp( 'Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka,' ); + disp( 'Christian Kirches et al. All rights reserved.' ); + disp( ' ' ); + disp( 'qpOASES is distributed under the terms of the' ); + disp( 'GNU Lesser General Public License 2.1 in the hope that it will be' ); + disp( 'useful, but WITHOUT ANY WARRANTY; without even the implied warranty' ); + disp( 'of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.' ); + disp( 'See the GNU Lesser General Public License for more details.' ); + disp( ' ' ); + disp( ' ' ); + +end + + +%% +%% end of file +%% diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES.cpp b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES.cpp new file mode 100644 index 0000000..5c5274f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES.cpp @@ -0,0 +1,608 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/matlab/qpOASES.cpp + * \author Hans Joachim Ferreau, Alexander Buchner (thanks to Aude Perrin) + * \version 3.2 + * \date 2007-2017 + * + * Interface for Matlab(R) that enables to call qpOASES as a MEX function. + * + */ + + +#include + + +USING_NAMESPACE_QPOASES + +#include "qpOASES_matlab_utils.hpp" + +/** initialise handle counter of QPInstance class */ +int_t QPInstance::s_nexthandle = 1; + +/** global pointer to QP objects */ +static std::vector g_instances; + +#include "qpOASES_matlab_utils.cpp" + + +/* + * Q P r o b l e m _ q p O A S E S + */ +int_t QProblem_qpOASES( int_t nV, int_t nC, HessianType hessianType, int_t nP, + SymmetricMatrix* H, double* g, Matrix* A, + double* lb, double* ub, + double* lbA, double* ubA, + int_t nWSRin, real_t maxCpuTimeIn, + const double* const x0, Options* options, + int_t nOutputs, mxArray* plhs[], + const double* const guessedBounds, const double* const guessedConstraints, + const double* const _R, + BooleanType isSparse + ) +{ + int_t nWSRout; + real_t maxCpuTimeOut; + + /* 1) Setup initial QP. */ + QProblem *QP; + if ( isSparse == BT_TRUE ) + { + #ifdef SOLVER_MA57 + QP = new SQProblemSchur ( nV,nC,hessianType ); + #else + QP = new QProblem ( nV,nC,hessianType ); + #endif + } + else + QP = new QProblem ( nV,nC,hessianType ); + QP->setOptions( *options ); + + /* 2) Solve initial QP. */ + returnValue returnvalue; + + Bounds bounds(nV); + Constraints constraints(nC); + if (guessedBounds != 0) { + for (int_t i = 0; i < nV; i++) { + if ( isEqual(guessedBounds[i],-1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_LOWER); + } else if ( isEqual(guessedBounds[i],1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_UPPER); + } else if ( isEqual(guessedBounds[i],0.0) == BT_TRUE ) { + bounds.setupBound(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of bounds!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + if (guessedConstraints != 0) { + for (int_t i = 0; i < nC; i++) { + if ( isEqual(guessedConstraints[i],-1.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_LOWER); + } else if ( isEqual(guessedConstraints[i],1.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_UPPER); + } else if ( isEqual(guessedConstraints[i],0.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of constraints!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + nWSRout = nWSRin; + maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + returnvalue = QP->init( H,g,A,lb,ub,lbA,ubA, + nWSRout,&maxCpuTimeOut, + x0,0, + (guessedBounds != 0) ? &bounds : 0, (guessedConstraints != 0) ? &constraints : 0, + _R + ); + + /* 3) Solve remaining QPs and assign lhs arguments. */ + /* Set up pointers to the current QP vectors */ + real_t* g_current = g; + real_t* lb_current = lb; + real_t* ub_current = ub; + real_t* lbA_current = lbA; + real_t* ubA_current = ubA; + + /* Loop through QP sequence. */ + for ( int_t k=0; k 0 ) + { + /* update pointers to the current QP vectors */ + g_current = &(g[k*nV]); + if ( lb != 0 ) + lb_current = &(lb[k*nV]); + if ( ub != 0 ) + ub_current = &(ub[k*nV]); + if ( lbA != 0 ) + lbA_current = &(lbA[k*nC]); + if ( ubA != 0 ) + ubA_current = &(ubA[k*nC]); + + nWSRout = nWSRin; + maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + returnvalue = QP->hotstart( g_current,lb_current,ub_current,lbA_current,ubA_current, nWSRout,&maxCpuTimeOut ); + } + + /* write results into output vectors */ + obtainOutputs( k,QP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,nC ); + } + + //QP->writeQpDataIntoMatFile( "qpDataMat0.mat" ); + + delete QP; + return 0; +} + + + +/* + * Q P r o b l e m B _ q p O A S E S + */ +int_t QProblemB_qpOASES( int_t nV, HessianType hessianType, int_t nP, + SymmetricMatrix *H, double* g, + double* lb, double* ub, + int_t nWSRin, real_t maxCpuTimeIn, + const double* const x0, Options* options, + int_t nOutputs, mxArray* plhs[], + const double* const guessedBounds, + const double* const _R + ) +{ + int_t nWSRout; + real_t maxCpuTimeOut; + + /* 1) Setup initial QP. */ + QProblemB QP( nV,hessianType ); + QP.setOptions( *options ); + + /* 2) Solve initial QP. */ + returnValue returnvalue; + + Bounds bounds(nV); + if (guessedBounds != 0) { + for (int_t i = 0; i < nV; i++) { + if ( isEqual(guessedBounds[i],-1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_LOWER); + } else if ( isEqual(guessedBounds[i],1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_UPPER); + } else if ( isEqual(guessedBounds[i],0.0) == BT_TRUE ) { + bounds.setupBound(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of bounds!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + nWSRout = nWSRin; + maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + returnvalue = QP.init( H,g,lb,ub, + nWSRout,&maxCpuTimeOut, + x0,0, + (guessedBounds != 0) ? &bounds : 0, + _R + ); + + /* 3) Solve remaining QPs and assign lhs arguments. */ + /* Set up pointers to the current QP vectors */ + real_t* g_current = g; + real_t* lb_current = lb; + real_t* ub_current = ub; + + /* Loop through QP sequence. */ + for ( int_t k=0; k 0 ) + { + /* update pointers to the current QP vectors */ + g_current = &(g[k*nV]); + if ( lb != 0 ) + lb_current = &(lb[k*nV]); + if ( ub != 0 ) + ub_current = &(ub[k*nV]); + + nWSRout = nWSRin; + maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + returnvalue = QP.hotstart( g_current,lb_current,ub_current, nWSRout,&maxCpuTimeOut ); + } + + /* write results into output vectors */ + obtainOutputs( k,&QP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV ); + } + + return 0; +} + + + +/* + * m e x F u n c t i o n + */ +void mexFunction( int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[] ) +{ + /* inputs */ + SymmetricMatrix *H=0; + Matrix *A=0; + + real_t *g=0, *lb=0, *ub=0, *lbA=0, *ubA=0; + HessianType hessianType = HST_UNKNOWN; + double *x0=0, *R=0, *R_for=0; + double *guessedBounds=0, *guessedConstraints=0; + + int H_idx=-1, g_idx=-1, A_idx=-1, lb_idx=-1, ub_idx=-1, lbA_idx=-1, ubA_idx=-1; + int options_idx=-1, x0_idx=-1, auxInput_idx=-1; + + /* Setup default options */ + Options options; + options.printLevel = PL_LOW; + #ifdef __DEBUG__ + options.printLevel = PL_HIGH; + #endif + #ifdef __SUPPRESSANYOUTPUT__ + options.printLevel = PL_NONE; + #endif + + /* dimensions */ + uint_t nV=0, nC=0, nP=0; + BooleanType isSimplyBoundedQp = BT_FALSE; + #ifdef SOLVER_MA57 + BooleanType isSparse = BT_TRUE; // This will be set to BT_FALSE later if a dense matrix is encountered. + #else + BooleanType isSparse = BT_FALSE; + #endif + + /* sparse matrix indices and values */ + sparse_int_t *Hir=0, *Hjc=0, *Air=0, *Ajc=0; + real_t *Hv=0, *Av=0; + + /* I) CONSISTENCY CHECKS: */ + /* 1a) Ensure that qpOASES is called with a feasible number of input arguments. */ + if ( ( nrhs < 4 ) || ( nrhs > 9 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES' for further information." ); + return; + } + + /* 2) Check for proper number of output arguments. */ + if ( nlhs > 6 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): At most six output arguments are allowed: \n [x,fval,exitflag,iter,lambda,auxOutput]!" ); + return; + } + if ( nlhs < 1 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): At least one output argument is required: [x,...]!" ); + return; + } + + + /* II) PREPARE RESPECTIVE QPOASES FUNCTION CALL: */ + /* Choose between QProblem and QProblemB object and assign the corresponding + * indices of the input pointer array in to order to access QP data correctly. */ + g_idx = 1; + + if ( mxIsEmpty(prhs[0]) == 1 ) + { + H_idx = -1; + nV = (int_t)mxGetM( prhs[ g_idx ] ); /* if Hessian is empty, row number of gradient vector */ + } + else + { + H_idx = 0; + nV = (int_t)mxGetM( prhs[ H_idx ] ); /* row number of Hessian matrix */ + } + + nP = (int_t)mxGetN( prhs[ g_idx ] ); /* number of columns of the gradient matrix (vectors series have to be stored columnwise!) */ + + if ( nrhs <= 6 ) + isSimplyBoundedQp = BT_TRUE; + else + isSimplyBoundedQp = BT_FALSE; + + + /* 0) Check whether options are specified .*/ + if ( isSimplyBoundedQp == BT_TRUE ) + { + if ( ( nrhs >= 5 ) && ( !mxIsEmpty(prhs[4]) ) && ( mxIsStruct(prhs[4]) ) ) + options_idx = 4; + } + else + { + /* Consistency check */ + if ( ( !mxIsEmpty(prhs[4]) ) && ( mxIsStruct(prhs[4]) ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Fifth input argument must not be a struct when solving QP with general constraints!\nType 'help qpOASES' for further information." ); + return; + } + + if ( ( nrhs >= 8 ) && ( !mxIsEmpty(prhs[7]) ) && ( mxIsStruct(prhs[7]) ) ) + options_idx = 7; + } + + // Is the third argument constraint Matrix A? + int_t numberOfColumns = (int_t)mxGetN(prhs[2]); + + /* 1) Simply bounded QP. */ + if ( ( isSimplyBoundedQp == BT_TRUE ) || + ( ( numberOfColumns == 1 ) && ( nV != 1 ) ) ) + { + lb_idx = 2; + ub_idx = 3; + + if ( ( nrhs >= 6 ) && ( !mxIsEmpty(prhs[5]) ) ) + { + /* auxInput specified */ + if ( mxIsStruct(prhs[5]) ) + { + auxInput_idx = 5; + x0_idx = -1; + } + else + { + auxInput_idx = -1; + x0_idx = 5; + } + } + else + { + auxInput_idx = -1; + x0_idx = -1; + } + } + else + { + A_idx = 2; + + /* If constraint matrix is empty, use a QProblemB object! */ + if ( mxIsEmpty( prhs[ A_idx ] ) ) + { + lb_idx = 3; + ub_idx = 4; + + nC = 0; + } + else + { + lb_idx = 3; + ub_idx = 4; + lbA_idx = 5; + ubA_idx = 6; + + nC = (int_t)mxGetM( prhs[ A_idx ] ); /* row number of constraint matrix */ + } + + if ( ( nrhs >= 9 ) && ( !mxIsEmpty(prhs[8]) ) ) + { + /* auxInput specified */ + if ( mxIsStruct(prhs[8]) ) + { + auxInput_idx = 8; + x0_idx = -1; + } + else + { + auxInput_idx = -1; + x0_idx = 8; + } + } + else + { + auxInput_idx = -1; + x0_idx = -1; + } + } + + + /* ensure that data is given in real_t precision */ + if ( ( ( H_idx >= 0 ) && ( mxIsDouble( prhs[ H_idx ] ) == 0 ) ) || + ( mxIsDouble( prhs[ g_idx ] ) == 0 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in double precision!" ); + return; + } + + /* check if supplied data contains 'NaN' or 'Inf' */ + if (containsNaNorInf( prhs,H_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,g_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + /* Check inputs dimensions and assign pointers to inputs. */ + if ( ( H_idx >= 0 ) && ( ( mxGetN( prhs[ H_idx ] ) != nV ) || ( mxGetM( prhs[ H_idx ] ) != nV ) ) ) + { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Hessian matrix dimension mismatch (%ld != %d)!", + (long int)mxGetN(prhs[H_idx]), (int)nV); + myMexErrMsgTxt(msg); + return; + } + + if ( nC > 0 ) + { + /* ensure that data is given in real_t precision */ + if ( mxIsDouble( prhs[ A_idx ] ) == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in real_t precision!" ); + return; + } + + /* Check inputs dimensions and assign pointers to inputs. */ + if ( mxGetN( prhs[ A_idx ] ) != nV ) + { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Constraint matrix input dimension mismatch (%ld != %d)!", + (long int)mxGetN(prhs[A_idx]), (int)nV); + myMexErrMsgTxt(msg); + return; + } + + if (containsNaNorInf(prhs,A_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf(prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf(prhs,ubA_idx, 1 ) == BT_TRUE) + return; + } + + /* check dimensions and copy auxInputs */ + if ( smartDimensionCheck( &g,nV,nP, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,nP, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,nP, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &x0,nV,1, BT_TRUE,prhs,x0_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( nC > 0 ) + { + if ( smartDimensionCheck( &lbA,nC,nP, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,nP, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + } + + if ( auxInput_idx >= 0 ) + setupAuxiliaryInputs( prhs[auxInput_idx],nV,nC, &hessianType,&x0,&guessedBounds,&guessedConstraints,&R_for ); + + /* convert Cholesky factor to C storage format */ + if ( R_for != 0 ) + { + R = new real_t[nV*nV]; + convertFortranToC( R_for, nV,nV, R ); + } + + /* III) ACTUALLY PERFORM QPOASES FUNCTION CALL: */ + int_t nWSRin = 5*(nV+nC); + real_t maxCpuTimeIn = -1.0; + + if ( options_idx > 0 ) + setupOptions( &options,prhs[options_idx],nWSRin,maxCpuTimeIn ); + + /* make a deep-copy of the user-specified Hessian matrix (possibly sparse) */ + if ( H_idx >= 0 ) + setupHessianMatrix( prhs[H_idx],nV, &H,&Hir,&Hjc,&Hv ); + + /* make a deep-copy of the user-specified constraint matrix (possibly sparse) */ + if ( ( nC > 0 ) && ( A_idx >= 0 ) ) + setupConstraintMatrix( prhs[A_idx],nV,nC, &A,&Air,&Ajc,&Av ); + + allocateOutputs( nlhs,plhs,nV,nC,nP ); + + /* check if QP is sparse */ + if ( H_idx >= 0 && !mxIsSparse( prhs[H_idx] ) ) + isSparse = BT_FALSE; + if ( nC > 0 && A_idx >= 0 && !mxIsSparse( prhs[A_idx] ) ) + isSparse = BT_FALSE; + + if ( nC == 0 ) + { + /* Call qpOASES (using QProblemB class). */ + QProblemB_qpOASES( nV,hessianType, nP, + H,g, + lb,ub, + nWSRin,maxCpuTimeIn, + x0,&options, + nlhs,plhs, + guessedBounds,R + ); + + if (R != 0) delete R; + if (H != 0) delete H; + if (Hv != 0) delete[] Hv; + if (Hjc != 0) delete[] Hjc; + if (Hir != 0) delete[] Hir; + return; + } + else + { + if ( A == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Internal interface error related to constraint matrix!" ); + return; + } + + /* Call qpOASES (using QProblem class). */ + QProblem_qpOASES( nV,nC,hessianType, nP, + H,g,A, + lb,ub,lbA,ubA, + nWSRin,maxCpuTimeIn, + x0,&options, + nlhs,plhs, + guessedBounds,guessedConstraints,R, + isSparse + ); + + if (R != 0) delete R; + if (A != 0) delete A; + if (H != 0) delete H; + if (Av != 0) delete[] Av; + if (Ajc != 0) delete[] Ajc; + if (Air != 0) delete[] Air; + if (Hv != 0) delete[] Hv; + if (Hjc != 0) delete[] Hjc; + if (Hir != 0) delete[] Hir; + return; + } +} + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES.m b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES.m new file mode 100644 index 0000000..88f4df9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES.m @@ -0,0 +1,75 @@ +%qpOASES -- An Implementation of the Online Active Set Strategy. +%Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. +% +%qpOASES is distributed under the terms of the +%GNU Lesser General Public License 2.1 in the hope that it will be +%useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%See the GNU Lesser General Public License for more details. +% +%--------------------------------------------------------------------------------- +% +%qpOASES solves (a series) of quadratic programming (QP) problems of the +%following form: +% +% min 1/2*x'Hx + x'g +% s.t. lb <= x <= ub +% lbA <= Ax <= ubA {optional} +% +%Call +% +% [x,fval,exitflag,iter,lambda,auxOutput] = +% qpOASES( H,g,A,lb,ub,lbA,ubA{,options{,auxInput}} ) +% +%for solving the above-mentioned QP. H must be a symmetric (but possibly +%indefinite) matrix and all vectors g, lb, ub, lbA, ubA have to be given +%as column vectors. Options can be generated using the qpOASES_options command, +%otherwise default values are used. Optionally, further auxiliary inputs +%may be generated using qpOASES_auxInput command and passed to the solver. +%Both matrices H or A may be passed in sparse matrix format. +% +%Call +% +% [x,fval,exitflag,iter,lambda,auxOutput] = +% qpOASES( H,g,lb,ub{,options{,auxInput}} ) +% +%for solving the above-mentioned QP without general constraints. +% +% +%Optional outputs (only x is mandatory): +% x - Optimal primal solution vector (if exitflag==0). +% fval - Optimal objective function value (if exitflag==0). +% exitflag - 0: QP problem solved, +% 1: QP could not be solved within given number of iterations, +% -1: QP could not be solved due to an internal error, +% -2: QP is infeasible (and thus could not be solved), +% -3: QP is unbounded (and thus could not be solved). +% iter - Number of active set iterations actually performed. +% lambda - Optimal dual solution vector (if exitflag==0). +% auxOutput - Struct containing auxiliary outputs as described below. +% +%The auxOutput struct contains the following entries: +% workingSetB - Working set of bounds at point x. +% workingSetC - Working set of constraints at point x. +% The working set is a subset of the active set (indices +% of bounds/constraints that hold with equality) yielding +% a set linearly independent of bounds/constraints. +% The working sets are encoded as follows: +% 1: bound/constraint at its upper bound +% 0: bound/constraint not at any bound +% -1: bound/constraint at its lower bound +% cpuTime - Internally measured CPU time for solving QP problem. +% +% +%If not a single QP but a sequence of QPs with varying vectors is to be solved, +%the i-th QP is given by the i-th columns of the QP vectors g, lb, ub, lbA, ubA +%(i.e. they are matrices in this case). Both matrices H and A remain constant. +% +%See also QPOASES_OPTIONS, QPOASES_AUXINPUT, QPOASES_SEQUENCE +% +% +%For additional information see the qpOASES User's Manual or +%visit http://www.qpOASES.org/. +% +%Please send remarks and questions to support@qpOASES.org! diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_auxInput.m b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_auxInput.m new file mode 100644 index 0000000..1ebb8d9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_auxInput.m @@ -0,0 +1,118 @@ +%qpOASES -- An Implementation of the Online Active Set Strategy. +%Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. +% +%qpOASES is distributed under the terms of the +%GNU Lesser General Public License 2.1 in the hope that it will be +%useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%See the GNU Lesser General Public License for more details. +% +%--------------------------------------------------------------------------------- +% +%Returns a struct containing all possible auxiliary inputs to be passed +%to qpOASES. +% +%Call +% auxInput = qpOASES_auxInput(); +%to obtain a struct with all auxiliary inputs empty. +% +%Call +% auxInput = qpOASES_auxInput( 'input1',value1,'input2',value2,... ) +%to obtain a struct with 'input1' set to value1 etc. and all remaining +%auxiliary inputs empty. +% +%Call +% auxInput = qpOASES_auxInput( oldInputs,'input1',value1,... ) +%to obtain a copy of the options struct oldInputs but with 'input1' set to +%value1 etc. +% +% +%qpOASES features the following auxiliary inputs: +% hessianType - Provide information on Hessian matrix: +% 0: Hessian is zero matrix (i.e. LP formulation) +% 1: Hessian is identity matrix +% 2: Hessian is (strictly) positive definite +% 3: Hessian is positive definite on null space +% of active bounds/constraints +% 4: Hessian is positive semi-definite. +% 5: Hessian is indefinite +% Leave hessianType empty if Hessian type is unknown. +% x0 - Initial guess for optimal primal solution. +% guessedWorkingSetB - Initial guess for working set of bounds at +% optimal solution (nV elements or empty). +% guessedWorkingSetC - Initial guess for working set of constraints at +% optimal solution (nC elements or empty). +% The working sets needs to be encoded as follows: +% 1: bound/constraint at its upper bound +% 0: bound/constraint not at any bound +% -1: bound/constraint at its lower bound +% R - Cholesky factor of Hessian matrix (upper-triangular); +% only used if both guessedWorkingSets are empty +% and option initialStatusBounds is set to 0. +% +% +%See also QPOASES, QPOASES_SEQUENCE, QPOASES_OPTIONS +% +% +%For additional information see the qpOASES User's Manual or +%visit http://www.qpOASES.org/. +% +%Please send remarks and questions to support@qpOASES.org! +function [ auxInput ] = qpOASES_auxInput( varargin ) + + firstIsStruct = 0; + + if ( nargin == 0 ) + auxInput = qpOASES_emptyAuxInput(); + else + if ( isstruct( varargin{1} ) ) + if ( mod( nargin,2 ) ~= 1 ) + error('ERROR (qpOASES_auxInput): Auxiliary inputs must be specified in pairs!'); + end + auxInput = varargin{1}; + firstIsStruct = 1; + else + if ( mod( nargin,2 ) ~= 0 ) + error('ERROR (qpOASES_auxInput): Auxiliary inputs must be specified in pairs!'); + end + auxInput = qpOASES_emptyAuxInput(); + end + end + + % set options to user-defined values + for i=(1+firstIsStruct):2:nargin + + argName = varargin{i}; + argValue = varargin{i+1}; + + if ( ( isempty( argName ) ) || ( ~ischar( argName ) ) ) + error('ERROR (qpOASES_auxInput): Argmument no. %d has to be a non-empty string!',i ); + end + + if ( ( ischar(argValue) ) || ( ~isnumeric( argValue ) ) ) + error('ERROR (qpOASES_auxInput): Argmument no. %d has to be a numerical constant!',i+1 ); + end + + if ( ~isfield( auxInput,argName ) ) + error('ERROR (qpOASES_auxInput): Argmument no. %d is not a valid auxiliary input!',i ); + end + + eval( ['auxInput.',argName,' = argValue;'] ); + + end + +end + + +function [ auxInput ] = qpOASES_emptyAuxInput( ) + + % setup auxiliary input struct with all entries empty + auxInput = struct( 'hessianType', [], ... + 'x0', [], ... + 'guessedWorkingSetB', [], ... + 'guessedWorkingSetC', [], ... + 'R', [] ... + ); + +end diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_matlab_utils.cpp b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_matlab_utils.cpp new file mode 100644 index 0000000..5a10400 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_matlab_utils.cpp @@ -0,0 +1,960 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/matlab/qpOASES_matlab_utils.cpp + * \author Hans Joachim Ferreau, Alexander Buchner + * \version 3.2 + * \date 2007-2017 + * + * Collects utility functions for Interface to Matlab(R) that + * enables to call qpOASES as a MEX function. + * + */ + + + +QPInstance::QPInstance( uint_t _nV, uint_t _nC, HessianType _hessianType, + BooleanType _isSimplyBounded, BooleanType _sparseLA + ) + : sparseLA(_sparseLA) +{ + handle = s_nexthandle++; + + if ( _nC > 0 ) + isSimplyBounded = BT_FALSE; + else + isSimplyBounded = _isSimplyBounded; + + if ( isSimplyBounded == BT_TRUE && sparseLA == BT_FALSE ) + { + sqp = 0; + qpb = new QProblemB( _nV,_hessianType ); + } + else if ( sparseLA == BT_FALSE ) + { + sqp = new SQProblem( _nV,_nC,_hessianType ); + qpb = 0; + } + else + { + #ifdef SOLVER_MA57 + sqp = new SQProblemSchur( _nV,_nC,_hessianType ); + #else + sqp = new SQProblem( _nV,_nC,_hessianType ); + #endif + qpb = 0; + } + + H = 0; + A = 0; + Hir = 0; + Hjc = 0; + Air = 0; + Ajc = 0; + Hv = 0; + Av = 0; +} + + +QPInstance::~QPInstance( ) +{ + deleteQPMatrices(); + + if ( sqp != 0 ) + { + delete sqp; + sqp = 0; + } + + if ( qpb != 0 ) + { + delete qpb; + qpb = 0; + } +} + + +returnValue QPInstance::deleteQPMatrices( ) +{ + if ( H != 0 ) + { + delete H; + H = 0; + } + + if ( Hv != 0 ) + { + delete[] Hv; + Hv = 0; + } + + if ( Hjc != 0 ) + { + delete[] Hjc; + Hjc = 0; + } + + if ( Hir != 0 ) + { + delete[] Hir; + Hir = 0; + } + + if ( A != 0 ) + { + delete A; + A = 0; + } + + if ( Av != 0 ) + { + delete[] Av; + Av = 0; + } + + if ( Ajc != 0 ) + { + delete[] Ajc; + Ajc = 0; + } + + if ( Air != 0 ) + { + delete[] Air; + Air = 0; + } + + return SUCCESSFUL_RETURN; +} + + +int_t QPInstance::getNV() const +{ + if ( sqp != 0 ) + return sqp->getNV(); + + if ( qpb != 0 ) + return qpb->getNV(); + + return 0; +} + + +int_t QPInstance::getNC() const +{ + if ( sqp != 0 ) + return sqp->getNC(); + + return 0; +} + + + +/* + * m x I s S c a l a r + */ +bool mxIsScalar( const mxArray *pm ) +{ + if ( ( mxGetM(pm) == 1 ) && ( mxGetN(pm) == 1 ) ) + return true; + else + return false; +} + + + +/* + * a l l o c a t e Q P r o b l e m I n s t a n c e + */ +int_t allocateQPInstance( int_t nV, int_t nC, HessianType hessianType, + BooleanType isSimplyBounded, BooleanType isSparse, const Options* options + ) +{ + QPInstance* inst = new QPInstance( nV,nC,hessianType, isSimplyBounded, isSparse ); + + if ( ( inst->sqp != 0 ) && ( options != 0 ) ) + inst->sqp->setOptions( *options ); + + if ( ( inst->qpb != 0 ) && ( options != 0 ) ) + inst->qpb->setOptions( *options ); + + g_instances.push_back(inst); + return inst->handle; +} + + +/* + * g e t Q P r o b l e m I n s t a n c e + */ +QPInstance* getQPInstance( int_t handle ) +{ + uint_t ii; + // TODO: this may become slow ... + for (ii = 0; ii < g_instances.size (); ++ii) + if (g_instances[ii]->handle == handle) + return g_instances[ii]; + return 0; +} + + +/* + * d e l e t e Q P r o b l e m I n s t a n c e + */ +void deleteQPInstance( int_t handle ) +{ + QPInstance *instance = getQPInstance (handle); + if (instance != 0) { + for (std::vector::iterator itor = g_instances.begin (); + itor != g_instances.end (); ++itor) + if ((*itor)->handle == handle) { + g_instances.erase (itor); + break; + } + delete instance; + } +} + + + +/* + * s m a r t D i m e n s i o n C h e c k + */ +returnValue smartDimensionCheck( real_t** input, uint_t m, uint_t n, BooleanType emptyAllowed, + const mxArray* prhs[], int_t idx + ) +{ + /* If index is negative, the input does not exist. */ + if ( idx < 0 ) + { + *input = 0; + return SUCCESSFUL_RETURN; + } + + /* Otherwise the input has been passed by the user. */ + if ( mxIsEmpty( prhs[ idx ] ) ) + { + /* input is empty */ + if ( ( emptyAllowed == BT_TRUE ) || ( idx == 0 ) ) /* idx==0 used for auxInput */ + { + *input = 0; + return SUCCESSFUL_RETURN; + } + else + { + char msg[MAX_STRING_LENGTH]; + if ( idx > 0 ) + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Empty argument %d not allowed!", idx+1); + myMexErrMsgTxt( msg ); + return RET_INVALID_ARGUMENTS; + } + } + else + { + /* input is non-empty */ + if ( mxIsSparse( prhs[ idx ] ) == 0 ) + { + if ( ( mxGetM( prhs[ idx ] ) == m ) && ( mxGetN( prhs[ idx ] ) == n ) ) + { + *input = (real_t*) mxGetPr( prhs[ idx ] ); + return SUCCESSFUL_RETURN; + } + else + { + char msg[MAX_STRING_LENGTH]; + if ( idx > 0 ) + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Input dimension mismatch for argument %d ([%ld,%ld] ~= [%d,%d]).", + idx+1, (long int)mxGetM(prhs[idx]), (long int)mxGetN(prhs[idx]), (int)m,(int)n); + else /* idx==0 used for auxInput */ + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Input dimension mismatch for some auxInput entry ([%ld,%ld] ~= [%d,%d]).", + (long int)mxGetM(prhs[idx]), (long int)mxGetN(prhs[idx]), (int)m,(int)n); + myMexErrMsgTxt( msg ); + return RET_INVALID_ARGUMENTS; + } + } + else + { + char msg[MAX_STRING_LENGTH]; + if ( idx > 0 ) + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Vector argument %d must not be in sparse format!", idx+1); + else /* idx==0 used for auxInput */ + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): auxInput entries must not be in sparse format!" ); + myMexErrMsgTxt( msg ); + return RET_INVALID_ARGUMENTS; + } + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * c o n t a i n s N a N + */ +BooleanType containsNaN( const real_t* const data, uint_t dim ) +{ + uint_t i; + + if ( data == 0 ) + return BT_FALSE; + + for ( i = 0; i < dim; ++i ) + if ( mxIsNaN(data[i]) == 1 ) + return BT_TRUE; + + return BT_FALSE; +} + + +/* + * c o n t a i n s I n f + */ +BooleanType containsInf( const real_t* const data, uint_t dim ) +{ + uint_t i; + + if ( data == 0 ) + return BT_FALSE; + + for ( i = 0; i < dim; ++i ) + if ( mxIsInf(data[i]) == 1 ) + return BT_TRUE; + + return BT_FALSE; +} + + +/* + * c o n t a i n s N a N o r I n f + */ +BooleanType containsNaNorInf( const mxArray* prhs[], int_t rhs_index, + bool mayContainInf + ) +{ + uint_t dim; + char msg[MAX_STRING_LENGTH]; + + if ( rhs_index < 0 ) + return BT_FALSE; + + /* overwrite dim for sparse matrices */ + if (mxIsSparse(prhs[rhs_index]) == 1) + dim = (uint_t)mxGetNzmax(prhs[rhs_index]); + else + dim = (uint_t)(mxGetM(prhs[rhs_index]) * mxGetN(prhs[rhs_index])); + + if (containsNaN((real_t*) mxGetPr(prhs[rhs_index]), dim) == BT_TRUE) { + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Argument %d contains 'NaN' !", rhs_index + 1); + myMexErrMsgTxt(msg); + return BT_TRUE; + } + + if (mayContainInf == 0) { + if (containsInf((real_t*) mxGetPr(prhs[rhs_index]), dim) == BT_TRUE) { + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Argument %d contains 'Inf' !", + rhs_index + 1); + myMexErrMsgTxt(msg); + return BT_TRUE; + } + } + + return BT_FALSE; +} + + +/* + * c o n v e r t F o r t r a n T o C + */ +returnValue convertFortranToC( const real_t* const M_for, int_t nV, int_t nC, real_t* const M ) +{ + int_t i,j; + + if ( ( M_for == 0 ) || ( M == 0 ) ) + return RET_INVALID_ARGUMENTS; + + if ( ( nV < 0 ) || ( nC < 0 ) ) + return RET_INVALID_ARGUMENTS; + + for ( i=0; i = ; */ + if ( mxGetNumberOfFields(optionsPtr) != 31 ) + mexWarnMsgTxt( "Options might be set incorrectly as struct has wrong number of entries!\n Type 'help qpOASES_options' for further information." ); + + + if ( hasOptionsValue( optionsPtr,"maxIter",&optionValue ) == BT_TRUE ) + if ( *optionValue >= 0.0 ) + nWSRin = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"maxCpuTime",&optionValue ) == BT_TRUE ) + if ( *optionValue >= 0.0 ) + maxCpuTime = *optionValue; + + if ( hasOptionsValue( optionsPtr,"printLevel",&optionValue ) == BT_TRUE ) + { + #ifdef __SUPPRESSANYOUTPUT__ + options->printLevel = PL_NONE; + #else + optionValueInt = (int_t)*optionValue; + options->printLevel = (REFER_NAMESPACE_QPOASES PrintLevel)optionValueInt; + if ( options->printLevel < PL_DEBUG_ITER ) + options->printLevel = PL_DEBUG_ITER; + if ( options->printLevel > PL_HIGH ) + options->printLevel = PL_HIGH; + #endif + } + + if ( hasOptionsValue( optionsPtr,"enableRamping",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableRamping = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableFarBounds",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableFarBounds = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableFlippingBounds",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableFlippingBounds = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableRegularisation",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableRegularisation = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableFullLITests",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableFullLITests = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableNZCTests",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableNZCTests = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableDriftCorrection",&optionValue ) == BT_TRUE ) + options->enableDriftCorrection = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"enableCholeskyRefactorisation",&optionValue ) == BT_TRUE ) + options->enableCholeskyRefactorisation = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"enableEqualities",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableEqualities = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + + if ( hasOptionsValue( optionsPtr,"terminationTolerance",&optionValue ) == BT_TRUE ) + options->terminationTolerance = *optionValue; + + if ( hasOptionsValue( optionsPtr,"boundTolerance",&optionValue ) == BT_TRUE ) + options->boundTolerance = *optionValue; + + if ( hasOptionsValue( optionsPtr,"boundRelaxation",&optionValue ) == BT_TRUE ) + options->boundRelaxation = *optionValue; + + if ( hasOptionsValue( optionsPtr,"epsNum",&optionValue ) == BT_TRUE ) + options->epsNum = *optionValue; + + if ( hasOptionsValue( optionsPtr,"epsDen",&optionValue ) == BT_TRUE ) + options->epsDen = *optionValue; + + if ( hasOptionsValue( optionsPtr,"maxPrimalJump",&optionValue ) == BT_TRUE ) + options->maxPrimalJump = *optionValue; + + if ( hasOptionsValue( optionsPtr,"maxDualJump",&optionValue ) == BT_TRUE ) + options->maxDualJump = *optionValue; + + + if ( hasOptionsValue( optionsPtr,"initialRamping",&optionValue ) == BT_TRUE ) + options->initialRamping = *optionValue; + + if ( hasOptionsValue( optionsPtr,"finalRamping",&optionValue ) == BT_TRUE ) + options->finalRamping = *optionValue; + + if ( hasOptionsValue( optionsPtr,"initialFarBounds",&optionValue ) == BT_TRUE ) + options->initialFarBounds = *optionValue; + + if ( hasOptionsValue( optionsPtr,"growFarBounds",&optionValue ) == BT_TRUE ) + options->growFarBounds = *optionValue; + + if ( hasOptionsValue( optionsPtr,"initialStatusBounds",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + if ( optionValueInt < -1 ) + optionValueInt = -1; + if ( optionValueInt > 1 ) + optionValueInt = 1; + options->initialStatusBounds = (REFER_NAMESPACE_QPOASES SubjectToStatus)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"epsFlipping",&optionValue ) == BT_TRUE ) + options->epsFlipping = *optionValue; + + if ( hasOptionsValue( optionsPtr,"numRegularisationSteps",&optionValue ) == BT_TRUE ) + options->numRegularisationSteps = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"epsRegularisation",&optionValue ) == BT_TRUE ) + options->epsRegularisation = *optionValue; + + if ( hasOptionsValue( optionsPtr,"numRefinementSteps",&optionValue ) == BT_TRUE ) + options->numRefinementSteps = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"epsIterRef",&optionValue ) == BT_TRUE ) + options->epsIterRef = *optionValue; + + if ( hasOptionsValue( optionsPtr,"epsLITests",&optionValue ) == BT_TRUE ) + options->epsLITests = *optionValue; + + if ( hasOptionsValue( optionsPtr,"epsNZCTests",&optionValue ) == BT_TRUE ) + options->epsNZCTests = *optionValue; + + return SUCCESSFUL_RETURN; +} + + + +/* + * s e t u p A u x i l i a r y I n p u t s + */ +returnValue setupAuxiliaryInputs( const mxArray* auxInput, uint_t nV, uint_t nC, + HessianType* hessianType, double** x0, double** guessedBounds, double** guessedConstraints, double** R + ) +{ + mxArray* curField = 0; + + /* hessianType */ + curField = mxGetField( auxInput,0,"hessianType" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'hessianType'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + if ( mxIsEmpty(curField) == true ) + { + *hessianType = HST_UNKNOWN; + } + else + { + if ( mxIsScalar(curField) == false ) + return RET_INVALID_ARGUMENTS; + + double* hessianTypeTmp = mxGetPr(curField); + int_t hessianTypeInt = (int_t)*hessianTypeTmp; + if ( hessianTypeInt < 0 ) + hessianTypeInt = 6; /* == HST_UNKNOWN */ + if ( hessianTypeInt > 5 ) + hessianTypeInt = 6; /* == HST_UNKNOWN */ + *hessianType = (REFER_NAMESPACE_QPOASES HessianType)hessianTypeInt; + } + } + + /* x0 */ + curField = mxGetField( auxInput,0,"x0" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'x0'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + *x0 = mxGetPr(curField); + if ( smartDimensionCheck( x0,nV,1, BT_TRUE,((const mxArray**)&curField),0 ) != SUCCESSFUL_RETURN ) + return RET_INVALID_ARGUMENTS; + } + + /* guessedWorkingSetB */ + curField = mxGetField( auxInput,0,"guessedWorkingSetB" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'guessedWorkingSetB'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + *guessedBounds = mxGetPr(curField); + if ( smartDimensionCheck( guessedBounds,nV,1, BT_TRUE,((const mxArray**)&curField),0 ) != SUCCESSFUL_RETURN ) + return RET_INVALID_ARGUMENTS; + } + + /* guessedWorkingSetC */ + curField = mxGetField( auxInput,0,"guessedWorkingSetC" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'guessedWorkingSetC'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + *guessedConstraints = mxGetPr(curField); + if ( smartDimensionCheck( guessedConstraints,nC,1, BT_TRUE,((const mxArray**)&curField),0 ) != SUCCESSFUL_RETURN ) + return RET_INVALID_ARGUMENTS; + } + + /* R */ + curField = mxGetField( auxInput,0,"R" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'R'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + *R = mxGetPr(curField); + if ( smartDimensionCheck( R,nV,nV, BT_TRUE,((const mxArray**)&curField),0 ) != SUCCESSFUL_RETURN ) + return RET_INVALID_ARGUMENTS; + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * a l l o c a t e O u t p u t s + */ +returnValue allocateOutputs( int nlhs, mxArray* plhs[], int_t nV, int_t nC = 0, int_t nP = 1, int_t handle = -1 + ) +{ + /* Create output vectors and assign pointers to them. */ + int_t curIdx = 0; + + /* handle */ + if ( handle >= 0 ) + plhs[curIdx++] = mxCreateDoubleMatrix( 1, 1, mxREAL ); + + /* x */ + plhs[curIdx++] = mxCreateDoubleMatrix( nV, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* fval */ + plhs[curIdx++] = mxCreateDoubleMatrix( 1, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* exitflag */ + plhs[curIdx++] = mxCreateDoubleMatrix( 1, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* iter */ + plhs[curIdx++] = mxCreateDoubleMatrix( 1, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* lambda */ + plhs[curIdx++] = mxCreateDoubleMatrix( nV+nC, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* setup auxiliary output struct */ + mxArray* auxOutput = mxCreateStructMatrix( 1,1,0,0 ); + int_t curFieldNum; + + /* working set */ + curFieldNum = mxAddField( auxOutput,"workingSetB" ); + if ( curFieldNum >= 0 ) + mxSetFieldByNumber( auxOutput,0,curFieldNum,mxCreateDoubleMatrix( nV, nP, mxREAL ) ); + + curFieldNum = mxAddField( auxOutput,"workingSetC" ); + if ( curFieldNum >= 0 ) + mxSetFieldByNumber( auxOutput,0,curFieldNum,mxCreateDoubleMatrix( nC, nP, mxREAL ) ); + + curFieldNum = mxAddField( auxOutput,"cpuTime" ); + if ( curFieldNum >= 0 ) + mxSetFieldByNumber( auxOutput,0,curFieldNum,mxCreateDoubleMatrix( 1, nP, mxREAL ) ); + + plhs[curIdx] = auxOutput; + } + } + } + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * o b t a i n O u t p u t s + */ +returnValue obtainOutputs( int_t k, QProblemB* qp, returnValue returnvalue, int_t _nWSRout, double _cpuTime, + int nlhs, mxArray* plhs[], int_t nV, int_t nC = 0, int_t handle = -1 + ) +{ + /* Create output vectors and assign pointers to them. */ + int_t curIdx = 0; + + /* handle */ + if ( handle >= 0 ) + plhs[curIdx++] = mxCreateDoubleScalar( handle ); + + /* x */ + double* x = mxGetPr( plhs[curIdx++] ); + qp->getPrimalSolution( &(x[k*nV]) ); + + if ( nlhs > curIdx ) + { + /* fval */ + double* obj = mxGetPr( plhs[curIdx++] ); + obj[k] = qp->getObjVal( ); + + if ( nlhs > curIdx ) + { + /* exitflag */ + double* status = mxGetPr( plhs[curIdx++] ); + status[k] = (double)getSimpleStatus( returnvalue ); + + if ( nlhs > curIdx ) + { + /* iter */ + double* nWSRout = mxGetPr( plhs[curIdx++] ); + nWSRout[k] = (double) _nWSRout; + + if ( nlhs > curIdx ) + { + /* lambda */ + double* y = mxGetPr( plhs[curIdx++] ); + qp->getDualSolution( &(y[k*(nV+nC)]) ); + + /* auxOutput */ + if ( nlhs > curIdx ) + { + QProblem* problemPointer; + problemPointer = dynamic_cast(qp); + + mxArray* auxOutput = plhs[curIdx]; + mxArray* curField = 0; + + /* working set bounds */ + if ( nV > 0 ) + { + curField = mxGetField( auxOutput,0,"workingSetB" ); + double* workingSetB = mxGetPr(curField); + + /* cast successful? */ + if (problemPointer != NULL) { + problemPointer->getWorkingSetBounds( &(workingSetB[k*nV]) ); + } else { + qp->getWorkingSetBounds( &(workingSetB[k*nV]) ); + } + } + + /* working set constraints */ + if ( nC > 0 ) + { + curField = mxGetField( auxOutput,0,"workingSetC" ); + double* workingSetC = mxGetPr(curField); + + /* cast successful? */ + if (problemPointer != NULL) { + problemPointer->getWorkingSetConstraints( &(workingSetC[k*nC]) ); + } else { + qp->getWorkingSetConstraints( &(workingSetC[k*nC]) ); + } + } + + /* cpu time */ + curField = mxGetField( auxOutput,0,"cpuTime" ); + double* cpuTime = mxGetPr(curField); + cpuTime[0] = (double) _cpuTime; + } + } + } + } + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * s e t u p H e s s i a n M a t r i x + */ +returnValue setupHessianMatrix( const mxArray* prhsH, int_t nV, + SymmetricMatrix** H, sparse_int_t** Hir, sparse_int_t** Hjc, real_t** Hv + ) +{ + if ( prhsH == 0 ) + return SUCCESSFUL_RETURN; + + if ( mxIsSparse( prhsH ) != 0 ) + { + mwIndex *mat_ir = mxGetIr( prhsH ); + mwIndex *mat_jc = mxGetJc( prhsH ); + double *v = (double*)mxGetPr( prhsH ); + sparse_int_t nfill = 0; + mwIndex i, j; + BooleanType needInsertDiag; + + /* copy indices to avoid 64/32-bit integer confusion */ + /* also add explicit zeros on diagonal for regularization strategy */ + /* copy values, too */ + *Hir = new sparse_int_t[mat_jc[nV] + nV]; + *Hjc = new sparse_int_t[nV+1]; + *Hv = new real_t[mat_jc[nV] + nV]; + for (j = 0; j < nV; j++) + { + needInsertDiag = BT_TRUE; + + (*Hjc)[j] = (sparse_int_t)(mat_jc[j]) + nfill; + /* fill up to diagonal */ + for (i = mat_jc[j]; i < mat_jc[j+1]; i++) + { + if ( mat_ir[i] == j ) + needInsertDiag = BT_FALSE; + + /* add zero diagonal element if not present */ + if ( ( mat_ir[i] > j ) && ( needInsertDiag == BT_TRUE ) ) + { + (*Hir)[i + nfill] = (sparse_int_t)j; + (*Hv)[i + nfill] = 0.0; + nfill++; + /* only add diag once */ + needInsertDiag = BT_FALSE; + } + + (*Hir)[i + nfill] = (sparse_int_t)(mat_ir[i]); + (*Hv)[i + nfill] = (real_t)(v[i]); + } + } + (*Hjc)[nV] = (sparse_int_t)(mat_jc[nV]) + nfill; + + SymSparseMat *sH; + *H = sH = new SymSparseMat(nV, nV, *Hir, *Hjc, *Hv); + sH->createDiagInfo(); + } + else + { + /* make a deep-copy in order to avoid modifying input data when regularising */ + real_t* H_for = (real_t*) mxGetPr( prhsH ); + real_t* H_mem = new real_t[nV*nV]; + memcpy( H_mem,H_for, nV*nV*sizeof(real_t) ); + + *H = new SymDenseMat( nV,nV,nV, H_mem ); + (*H)->doFreeMemory( ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p C o n s t r a i n t M a t r i x + */ +returnValue setupConstraintMatrix( const mxArray* prhsA, int_t nV, int_t nC, + Matrix** A, sparse_int_t** Air, sparse_int_t** Ajc, real_t** Av + ) +{ + if ( prhsA == 0 ) + return SUCCESSFUL_RETURN; + + if ( mxIsSparse( prhsA ) != 0 ) + { + mwIndex i; + long j; + + mwIndex *mat_ir = mxGetIr( prhsA ); + mwIndex *mat_jc = mxGetJc( prhsA ); + double *v = (double*)mxGetPr( prhsA ); + + /* copy indices to avoid 64/32-bit integer confusion */ + *Air = new sparse_int_t[mat_jc[nV]]; + *Ajc = new sparse_int_t[nV+1]; + for (i = 0; i < mat_jc[nV]; i++) + (*Air)[i] = (sparse_int_t)(mat_ir[i]); + for (i = 0; i < nV + 1; i++) + (*Ajc)[i] = (sparse_int_t)(mat_jc[i]); + + /* copy values, too */ + *Av = new real_t[(*Ajc)[nV]]; + for (j = 0; j < (*Ajc)[nV]; j++) + (*Av)[j] = (real_t)(v[j]); + + *A = new SparseMatrix(nC, nV, *Air, *Ajc, *Av); + } + else + { + /* Convert constraint matrix A from FORTRAN to C style + * (not necessary for H as it should be symmetric!). */ + real_t* A_for = (real_t*) mxGetPr( prhsA ); + real_t* A_mem = new real_t[nC*nV]; + convertFortranToC( A_for,nV,nC, A_mem ); + *A = new DenseMatrix(nC, nV, nV, A_mem ); + (*A)->doFreeMemory(); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_matlab_utils.hpp b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_matlab_utils.hpp new file mode 100644 index 0000000..9ad078e --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_matlab_utils.hpp @@ -0,0 +1,102 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/matlab/qpOASES_matlab_utils.hpp + * \author Hans Joachim Ferreau, Alexander Buchner + * \version 3.2 + * \date 2007-2017 + * + * Collects utility functions for Interface to Matlab(R) that + * enables to call qpOASES as a MEX function. + * + */ + + + +/* Work-around for settings where mexErrMsgTxt causes unexpected behaviour. */ +#ifdef __AVOID_MEXERRMSGTXT__ + #define myMexErrMsgTxt( TEXT ) mexPrintf( "%s\n\n",(TEXT) ); +#else + #define myMexErrMsgTxt mexErrMsgTxt +#endif + + +/* Workaround for problem on Matlab 2012b + * see https://github.com/robotology/codyco-superbuild/issues/84 + * see http://stackoverflow.com/questions/22440523/mex-files-using-xcode-5-1-under-os-x-10-9-with-matlab-2012a/22705789#22705789 */ +#ifdef __APPLE__ + #include +#endif + +#include "mex.h" +#include "matrix.h" +#include "string.h" +#include + + +/* + * QProblem instance class + */ +class QPInstance +{ + private: + static int_t s_nexthandle; + + public: + QPInstance( uint_t _nV = 0, + uint_t _nC = 0, + HessianType _hessianType = HST_UNKNOWN, + BooleanType _isSimplyBounded = BT_FALSE, + BooleanType _sparseLA = BT_FALSE + ); + + ~QPInstance( ); + + returnValue deleteQPMatrices(); + + int_t getNV() const; + int_t getNC() const; + + int_t handle; + + SQProblem* sqp; + QProblemB* qpb; + BooleanType isSimplyBounded; + BooleanType sparseLA; + + SymmetricMatrix* H; + Matrix* A; + sparse_int_t* Hir; + sparse_int_t* Hjc; + sparse_int_t* Air; + sparse_int_t* Ajc; + real_t* Hv; + real_t* Av; +}; + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_options.m b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_options.m new file mode 100644 index 0000000..0cccf95 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_options.m @@ -0,0 +1,251 @@ +%qpOASES -- An Implementation of the Online Active Set Strategy. +%Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. +% +%qpOASES is distributed under the terms of the +%GNU Lesser General Public License 2.1 in the hope that it will be +%useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%See the GNU Lesser General Public License for more details. +% +%--------------------------------------------------------------------------------- +% +%Returns a struct containing values for all options to be used within qpOASES. +% +%Call +% options = qpOASES_options( 'default' ); +% options = qpOASES_options( 'reliable' ); +% options = qpOASES_options( 'MPC' ); +%to obtain a set of default options or a pre-defined set of options tuned +%for reliable or fast QP solution, respectively. +% +%Call +% options = qpOASES_options( 'option1',value1,'option2',value2,... ) +%to obtain a set of default options but with 'option1' set to value1 etc. +% +%Call +% options = qpOASES_options( oldOptions,'option1',value1,... ) +%to obtain a copy of the options struct oldOptions but with 'option1' set +%to value1 etc. +% +%Call +% options = qpOASES_options( 'default', 'option1',value1,... ) +% options = qpOASES_options( 'reliable','option1',value1,... ) +% options = qpOASES_options( 'MPC', 'option1',value1,... ) +%to obtain a set of default options or a pre-defined set of options tuned +%for reliable or fast QP solution, respectively, but with 'option1' set to +%value1 etc. +% +% +%qpOASES features the following options: +% maxIter - Maximum number of iterations (if set +% to -1, a value is chosen heuristically) +% maxCpuTime - Maximum CPU time in seconds (if set +% to -1, only iteration limit is used) +% printLevel - 0: no printed output, +% 1: only error messages are printed, +% 2: iterations and error messages are printed, +% 3: all available messages are printed. +% +% enableRamping - Enables (1) or disables (0) ramping. +% enableFarBounds - Enables (1) or disables (0) the use of +% far bounds. +% enableFlippingBounds - Enables (1) or disables (0) the use of +% flipping bounds. +% enableRegularisation - Enables (1) or disables (0) automatic +% Hessian regularisation. +% enableFullLITests - Enables (1) or disables (0) condition-hardened +% (but more expensive) LI test. +% enableNZCTests - Enables (1) or disables (0) nonzero curvature +% tests. +% enableDriftCorrection - Specifies the frequency of drift corrections: +% 0: turns them off, +% 1: uses them at each iteration etc. +% enableCholeskyRefactorisation - Specifies the frequency of a full re- +% factorisation of projected Hessian matrix: +% 0: turns them off, +% 1: uses them at each iteration etc. +% enableEqualities - Specifies whether equalities should be treated +% as always active (1) or not (0) +% +% terminationTolerance - Relative termination tolerance to stop homotopy. +% boundTolerance - If upper and lower bounds differ less than this +% tolerance, they are regarded equal, i.e. as +% equality constraint. +% boundRelaxation - Initial relaxation of bounds to start homotopy +% and initial value for far bounds. +% epsNum - Numerator tolerance for ratio tests. +% epsDen - Denominator tolerance for ratio tests. +% maxPrimalJump - Maximum allowed jump in primal variables in +% nonzero curvature tests. +% maxDualJump - Maximum allowed jump in dual variables in +% linear independence tests. +% +% initialRamping - Start value for ramping strategy. +% finalRamping - Final value for ramping strategy. +% initialFarBounds - Initial size for far bounds. +% growFarBounds - Factor to grow far bounds. +% initialStatusBounds - Initial status of bounds at first iteration: +% 0: all bounds inactive, +% -1: all bounds active at their lower bound, +% +1: all bounds active at their upper bound. +% epsFlipping - Tolerance of squared Cholesky diagonal factor +% which triggers flipping bound. +% numRegularisationSteps - Maximum number of successive regularisation steps. +% epsRegularisation - Scaling factor of identity matrix used for +% Hessian regularisation. +% numRefinementSteps - Maximum number of iterative refinement steps. +% epsIterRef - Early termination tolerance for iterative +% refinement. +% epsLITests - Tolerance for linear independence tests. +% epsNZCTests - Tolerance for nonzero curvature tests. +% +% +%See also QPOASES, QPOASES_SEQUENCE, QPOASES_AUXINPUT +% +% +%For additional information see the qpOASES User's Manual or +%visit http://www.qpOASES.org/. +% +%Please send remarks and questions to support@qpOASES.org! +function [ options ] = qpOASES_options( varargin ) + + firstIsStructOrScheme = 0; + + if ( nargin == 0 ) + options = qpOASES_default_options(); + else + if ( isstruct( varargin{1} ) ) + if ( mod( nargin,2 ) ~= 1 ) + error('ERROR (qpOASES_options): Options must be specified in pairs!'); + end + options = varargin{1}; + firstIsStructOrScheme = 1; + else + if ( ischar( varargin{1} ) ) + if ( mod( nargin,2 ) == 0 ) + options = qpOASES_default_options(); + else + if ( ( nargin > 1 ) && ( ischar( varargin{nargin} ) ) ) + error('ERROR (qpOASES_options): Options must be specified in pairs!'); + end + + switch ( varargin{1} ) + case 'default' + options = qpOASES_default_options(); + case 'reliable' + options = qpOASES_reliable_options(); + case {'MPC','mpc','fast'} + options = qpOASES_MPC_options(); + otherwise + error( ['ERROR (qpOASES_options): Only the following option schemes are defined: ''default'', ''reliable'', ''MPC''!'] ); + + end + firstIsStructOrScheme = 1; + end + else + error('ERROR (qpOASES_options): First argument needs to be a string or an options struct!'); + end + end + end + + % set options to user-defined values + for i=(1+firstIsStructOrScheme):2:nargin + + argName = varargin{i}; + argValue = varargin{i+1}; + + if ( ( isempty( argName ) ) || ( ~ischar( argName ) ) ) + error('ERROR (qpOASES_options): Argmument no. %d has to be a non-empty string!',i ); + end + + if ( ( ischar(argValue) ) || ( ~isscalar( argValue ) ) ) + error('ERROR (qpOASES_options): Argmument no. %d has to be a scalar constant!',i+1 ); + end + + if ( ~isfield( options,argName ) ) + error('ERROR (qpOASES_options): Argmument no. %d is an invalid option!',i ); + end + + eval( ['options.',argName,' = ',num2str(argValue),';'] ); + + end + +end + + +function [ options ] = qpOASES_default_options( ) + + % setup options struct with default values + options = struct( 'maxIter', -1, ... + 'maxCpuTime', -1, ... + 'printLevel', 1, ... + ... + 'enableRamping', 1, ... + 'enableFarBounds', 1, ... + 'enableFlippingBounds', 1, ... + 'enableRegularisation', 0, ... + 'enableFullLITests', 0, ... + 'enableNZCTests', 1, ... + 'enableDriftCorrection', 1, ... + 'enableCholeskyRefactorisation', 0, ... + 'enableEqualities', 0, ... + ... + 'terminationTolerance', 5.0e6*eps, ... + 'boundTolerance', 1.0e6*eps, ... + 'boundRelaxation', 1.0e4, ... + 'epsNum', -1.0e3*eps, ... + 'epsDen', 1.0e3*eps, ... + 'maxPrimalJump', 1.0e8, ... + 'maxDualJump', 1.0e8, ... + ... + 'initialRamping', 0.5, ... + 'finalRamping', 1.0, ... + 'initialFarBounds', 1.0e6, ... + 'growFarBounds', 1.0e3, ... + 'initialStatusBounds', -1, ... + 'epsFlipping', 1.0e3*eps, ... + 'numRegularisationSteps', 0, ... + 'epsRegularisation', 1.0e3*eps, ... + 'numRefinementSteps', 1, ... + 'epsIterRef', 1.0e2*eps, ... + 'epsLITests', 1.0e5*eps, ... + 'epsNZCTests', 3.1e3*eps ); + +end + + + +function [ options ] = qpOASES_reliable_options( ) + + % setup options struct with values for most reliable QP solution + options = qpOASES_default_options( ); + + options.enableFullLITests = 1; + options.enableCholeskyRefactorisation = 1; + + options.numRefinementSteps = 2; + +end + + +function [ options ] = qpOASES_MPC_options( ) + + % setup options struct with values for most reliable QP solution + options = qpOASES_default_options( ); + + options.enableRamping = 0; + options.enableFarBounds = 1; + options.enableFlippingBounds = 0; + options.enableRegularisation = 1; + options.enableNZCTests = 0; + options.enableDriftCorrection = 0; + options.enableEqualities = 1; + + options.terminationTolerance = 1.0e9*eps; + + options.initialStatusBounds = 0; + options.numRegularisationSteps = 1; + options.numRefinementSteps = 0; + +end diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_sequence.cpp b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_sequence.cpp new file mode 100644 index 0000000..b10aede --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_sequence.cpp @@ -0,0 +1,1115 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/matlab/qpOASES_sequence.cpp + * \author Hans Joachim Ferreau, Christian Kirches, Andreas Potschka, Alexander Buchner + * \version 3.2 + * \date 2007-2017 + * + * Interface for Matlab(R) that enables to call qpOASES as a MEX function + * (variant for solving QP sequences). + * + */ + + + +#include + + +USING_NAMESPACE_QPOASES + + +#include "qpOASES_matlab_utils.hpp" + +/** initialise handle counter of QPInstance class */ +int_t QPInstance::s_nexthandle = 1; + +/** global pointer to QP objects */ +static std::vector g_instances; + +#include "qpOASES_matlab_utils.cpp" + + +/* + * Q P r o b l e m B _ i n i t + */ +int_t QProblemB_init( int_t handle, + SymmetricMatrix* H, real_t* g, + const real_t* const lb, const real_t* const ub, + int_t nWSRin, real_t maxCpuTimeIn, + const double* const x0, Options* options, + int_t nOutputs, mxArray* plhs[], + const double* const guessedBounds, + const double* const _R + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + /* 1) setup initial QP. */ + QProblemB* globalQPB = getQPInstance(handle)->qpb; + + if ( globalQPB == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return -1; + } + + globalQPB->setOptions( *options ); + + /* 2) Solve initial QP. */ + returnValue returnvalue; + int_t nV = globalQPB->getNV(); + + /* 3) Fill the working set. */ + Bounds bounds(nV); + if (guessedBounds != 0) { + for (int_t i = 0; i < nV; i++) { + if ( isEqual(guessedBounds[i],-1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_LOWER); + } else if ( isEqual(guessedBounds[i],1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_UPPER); + } else if ( isEqual(guessedBounds[i],0.0) == BT_TRUE ) { + bounds.setupBound(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of bounds!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + returnvalue = globalQPB->init( H,g,lb,ub, + nWSRout,&maxCpuTimeOut, + x0,0, + (guessedBounds != 0) ? &bounds : 0, + _R + ); + + /* 3) Assign lhs arguments. */ + obtainOutputs( 0,globalQPB,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,0,handle ); + + return 0; +} + + +/* + * S Q P r o b l e m _ i n i t + */ +int_t SQProblem_init( int_t handle, + SymmetricMatrix* H, real_t* g, Matrix* A, + const real_t* const lb, const real_t* const ub, + const real_t* const lbA, const real_t* const ubA, + int_t nWSRin, real_t maxCpuTimeIn, + const double* const x0, Options* options, + int_t nOutputs, mxArray* plhs[], + const double* const guessedBounds, const double* const guessedConstraints, + const double* const _R + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + /* 1) setup initial QP. */ + SQProblem* globalSQP = getQPInstance(handle)->sqp; + + if ( globalSQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return -1; + } + + globalSQP->setOptions( *options ); + + /* 2) Solve initial QP. */ + returnValue returnvalue; + int_t nV = globalSQP->getNV(); + int_t nC = globalSQP->getNC(); + + /* 3) Fill the working set. */ + Bounds bounds(nV); + Constraints constraints(nC); + if (guessedBounds != 0) { + for (int_t i = 0; i < nV; i++) { + if ( isEqual(guessedBounds[i],-1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_LOWER); + } else if ( isEqual(guessedBounds[i],1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_UPPER); + } else if ( isEqual(guessedBounds[i],0.0) == BT_TRUE ) { + bounds.setupBound(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of bounds!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + if (guessedConstraints != 0) { + for (int_t i = 0; i < nC; i++) { + if ( isEqual(guessedConstraints[i],-1.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_LOWER); + } else if ( isEqual(guessedConstraints[i],1.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_UPPER); + } else if ( isEqual(guessedConstraints[i],0.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of constraints!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + returnvalue = globalSQP->init( H,g,A,lb,ub,lbA,ubA, + nWSRout,&maxCpuTimeOut, + x0,0, + (guessedBounds != 0) ? &bounds : 0, (guessedConstraints != 0) ? &constraints : 0, + _R + ); + + /* 3) Assign lhs arguments. */ + obtainOutputs( 0,globalSQP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,nC,handle ); + + return 0; +} + + + +/* + * Q P r o b l e m B _ h o t s t a r t + */ +int_t QProblemB_hotstart( int_t handle, + const real_t* const g, + const real_t* const lb, const real_t* const ub, + int_t nWSRin, real_t maxCpuTimeIn, + Options* options, + int_t nOutputs, mxArray* plhs[] + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + QProblemB* globalQPB = getQPInstance(handle)->qpb; + + if ( globalQPB == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): QP needs to be initialised first!" ); + return -1; + } + + int_t nV = globalQPB->getNV(); + + /* 1) Solve QP with given options. */ + globalQPB->setOptions( *options ); + returnValue returnvalue = globalQPB->hotstart( g,lb,ub, nWSRout,&maxCpuTimeOut ); + + /* 2) Assign lhs arguments. */ + obtainOutputs( 0,globalQPB,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,0 ); + + return 0; +} + + +/* + * Q P r o b l e m _ h o t s t a r t + */ +int_t QProblem_hotstart( int_t handle, + const real_t* const g, + const real_t* const lb, const real_t* const ub, + const real_t* const lbA, const real_t* const ubA, + int_t nWSRin, real_t maxCpuTimeIn, + Options* options, + int_t nOutputs, mxArray* plhs[] + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + QProblem* globalSQP = getQPInstance(handle)->sqp; + + if ( globalSQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): QP needs to be initialised first!" ); + return -1; + } + + int_t nV = globalSQP->getNV(); + int_t nC = globalSQP->getNC(); + + /* 1) Solve QP with given options. */ + globalSQP->setOptions( *options ); + returnValue returnvalue = globalSQP->hotstart( g,lb,ub,lbA,ubA, nWSRout,&maxCpuTimeOut ); + + /* 2) Assign lhs arguments. */ + obtainOutputs( 0,globalSQP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,nC ); + + return 0; +} + + +/* + * S Q P r o b l e m _ h o t s t a r t + */ +int_t SQProblem_hotstart( int_t handle, + SymmetricMatrix* H, real_t* g, Matrix* A, + const real_t* const lb, const real_t* const ub, const real_t* const lbA, const real_t* const ubA, + int_t nWSRin, real_t maxCpuTimeIn, + Options* options, + int_t nOutputs, mxArray* plhs[] + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + SQProblem* globalSQP = getQPInstance(handle)->sqp; + + if ( globalSQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): QP needs to be initialised first!" ); + return -1; + } + + int_t nV = globalSQP->getNV(); + int_t nC = globalSQP->getNC(); + + /* 1) Solve QP. */ + globalSQP->setOptions( *options ); + returnValue returnvalue = globalSQP->hotstart( H,g,A,lb,ub,lbA,ubA, nWSRout,&maxCpuTimeOut ); + + switch (returnvalue) + { + case SUCCESSFUL_RETURN: + case RET_QP_UNBOUNDED: + case RET_QP_INFEASIBLE: + break; + + default: + myMexErrMsgTxt( "ERROR (qpOASES): Hotstart failed." ); + return -1; + } + + /* 2) Assign lhs arguments. */ + obtainOutputs( 0,globalSQP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,nC ); + + return 0; +} + + + +/* + * m e x F u n c t i o n + */ +void mexFunction( int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[] ) +{ + /* inputs */ + char typeString[2]; + + real_t *g=0, *lb=0, *ub=0, *lbA=0, *ubA=0; + HessianType hessianType = HST_UNKNOWN; + double *x0=0, *R=0, *R_for=0; + double *guessedBounds=0, *guessedConstraints=0; + + int_t H_idx=-1, g_idx=-1, A_idx=-1, lb_idx=-1, ub_idx=-1, lbA_idx=-1, ubA_idx=-1; + int_t x0_idx=-1, auxInput_idx=-1; + + BooleanType isSimplyBoundedQp = BT_FALSE; + #ifdef SOLVER_MA57 + BooleanType isSparse = BT_TRUE; /* This will be set to BT_FALSE later if a dense matrix is encountered. */ + #else + BooleanType isSparse = BT_FALSE; + #endif + + Options options; + options.printLevel = PL_LOW; + #ifdef __DEBUG__ + options.printLevel = PL_HIGH; + #endif + #ifdef __SUPPRESSANYOUTPUT__ + options.printLevel = PL_NONE; + #endif + + /* dimensions */ + uint_t nV=0, nC=0, handle=0; + int_t nWSRin; + real_t maxCpuTimeIn = -1.0; + QPInstance* globalQP = 0; + + /* I) CONSISTENCY CHECKS: */ + /* 1) Ensure that qpOASES is called with a feasible number of input arguments. */ + if ( ( nrhs < 5 ) || ( nrhs > 10 ) ) + { + if ( nrhs != 2 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + } + + /* 2) Ensure that first input is a string ... */ + if ( mxIsChar( prhs[0] ) != 1 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): First input argument must be a string!" ); + return; + } + + mxGetString( prhs[0], typeString, 2 ); + + /* ... and if so, check if it is an allowed one. */ + if ( ( strcmp( typeString,"i" ) != 0 ) && ( strcmp( typeString,"I" ) != 0 ) && + ( strcmp( typeString,"h" ) != 0 ) && ( strcmp( typeString,"H" ) != 0 ) && + ( strcmp( typeString,"m" ) != 0 ) && ( strcmp( typeString,"M" ) != 0 ) && + ( strcmp( typeString,"e" ) != 0 ) && ( strcmp( typeString,"E" ) != 0 ) && + ( strcmp( typeString,"c" ) != 0 ) && ( strcmp( typeString,"C" ) != 0 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Undefined first input argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + + /* II) SELECT RESPECTIVE QPOASES FUNCTION CALL: */ + /* 1) Init (without or with initial guess for primal solution). */ + if ( ( strcmp( typeString,"i" ) == 0 ) || ( strcmp( typeString,"I" ) == 0 ) ) + { + /* consistency checks */ + if ( ( nlhs < 1 ) || ( nlhs > 7 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( nrhs < 5 ) || ( nrhs > 10 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + g_idx = 2; + + if ( mxIsEmpty(prhs[1]) == 1 ) + { + H_idx = -1; + nV = (uint_t)mxGetM( prhs[ g_idx ] ); /* row number of Hessian matrix */ + } + else + { + H_idx = 1; + nV = (uint_t)mxGetM( prhs[ H_idx ] ); /* row number of Hessian matrix */ + } + + + /* ensure that data is given in double precision */ + if ( ( ( H_idx >= 0 ) && ( mxIsDouble( prhs[ H_idx ] ) == 0 ) ) || + ( mxIsDouble( prhs[ g_idx ] ) == 0 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in double precision!" ); + return; + } + + if ( ( H_idx >= 0 ) && ( ( mxGetN( prhs[ H_idx ] ) != nV ) || ( mxGetM( prhs[ H_idx ] ) != nV ) ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Hessian matrix dimension mismatch!" ); + return; + } + + + /* Check for 'Inf' and 'Nan' in Hessian */ + if (containsNaNorInf( prhs,H_idx, 0 ) == BT_TRUE) + return; + + /* Check for 'Inf' and 'Nan' in gradient */ + if (containsNaNorInf(prhs,g_idx, 0 ) == BT_TRUE) + return; + + /* determine whether is it a simply bounded QP */ + if ( nrhs <= 7 ) + isSimplyBoundedQp = BT_TRUE; + else + isSimplyBoundedQp = BT_FALSE; + + if ( isSimplyBoundedQp == BT_TRUE ) + { + lb_idx = 3; + ub_idx = 4; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + /* Check inputs dimensions and assign pointers to inputs. */ + nC = 0; /* row number of constraint matrix */ + + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,2 ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,3 ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,4 ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*nV; + + /* Check whether x0 and options are specified .*/ + if ( nrhs >= 6 ) + { + if ((!mxIsEmpty(prhs[5])) && (mxIsStruct(prhs[5]))) + setupOptions( &options,prhs[5],nWSRin,maxCpuTimeIn ); + + if ( ( nrhs >= 7 ) && ( !mxIsEmpty(prhs[6]) ) ) + { + /* auxInput specified */ + if ( mxIsStruct(prhs[6]) ) + { + auxInput_idx = 6; + x0_idx = -1; + } + else + { + auxInput_idx = -1; + x0_idx = 6; + } + } + else + { + auxInput_idx = -1; + x0_idx = -1; + } + } + } + else + { + A_idx = 3; + + /* ensure that data is given in double precision */ + if ( mxIsDouble( prhs[ A_idx ] ) == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in double precision!" ); + return; + } + + /* Check inputs dimensions and assign pointers to inputs. */ + nC = (uint_t)mxGetM( prhs[ A_idx ] ); /* row number of constraint matrix */ + + lb_idx = 4; + ub_idx = 5; + lbA_idx = 6; + ubA_idx = 7; + + if (containsNaNorInf( prhs,A_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ubA_idx, 1 ) == BT_TRUE) + return; + + if ( ( mxGetN( prhs[ A_idx ] ) != 0 ) && ( mxGetN( prhs[ A_idx ] ) != nV ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Constraint matrix dimension mismatch!" ); + return; + } + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lbA,nC,1, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,1, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*(nV+nC); + + /* Check whether x0 and options are specified .*/ + if ( nrhs >= 9 ) + { + if ((!mxIsEmpty(prhs[8])) && (mxIsStruct(prhs[8]))) + setupOptions( &options,prhs[8],nWSRin,maxCpuTimeIn ); + + if ( ( nrhs >= 10 ) && ( !mxIsEmpty(prhs[9]) ) ) + { + /* auxInput specified */ + if ( mxIsStruct(prhs[9]) ) + { + auxInput_idx = 9; + x0_idx = -1; + } + else + { + auxInput_idx = -1; + x0_idx = 9; + } + } + else + { + auxInput_idx = -1; + x0_idx = -1; + } + } + } + + + /* check dimensions and copy auxInputs */ + if ( smartDimensionCheck( &x0,nV,1, BT_TRUE,prhs,x0_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( auxInput_idx >= 0 ) + setupAuxiliaryInputs( prhs[auxInput_idx],nV,nC, &hessianType,&x0,&guessedBounds,&guessedConstraints,&R_for ); + + /* convert Cholesky factor to C storage format */ + if ( R_for != 0 ) + { + R = new real_t[nV*nV]; + convertFortranToC( R_for, nV,nV, R ); + } + + /* check if QP is sparse */ + if ( H_idx >= 0 && !mxIsSparse( prhs[H_idx] ) ) + isSparse = BT_FALSE; + if ( nC > 0 && A_idx >= 0 && !mxIsSparse( prhs[A_idx] ) ) + isSparse = BT_FALSE; + + /* allocate instance */ + handle = allocateQPInstance( nV,nC,hessianType, isSimplyBoundedQp, isSparse, &options ); + globalQP = getQPInstance( handle ); + + /* make a deep-copy of the user-specified Hessian matrix (possibly sparse) */ + if ( H_idx >= 0 ) + setupHessianMatrix( prhs[H_idx],nV, &(globalQP->H),&(globalQP->Hir),&(globalQP->Hjc),&(globalQP->Hv) ); + + /* make a deep-copy of the user-specified constraint matrix (possibly sparse) */ + if ( ( nC > 0 ) && ( A_idx >= 0 ) ) + setupConstraintMatrix( prhs[A_idx],nV,nC, &(globalQP->A),&(globalQP->Air),&(globalQP->Ajc),&(globalQP->Av) ); + + /* Create output vectors and assign pointers to them. */ + allocateOutputs( nlhs,plhs, nV,nC,1,handle ); + + /* Call qpOASES. */ + if ( isSimplyBoundedQp == BT_TRUE ) + { + QProblemB_init( handle, + globalQP->H,g, + lb,ub, + nWSRin,maxCpuTimeIn, + x0,&options, + nlhs,plhs, + guessedBounds,R + ); + } + else + { + SQProblem_init( handle, + globalQP->H,g,globalQP->A, + lb,ub,lbA,ubA, + nWSRin,maxCpuTimeIn, + x0,&options, + nlhs,plhs, + guessedBounds,guessedConstraints,R + ); + } + + if (R != 0) delete R; + return; + } + + /* 2) Hotstart. */ + if ( ( strcmp( typeString,"h" ) == 0 ) || ( strcmp( typeString,"H" ) == 0 ) ) + { + /* consistency checks */ + if ( ( nlhs < 1 ) || ( nlhs > 6 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( nrhs < 5 ) || ( nrhs > 8 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + /* determine whether is it a simply bounded QP */ + if ( nrhs < 7 ) + isSimplyBoundedQp = BT_TRUE; + else + isSimplyBoundedQp = BT_FALSE; + + + if ( ( mxIsDouble( prhs[1] ) == false ) || ( mxIsScalar( prhs[1] ) == false ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Expecting a handle to QP object as second argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + /* get QP instance */ + handle = (uint_t)mxGetScalar( prhs[1] ); + globalQP = getQPInstance( handle ); + if ( globalQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return; + } + + nV = globalQP->getNV(); + + g_idx = 2; + lb_idx = 3; + ub_idx = 4; + + if (containsNaNorInf( prhs,g_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + + /* Check inputs dimensions and assign pointers to inputs. */ + if ( isSimplyBoundedQp == BT_TRUE ) + { + nC = 0; + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*nV; + + /* Check whether options are specified .*/ + if ( nrhs == 6 ) + if ( ( !mxIsEmpty( prhs[5] ) ) && ( mxIsStruct( prhs[5] ) ) ) + setupOptions( &options,prhs[5],nWSRin,maxCpuTimeIn ); + } + else + { + nC = globalQP->getNC( ); + + lbA_idx = 5; + ubA_idx = 6; + + if (containsNaNorInf( prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ubA_idx, 1 ) == BT_TRUE) + return; + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lbA,nC,1, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,1, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*(nV+nC); + + /* Check whether options are specified .*/ + if ( nrhs == 8 ) + if ( ( !mxIsEmpty( prhs[7] ) ) && ( mxIsStruct( prhs[7] ) ) ) + setupOptions( &options,prhs[7],nWSRin,maxCpuTimeIn ); + } + + /* Create output vectors and assign pointers to them. */ + allocateOutputs( nlhs,plhs, nV,nC ); + + /* call qpOASES */ + if ( isSimplyBoundedQp == BT_TRUE ) + { + QProblemB_hotstart( handle, g, + lb,ub, + nWSRin,maxCpuTimeIn, + &options, + nlhs,plhs + ); + } + else + { + QProblem_hotstart( handle, g, + lb,ub,lbA,ubA, + nWSRin,maxCpuTimeIn, + &options, + nlhs,plhs + ); + } + + return; + } + + /* 3) Modify matrices. */ + if ( ( strcmp( typeString,"m" ) == 0 ) || ( strcmp( typeString,"M" ) == 0 ) ) + { + /* consistency checks */ + if ( ( nlhs < 1 ) || ( nlhs > 6 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( nrhs < 9 ) || ( nrhs > 10 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( mxIsDouble( prhs[1] ) == false ) || ( mxIsScalar( prhs[1] ) == false ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Expecting a handle to QP object as second argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + + /* get QP instance */ + handle = (uint_t)mxGetScalar( prhs[1] ); + globalQP = getQPInstance( handle ); + if ( globalQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return; + } + + /* Check inputs dimensions and assign pointers to inputs. */ + g_idx = 3; + + if ( mxIsEmpty(prhs[2]) == 1 ) + { + H_idx = -1; + nV = (uint_t)mxGetM( prhs[ g_idx ] ); /* if Hessian is empty, row number of gradient vector */ + } + else + { + H_idx = 2; + nV = (uint_t)mxGetM( prhs[ H_idx ] ); /* row number of Hessian matrix */ + } + + A_idx = 4; + nC = (uint_t)mxGetM( prhs[ A_idx ] ); /* row number of constraint matrix */ + + lb_idx = 5; + ub_idx = 6; + lbA_idx = 7; + ubA_idx = 8; + + + /* ensure that data is given in double precision */ + if ( ( ( H_idx >= 0 ) && ( mxIsDouble( prhs[H_idx] ) == 0 ) ) || + ( mxIsDouble( prhs[g_idx] ) == 0 ) || + ( mxIsDouble( prhs[A_idx] ) == 0 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in real_t precision!" ); + return; + } + + /* check if supplied data contains 'NaN' or 'Inf' */ + if (containsNaNorInf(prhs,H_idx, 0) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,g_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,A_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ubA_idx, 1 ) == BT_TRUE) + return; + + /* Check that dimensions are consistent with existing QP instance */ + if (nV != (uint_t) globalQP->getNV () || nC != (uint_t) globalQP->getNC ()) + { + myMexErrMsgTxt( "ERROR (qpOASES): QP dimensions must be constant during a sequence! Try creating a new QP instance instead." ); + return; + } + + if ( ( H_idx >= 0 ) && ( ( mxGetN( prhs[ H_idx ] ) != nV ) || ( mxGetM( prhs[ H_idx ] ) != nV ) ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Hessian matrix dimension mismatch!" ); + return; + } + + if ( ( mxGetN( prhs[ A_idx ] ) != 0 ) && ( mxGetN( prhs[ A_idx ] ) != nV ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Constraint matrix dimension mismatch!" ); + return; + } + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lbA,nC,1, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,1, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*(nV+nC); + + /* Check whether options are specified .*/ + if ( nrhs > 9 ) + if ( ( !mxIsEmpty( prhs[9] ) ) && ( mxIsStruct( prhs[9] ) ) ) + setupOptions( &options,prhs[9],nWSRin,maxCpuTimeIn ); + + globalQP->deleteQPMatrices( ); + + /* make a deep-copy of the user-specified Hessian matrix (possibly sparse) */ + if ( H_idx >= 0 ) + setupHessianMatrix( prhs[H_idx],nV, &(globalQP->H),&(globalQP->Hir),&(globalQP->Hjc),&(globalQP->Hv) ); + + /* make a deep-copy of the user-specified constraint matrix (possibly sparse) */ + if ( ( nC > 0 ) && ( A_idx >= 0 ) ) + setupConstraintMatrix( prhs[A_idx],nV,nC, &(globalQP->A),&(globalQP->Air),&(globalQP->Ajc),&(globalQP->Av) ); + + /* Create output vectors and assign pointers to them. */ + allocateOutputs( nlhs,plhs, nV,nC ); + + /* Call qpOASES */ + SQProblem_hotstart( handle, globalQP->H,g,globalQP->A, + lb,ub,lbA,ubA, + nWSRin,maxCpuTimeIn, + &options, + nlhs,plhs + ); + + return; + } + + /* 4) Solve current equality constrained QP. */ + if ( ( strcmp( typeString,"e" ) == 0 ) || ( strcmp( typeString,"E" ) == 0 ) ) + { + /* consistency checks */ + if ( ( nlhs < 1 ) || ( nlhs > 4 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( nrhs < 7 ) || ( nrhs > 8 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( mxIsDouble( prhs[1] ) == false ) || ( mxIsScalar( prhs[1] ) == false ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Expecting a handle to QP object as second argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + /* get QP instance */ + handle = (uint_t)mxGetScalar( prhs[1] ); + globalQP = getQPInstance( handle ); + if ( globalQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return; + } + + /* Check inputs dimensions and assign pointers to inputs. */ + int_t nRHS = (int_t)mxGetN(prhs[2]); + nV = globalQP->getNV( ); + nC = globalQP->getNC( ); + real_t *x_out, *y_out; + + g_idx = 2; + lb_idx = 3; + ub_idx = 4; + lbA_idx = 5; + ubA_idx = 6; + + /* check if supplied data contains 'NaN' or 'Inf' */ + if (containsNaNorInf(prhs,g_idx, 0) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ubA_idx, 1 ) == BT_TRUE) + return; + + if ( smartDimensionCheck( &g,nV,nRHS, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,nRHS, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,nRHS, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lbA,nC,nRHS, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,nRHS, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + + /* Check whether options are specified .*/ + if ( ( nrhs == 8 ) && ( !mxIsEmpty( prhs[7] ) ) && ( mxIsStruct( prhs[7] ) ) ) + { + nWSRin = 5*(nV+nC); + setupOptions( &options,prhs[7],nWSRin,maxCpuTimeIn ); + globalQP->sqp->setOptions( options ); + } + + /* Create output vectors and assign pointers to them. */ + plhs[0] = mxCreateDoubleMatrix( nV, nRHS, mxREAL ); + x_out = mxGetPr(plhs[0]); + if (nlhs >= 2) + { + plhs[1] = mxCreateDoubleMatrix( nV+nC, nRHS, mxREAL ); + y_out = mxGetPr(plhs[1]); + + if (nlhs >= 3) + { + plhs[2] = mxCreateDoubleMatrix( nV, nRHS, mxREAL ); + real_t* workingSetB = mxGetPr(plhs[2]); + globalQP->sqp->getWorkingSetBounds(workingSetB); + + if ( nlhs >= 4 ) + { + plhs[3] = mxCreateDoubleMatrix( nC, nRHS, mxREAL ); + real_t* workingSetC = mxGetPr(plhs[3]); + globalQP->sqp->getWorkingSetConstraints(workingSetC); + } + } + } + else + y_out = new real_t[nV+nC]; + + /* Solve equality constrained QP */ + returnValue returnvalue = globalQP->sqp->solveCurrentEQP( nRHS,g,lb,ub,lbA,ubA, x_out,y_out ); + + if (nlhs < 2) + delete[] y_out; + + if (returnvalue != SUCCESSFUL_RETURN) + { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Couldn't solve current EQP (code %d)!", returnvalue); + myMexErrMsgTxt(msg); + return; + } + + return; + } + + /* 5) Cleanup. */ + if ( ( strcmp( typeString,"c" ) == 0 ) || ( strcmp( typeString,"C" ) == 0 ) ) + { + /* consistency checks */ + if ( nlhs != 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( nrhs != 2 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( mxIsDouble( prhs[1] ) == false ) || ( mxIsScalar( prhs[1] ) == false ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Expecting a handle to QP object as second argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + /* Cleanup SQProblem instance. */ + handle = (uint_t)mxGetScalar( prhs[1] ); + deleteQPInstance( handle ); + + return; + } + +} + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_sequence.m b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_sequence.m new file mode 100644 index 0000000..e064e8b --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/qpOASES_sequence.m @@ -0,0 +1,111 @@ +%qpOASES -- An Implementation of the Online Active Set Strategy. +%Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. +% +%qpOASES is distributed under the terms of the +%GNU Lesser General Public License 2.1 in the hope that it will be +%useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%See the GNU Lesser General Public License for more details. +% +%--------------------------------------------------------------------------------- +% +%qpOASES_sequence is intended to solve a sequence of quadratic +%programming (QP) problems of the following form: +% +% min 1/2*x'Hx + x'g +% s.t. lb <= x <= ub +% lbA <= Ax <= ubA {optional} +% +%I) Call +% +% [QP,x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'i',H,g,A,lb,ub,lbA,ubA{,options{,auxInput}} ) +%or +% [QP,x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'i',H,g,lb,ub{,options{,auxInput}} ) +% +%for initialising and solving the first above-mentioned QP of the sequence +%starting from an initial guess x0. H must be a symmetric (possibly indefinite) +%matrix and all vectors g, lb, ub, lbA, ubA have to be given as column vectors. +%Options can be generated using the qpOASES_options command, otherwise default +%values are used. Optionally, further auxiliary inputs may be generated +%using qpOASES_auxInput command and passed to the solver. +%Both matrices H or A may be passed in sparse matrix format. +% +%II) Call +% +% [x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'h',QP,g,lb,ub,lbA,ubA{,options} ) +%or +% [x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'h',QP,g,lb,ub{,options} ) +% +%for hotstarting from the previous QP solution to the one of the next QP +%given by the vectors g, lb, ub, lbA, ubA. Options can be generated using the +%qpOASES_options command, otherwise default values are used. +% +%III) Call +% +% [x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'm',QP,H,g,A,lb,ub,lbA,ubA{,options} ) +% +%for hotstarting from the previous QP solution to the one of the next QP +%given by the matrices H, A and the vectors g, lb, ub, lbA, ubA. The previous +%active set serves as a starting guess. If the new projected Hessian matrix +%turns out to be not positive definite, qpOASES recedes to a safe initial active +%set guess automatically. This can result in a high number of iterations iter. +%Options can be generated using the qpOASES_options command, otherwise default +%values are used. +% +%IV) Call +% +% [x,lambda,workingSetB,workingSetC] = ... +% qpOASES_sequence( 'e',QP,g,lb,ub,lbA,ubA{,options} ) +% +%for solving the equality constrained QP with constraints determined by the +%current active set. All inequalities and bounds which were not active in the +%previous solution might be violated. This command does not alter the internal +%state of qpOASES. Instead of calling this command multiple times, it is +%possible to supply several columns simultaneously in g, lb, ub, lbA, and ubA. +%Options can be generated using the qpOASES_options command, otherwise default +%values are used. +% +%V) Having solved the last QP of your sequence, call +% +% qpOASES_sequence( 'c',QP ) +% +%in order to cleanup the internal memory. +% +% +%Optional outputs (only x is mandatory): +% x - Optimal primal solution vector (if exitflag==0). +% fval - Optimal objective function value (if exitflag==0). +% exitflag - 0: QP solved, +% 1: QP could not be solved within given number of iterations, +% -1: QP could not be solved due to an internal error, +% -2: QP is infeasible (and thus could not be solved), +% -3: QP is unbounded (and thus could not be solved). +% iter - Number of active set iterations actually performed. +% lambda - Optimal dual solution vector (if exitflag==0). +% auxOutput - Struct containing auxiliary outputs as described below. +% +%The auxOutput struct contains the following entries: +% workingSetB - Working set of bounds at point x. +% workingSetC - Working set of constraints at point x. +% The working set is a subset of the active set (indices +% of bounds/constraints that hold with equality) yielding +% a set linearly independent of bounds/constraints. +% The working sets are encoded as follows: +% 1: bound/constraint at its upper bound +% 0: bound/constraint not at any bound +% -1: bound/constraint at its lower bound +% cpuTime - Internally measured CPU time for solving QP problem. +% +%See also QPOASES_OPTIONS, QPOASES_AUXINPUT, QPOASES +% +% +%For additional information see the qpOASES User's Manual or +%visit http://www.qpOASES.org/. +% +%Please send remarks and questions to support@qpOASES.org! diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/testQPset.m b/locomotion/src/third_party/qpOASES/interfaces/matlab/testQPset.m new file mode 100644 index 0000000..ebb08ca --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/testQPset.m @@ -0,0 +1,40 @@ +% Requires Lukas Schork's Matlab repository of the Maros Meszaros test set +QPsetDIR = '~/git/QPset/maros'; + +files = dir(QPsetDIR); + +options = qpOASES_options('default', ... + 'printLevel', 0, 'maxIter', 1e8, 'maxCpuTime', 60, ... + 'initialStatusBounds', 0); +nQP = 0; +for i = 1:length(files) + clear mex + try + load([QPsetDIR, '/', files(i).name]); + H = sparse(H); + A = sparse(A); + catch + continue + end + + startTime = tic; + try + [x,fval,exitflag,iter,lambda] = qpOASES(H,g,A,xl,xu,al,au,options); + catch + exitflag = 666; + iter = 666; + fval = 666; + end + elapsedTime = toc(startTime); + + if mod(nQP, 20) == 0 + fprintf('\n%-10s %6s %6s %5s %7s %15s %9s\n', ... + 'name', 'nvar', 'ncon', 'eflag', 'iter', 'fval', 'time [s]'); + end + fprintf('%-10s %6d %6d %5d %7d %15g %9g\n', ... + files(i).name(1:findstr(files(i).name, '.')-1), ... + size(A,2), size(A,1), exitflag, iter, fval, elapsedTime); + + nQP = nQP + 1; +end + diff --git a/locomotion/src/third_party/qpOASES/interfaces/matlab/testSchur.m b/locomotion/src/third_party/qpOASES/interfaces/matlab/testSchur.m new file mode 100644 index 0000000..8ac27c1 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/matlab/testSchur.m @@ -0,0 +1,16 @@ +m = 2000; +n = 2*m+1; +H = 2*speye(n); +A = 0.5*H(1:m,:); +g = zeros(n,1); +lb = -ones(n,1); +ub = -lb; +lbA = 0.5*ones(m,1); +ubA = 0.5*ones(m,1); + +options = qpOASES_options('default', 'printLevel', -1, 'maxIter', n+m+1, ... + 'enableEqualities', 0, 'initialStatusBounds', 1); + +%[x,fval,exitflag,iter,lambda] = qpOASES(full(H),g,full(A),lb,ub,lbA,ubA,options); +[x,fval,exitflag,iter,lambda] = qpOASES(H,g,A,lb,ub,lbA,ubA,options); + diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/clean b/locomotion/src/third_party/qpOASES/interfaces/octave/clean new file mode 100644 index 0000000..2957397 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/clean @@ -0,0 +1,3 @@ +rm *.*~ +rm *.o +rm qpOASES qpOASES_sequence diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/clean.sh b/locomotion/src/third_party/qpOASES/interfaces/octave/clean.sh new file mode 100644 index 0000000..2957397 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/clean.sh @@ -0,0 +1,3 @@ +rm *.*~ +rm *.o +rm qpOASES qpOASES_sequence diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/example1.mat b/locomotion/src/third_party/qpOASES/interfaces/octave/example1.mat new file mode 100644 index 0000000000000000000000000000000000000000..c0bd0d2ed4364ebaf2b16eeb1791b99510164d60 GIT binary patch literal 790 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQgHY2i?A@$QE)CwO)N=GQOM7; zQV7W?Rq#(PQBW{ZFtoHXwy-iZQZOA%wc4c5GZW8!2gYzq2v=QA4sbvTq}xwN{M9( rdcH+H=e>2)6PUUhjxboKF`MIYAV|YGPpF2pgrpzeL4oIZl~o4-!Xx*U literal 0 HcmV?d00001 diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/example1a.mat b/locomotion/src/third_party/qpOASES/interfaces/octave/example1a.mat new file mode 100644 index 0000000000000000000000000000000000000000..48c784fcb7c53eedc3b3124e3577f8d0822e1cb2 GIT binary patch literal 896 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQgHY2i?A@$QE)CwO)N=GQOM7; zQV7W?Rq#(PQBW{ZFtoHXwzM)dRWLFzFjpWIFfe-h@-r|n=m2rWoX5!t2^A%wc4c5GZW8!2gYzq2v=QA4sbvTq}xwN{M9( zdcH+H=e>2)6PUUhjxboKF`MIYAV|YGPpF2pgrpzeL4oIZl~o6%$pCIk2ePk#sWRk@ zvYq}`8INM7jZDluH5=M5@Ec?>oIk~G0n(=h*N5UdV9K1r)@ga{`O<04M`r+2CliB_ HDN`x{YE&BX literal 0 HcmV?d00001 diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/example1b.mat b/locomotion/src/third_party/qpOASES/interfaces/octave/example1b.mat new file mode 100644 index 0000000000000000000000000000000000000000..b45b4f74c6a935c350dac6de0673396f20801338 GIT binary patch literal 549 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQgHY2i?A@$QE)CwO)N=GQOM7; zQV7W?Rq#(PQBW{ZFtoHXwy-iXRWLFzFjpWIFfe-h@-r|n=m2rWoX5!t2^Gx%BvR z(CJ1KbpdXJ0|(fvIsP7&V$n literal 0 HcmV?d00001 diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/make.m b/locomotion/src/third_party/qpOASES/interfaces/octave/make.m new file mode 100644 index 0000000..a611ee0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/make.m @@ -0,0 +1,238 @@ +function [] = make( varargin ) +%MAKE Compiles the octave interface of qpOASES. +% +%Type make to compile all interfaces that +% have been modified, +%type make clean to delete all compiled interfaces, +%type make clean all to first delete and then compile +% all interfaces, +%type make 'name' to compile only the interface with +% the given name (if it has been modified), +%type make 'opt' to compile all interfaces using the +% given compiler options. +% +%Copyright (C) 2013-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. + +%% +%% This file is part of qpOASES. +%% +%% qpOASES -- An Implementation of the Online Active Set Strategy. +%% Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%% Christian Kirches et al. All rights reserved. +%% +%% qpOASES is free software; you can redistribute it and/or +%% modify it under the terms of the GNU Lesser General Public +%% License as published by the Free Software Foundation; either +%% version 2.1 of the License, or (at your option) any later version. +%% +%% qpOASES is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%% See the GNU Lesser General Public License for more details. +%% +%% You should have received a copy of the GNU Lesser General Public +%% License along with qpOASES; if not, write to the Free Software +%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +%% + +%% +%% Filename: interfaces/octave/make.m +%% Author: Hans Joachim Ferreau, Andreas Potschka, Christian Kirches +%% Version: 3.2 +%% Date: 2007-2017 +%% + + + %% consistency check + if ( exist( [pwd, '/make.m'],'file' ) == 0 ) + error( ['ERROR (',mfilename '.m): Run this make script directly within the directory', ... + '/interfaces/octave, please.'] ); + end + + + if ( nargin > 2 ) + error( ['ERROR (',mfilename '.m): At most two make arguments supported!'] ); + else + [ doClean,fcnNames,userFlags ] = analyseMakeArguments( nargin,varargin ); + end + + + %% define compiler settings + QPOASESPATH = '../../'; + + DEBUGFLAGS = ' '; + %DEBUGFLAGS = ' -g CXXDEBUGFLAGS=''$CXXDEBUGFLAGS -Wall -pedantic -Wshadow'' '; + + IFLAGS = [ '-I. -I',QPOASESPATH,'include',' -I',QPOASESPATH,'src',' ' ]; + CPPFLAGS = [ IFLAGS, DEBUGFLAGS, '-D__cpluplus -D__SINGLE_OBJECT__',' ' ]; %%removed: -largeArrayDims + defaultFlags = '-D__NO_COPYRIGHT__ '; %% -D__SUPPRESSANYOUTPUT__ %%removed: -O + + if ( ispc == 0 ) + CPPFLAGS = [ CPPFLAGS, '-DLINUX ',' ' ]; + else + CPPFLAGS = [ CPPFLAGS, '-DWIN32 ',' ' ]; + end + + if ( isempty(userFlags) > 0 ) + CPPFLAGS = [ CPPFLAGS, defaultFlags,' ' ]; + else + CPPFLAGS = [ CPPFLAGS, userFlags,' ' ]; + end + + mexExt = mexext(); + + + %% ensure copyright notice is displayed + if ~isempty( strfind( CPPFLAGS,'-D__NO_COPYRIGHT__' ) ) + printCopyrightNotice( ); + end + + + %% clean if desired + if ( doClean > 0 ) + + eval( 'delete *.o;' ); + eval( ['delete *.',mexExt,'*;'] ); + disp( [ 'INFO (',mfilename '.m): Cleaned all compiled files.'] ); + pause( 0.2 ); + + end + + + if ( ~isempty(userFlags) ) + disp( [ 'INFO (',mfilename '.m): Compiling all files with user-defined compiler flags (''',userFlags,''')...'] ); + end + + + %% call mex compiler + for ii=1:length(fcnNames) + + cmd = [ 'mkoctfile --mex --output ', fcnNames{ii}, '.', mexext(), ' ', CPPFLAGS, [fcnNames{ii},'.cpp'] ]; + + if ( exist( [fcnNames{ii},'.',mexExt],'file' ) == 0 ) + + eval( cmd ); + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' successfully created.'] ); + + else + + % check modification time of source/Make files and compiled mex file + cppFile = dir( [pwd,'/',fcnNames{ii},'.cpp'] ); + cppFileTimestamp = getTimestamp( cppFile.date ); + + utilsFile = dir( [pwd,'/qpOASES_octave_utils.cpp'] ); + utilsFileTimestamp = getTimestamp( utilsFile.date ); + + makeFile = dir( [pwd,'/make.m'] ); + makeFileTimestamp = getTimestamp( makeFile.date ); + + mexFile = dir( [pwd,'/',fcnNames{ii},'.',mexExt] ); + if ( isempty(mexFile) == 0 ) + mexFileTimestamp = getTimestamp( mexFile.date ); + else + mexFileTimestamp = 0; + end + + if ( ( cppFileTimestamp >= mexFileTimestamp ) || ... + ( utilsFileTimestamp >= mexFileTimestamp ) || ... + ( makeFileTimestamp >= mexFileTimestamp ) ) + eval( cmd ); + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' successfully created.'] ); + else + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' already exists.'] ); + end + + end + + end + + %% add qpOASES directory to path + path( path,pwd ); + +end + + +function [ doClean,fcnNames,userIFlags ] = analyseMakeArguments( nArgs,args ) + + doClean = 0; + fcnNames = []; + userIFlags = []; + + switch ( nArgs ) + + case 1 + if ( strcmp( args{1},'all' ) > 0 ) + fcnNames = { 'qpOASES','qpOASES_sequence' }; + elseif ( strcmp( args{1},'qpOASES' ) > 0 ) + fcnNames = { 'qpOASES' }; + elseif ( strcmp( args{1},'qpOASES_sequence' ) > 0 ) + fcnNames = { 'qpOASES_sequence' }; + elseif ( strcmp( args{1},'clean' ) > 0 ) + doClean = 1; + elseif ( strcmp( args{1}(1),'-' ) > 0 ) + % make clean all with user-specified compiler flags + userIFlags = args{1}; + doClean = 1; + fcnNames = { 'qpOASES','qpOASES_sequence' }; + else + error( ['ERROR (',mfilename '.m): Invalid first argument (''',args{1},''')!'] ); + end + + case 2 + if ( strcmp( args{1},'clean' ) > 0 ) + doClean = 1; + else + error( ['ERROR (',mfilename '.m): First argument must be ''clean'' if two arguments are provided!'] ); + end + + if ( strcmp( args{2},'all' ) > 0 ) + fcnNames = { 'qpOASES','qpOASES_sequence' }; + elseif ( strcmp( args{2},'qpOASES' ) > 0 ) + fcnNames = { 'qpOASES' }; + elseif ( strcmp( args{2},'qpOASES_sequence' ) > 0 ) + fcnNames = { 'qpOASES_sequence' }; + else + error( ['ERROR (',mfilename '.m): Invalid second argument (''',args{2},''')!'] ); + end + + otherwise + fcnNames = { 'qpOASES','qpOASES_sequence' }; + + end + +end + + +function [ timestamp ] = getTimestamp( dateString ) + + try + timestamp = datenum( dateString ); + catch + timestamp = Inf; + end + +end + + +function [ ] = printCopyrightNotice( ) + + disp( ' ' ); + disp( 'qpOASES -- An Implementation of the Online Active Set Strategy.' ); + disp( 'Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka,' ); + disp( 'Christian Kirches et al. All rights reserved.' ); + disp( ' ' ); + disp( 'qpOASES is distributed under the terms of the' ); + disp( 'GNU Lesser General Public License 2.1 in the hope that it will be' ); + disp( 'useful, but WITHOUT ANY WARRANTY; without even the implied warranty' ); + disp( 'of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.' ); + disp( 'See the GNU Lesser General Public License for more details.' ); + disp( ' ' ); + disp( ' ' ); + +end + + +%% +%% end of file +%% diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES.cpp b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES.cpp new file mode 100644 index 0000000..0c1fd01 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES.cpp @@ -0,0 +1,584 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/octave/qpOASES.cpp + * \author Hans Joachim Ferreau, Alexander Buchner, Andreas Potschka + * \version 3.2 + * \date 2007-2017 + * + * Interface for Matlab(R) that enables to call qpOASES as a MEX function. + * + */ + + +#include + + +USING_NAMESPACE_QPOASES + +#include "qpOASES_octave_utils.hpp" + +/** initialise handle counter of QPInstance class */ +int_t QPInstance::s_nexthandle = 1; + +/** global pointer to QP objects */ +static std::vector g_instances; + +#include "qpOASES_octave_utils.cpp" + + +/* + * Q P r o b l e m _ q p O A S E S + */ +int_t QProblem_qpOASES( int_t nV, int_t nC, HessianType hessianType, int_t nP, + SymmetricMatrix* H, double* g, Matrix* A, + double* lb, double* ub, + double* lbA, double* ubA, + int_t nWSRin, real_t maxCpuTimeIn, + const double* const x0, Options* options, + int_t nOutputs, mxArray* plhs[], + const double* const guessedBounds, const double* const guessedConstraints, + const double* const _R + ) +{ + int_t nWSRout; + real_t maxCpuTimeOut; + + /* 1) Setup initial QP. */ + QProblem QP( nV,nC,hessianType ); + QP.setOptions( *options ); + + /* 2) Solve initial QP. */ + returnValue returnvalue; + + Bounds bounds(nV); + Constraints constraints(nC); + if (guessedBounds != 0) { + for (int_t i = 0; i < nV; i++) { + if ( isEqual(guessedBounds[i],-1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_LOWER); + } else if ( isEqual(guessedBounds[i],1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_UPPER); + } else if ( isEqual(guessedBounds[i],0.0) == BT_TRUE ) { + bounds.setupBound(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of bounds!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + if (guessedConstraints != 0) { + for (int_t i = 0; i < nC; i++) { + if ( isEqual(guessedConstraints[i],-1.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_LOWER); + } else if ( isEqual(guessedConstraints[i],1.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_UPPER); + } else if ( isEqual(guessedConstraints[i],0.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of constraints!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + nWSRout = nWSRin; + maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + returnvalue = QP.init( H,g,A,lb,ub,lbA,ubA, + nWSRout,&maxCpuTimeOut, + x0,0, + (guessedBounds != 0) ? &bounds : 0, (guessedConstraints != 0) ? &constraints : 0, + _R + ); + + /* 3) Solve remaining QPs and assign lhs arguments. */ + /* Set up pointers to the current QP vectors */ + real_t* g_current = g; + real_t* lb_current = lb; + real_t* ub_current = ub; + real_t* lbA_current = lbA; + real_t* ubA_current = ubA; + + /* Loop through QP sequence. */ + for ( int_t k=0; k 0 ) + { + /* update pointers to the current QP vectors */ + g_current = &(g[k*nV]); + if ( lb != 0 ) + lb_current = &(lb[k*nV]); + if ( ub != 0 ) + ub_current = &(ub[k*nV]); + if ( lbA != 0 ) + lbA_current = &(lbA[k*nC]); + if ( ubA != 0 ) + ubA_current = &(ubA[k*nC]); + + nWSRout = nWSRin; + maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + returnvalue = QP.hotstart( g_current,lb_current,ub_current,lbA_current,ubA_current, nWSRout,&maxCpuTimeOut ); + } + + /* write results into output vectors */ + obtainOutputs( k,&QP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,nC ); + } + + //QP.writeQpDataIntoMatFile( "qpDataMat0.mat" ); + + return 0; +} + + + +/* + * Q P r o b l e m B _ q p O A S E S + */ +int_t QProblemB_qpOASES( int_t nV, HessianType hessianType, int_t nP, + SymmetricMatrix *H, double* g, + double* lb, double* ub, + int_t nWSRin, real_t maxCpuTimeIn, + const double* const x0, Options* options, + int_t nOutputs, mxArray* plhs[], + const double* const guessedBounds, + const double* const _R + ) +{ + int_t nWSRout; + real_t maxCpuTimeOut; + + /* 1) Setup initial QP. */ + QProblemB QP( nV,hessianType ); + QP.setOptions( *options ); + + /* 2) Solve initial QP. */ + returnValue returnvalue; + + Bounds bounds(nV); + if (guessedBounds != 0) { + for (int_t i = 0; i < nV; i++) { + if ( isEqual(guessedBounds[i],-1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_LOWER); + } else if ( isEqual(guessedBounds[i],1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_UPPER); + } else if ( isEqual(guessedBounds[i],0.0) == BT_TRUE ) { + bounds.setupBound(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of bounds!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + nWSRout = nWSRin; + maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + returnvalue = QP.init( H,g,lb,ub, + nWSRout,&maxCpuTimeOut, + x0,0, + (guessedBounds != 0) ? &bounds : 0, + _R + ); + + /* 3) Solve remaining QPs and assign lhs arguments. */ + /* Set up pointers to the current QP vectors */ + real_t* g_current = g; + real_t* lb_current = lb; + real_t* ub_current = ub; + + /* Loop through QP sequence. */ + for ( int_t k=0; k 0 ) + { + /* update pointers to the current QP vectors */ + g_current = &(g[k*nV]); + if ( lb != 0 ) + lb_current = &(lb[k*nV]); + if ( ub != 0 ) + ub_current = &(ub[k*nV]); + + nWSRout = nWSRin; + maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + returnvalue = QP.hotstart( g_current,lb_current,ub_current, nWSRout,&maxCpuTimeOut ); + } + + /* write results into output vectors */ + obtainOutputs( k,&QP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV ); + } + + return 0; +} + + + +/* + * m e x F u n c t i o n + */ +void mexFunction( int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[] ) +{ + /* inputs */ + SymmetricMatrix *H=0; + Matrix *A=0; + + real_t *g=0, *lb=0, *ub=0, *lbA=0, *ubA=0; + HessianType hessianType = HST_UNKNOWN; + double *x0=0, *R=0, *R_for=0; + double *guessedBounds=0, *guessedConstraints=0; + + int H_idx=-1, g_idx=-1, A_idx=-1, lb_idx=-1, ub_idx=-1, lbA_idx=-1, ubA_idx=-1; + int options_idx=-1, x0_idx=-1, auxInput_idx=-1; + + /* Setup default options */ + Options options; + options.printLevel = PL_LOW; + #ifdef __DEBUG__ + options.printLevel = PL_HIGH; + #endif + #ifdef __SUPPRESSANYOUTPUT__ + options.printLevel = PL_NONE; + #endif + + /* dimensions */ + uint_t nV=0, nC=0, nP=0; + BooleanType isSimplyBoundedQp = BT_FALSE; + + /* sparse matrix indices and values */ + sparse_int_t *Hir=0, *Hjc=0, *Air=0, *Ajc=0; + real_t *Hv=0, *Av=0; + + /* I) CONSISTENCY CHECKS: */ + /* 1a) Ensure that qpOASES is called with a feasible number of input arguments. */ + if ( ( nrhs < 4 ) || ( nrhs > 9 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES' for further information." ); + return; + } + + /* 2) Check for proper number of output arguments. */ + if ( nlhs > 6 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): At most six output arguments are allowed: \n [x,fval,exitflag,iter,lambda,auxOutput]!" ); + return; + } + if ( nlhs < 1 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): At least one output argument is required: [x,...]!" ); + return; + } + + + /* II) PREPARE RESPECTIVE QPOASES FUNCTION CALL: */ + /* Choose between QProblem and QProblemB object and assign the corresponding + * indices of the input pointer array in to order to access QP data correctly. */ + g_idx = 1; + + if ( mxIsEmpty(prhs[0]) == 1 ) + { + H_idx = -1; + nV = (int_t)mxGetM( prhs[ g_idx ] ); /* if Hessian is empty, row number of gradient vector */ + } + else + { + H_idx = 0; + nV = (int_t)mxGetM( prhs[ H_idx ] ); /* row number of Hessian matrix */ + } + + nP = (int_t)mxGetN( prhs[ g_idx ] ); /* number of columns of the gradient matrix (vectors series have to be stored columnwise!) */ + + if ( nrhs <= 6 ) + isSimplyBoundedQp = BT_TRUE; + else + isSimplyBoundedQp = BT_FALSE; + + + /* 0) Check whether options are specified .*/ + if ( isSimplyBoundedQp == BT_TRUE ) + { + if ( ( nrhs >= 5 ) && ( !mxIsEmpty(prhs[4]) ) && ( mxIsStruct(prhs[4]) ) ) + options_idx = 4; + } + else + { + /* Consistency check */ + if ( ( !mxIsEmpty(prhs[4]) ) && ( mxIsStruct(prhs[4]) ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Fifth input argument must not be a struct when solving QP with general constraints!\nType 'help qpOASES' for further information." ); + return; + } + + if ( ( nrhs >= 8 ) && ( !mxIsEmpty(prhs[7]) ) && ( mxIsStruct(prhs[7]) ) ) + options_idx = 7; + } + + // Is the third argument constraint Matrix A? + int_t numberOfColumns = (int_t)mxGetN(prhs[2]); + + /* 1) Simply bounded QP. */ + if ( ( isSimplyBoundedQp == BT_TRUE ) || + ( ( numberOfColumns == 1 ) && ( nV != 1 ) ) ) + { + lb_idx = 2; + ub_idx = 3; + + if ( ( nrhs >= 6 ) && ( !mxIsEmpty(prhs[5]) ) ) + { + /* auxInput specified */ + if ( mxIsStruct(prhs[5]) ) + { + auxInput_idx = 5; + x0_idx = -1; + } + else + { + auxInput_idx = -1; + x0_idx = 5; + } + } + else + { + auxInput_idx = -1; + x0_idx = -1; + } + } + else + { + A_idx = 2; + + /* If constraint matrix is empty, use a QProblemB object! */ + if ( mxIsEmpty( prhs[ A_idx ] ) ) + { + lb_idx = 3; + ub_idx = 4; + + nC = 0; + } + else + { + lb_idx = 3; + ub_idx = 4; + lbA_idx = 5; + ubA_idx = 6; + + nC = (int_t)mxGetM( prhs[ A_idx ] ); /* row number of constraint matrix */ + } + + if ( ( nrhs >= 9 ) && ( !mxIsEmpty(prhs[8]) ) ) + { + /* auxInput specified */ + if ( mxIsStruct(prhs[8]) ) + { + auxInput_idx = 8; + x0_idx = -1; + } + else + { + auxInput_idx = -1; + x0_idx = 8; + } + } + else + { + auxInput_idx = -1; + x0_idx = -1; + } + } + + + /* ensure that data is given in real_t precision */ + if ( ( ( H_idx >= 0 ) && ( mxIsDouble( prhs[ H_idx ] ) == 0 ) ) || + ( mxIsDouble( prhs[ g_idx ] ) == 0 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in double precision!" ); + return; + } + + /* check if supplied data contains 'NaN' or 'Inf' */ + if (containsNaNorInf( prhs,H_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,g_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + /* Check inputs dimensions and assign pointers to inputs. */ + if ( ( H_idx >= 0 ) && ( ( mxGetN( prhs[ H_idx ] ) != nV ) || ( mxGetM( prhs[ H_idx ] ) != nV ) ) ) + { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Hessian matrix dimension mismatch (%ld != %d)!", + (long int)mxGetN(prhs[H_idx]), (int)nV); + myMexErrMsgTxt(msg); + return; + } + + if ( nC > 0 ) + { + /* ensure that data is given in real_t precision */ + if ( mxIsDouble( prhs[ A_idx ] ) == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in real_t precision!" ); + return; + } + + /* Check inputs dimensions and assign pointers to inputs. */ + if ( mxGetN( prhs[ A_idx ] ) != nV ) + { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Constraint matrix input dimension mismatch (%ld != %d)!", + (long int)mxGetN(prhs[A_idx]), (int)nV); + myMexErrMsgTxt(msg); + return; + } + + if (containsNaNorInf(prhs,A_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf(prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf(prhs,ubA_idx, 1 ) == BT_TRUE) + return; + } + + /* check dimensions and copy auxInputs */ + if ( smartDimensionCheck( &g,nV,nP, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,nP, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,nP, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &x0,nV,1, BT_TRUE,prhs,x0_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( nC > 0 ) + { + if ( smartDimensionCheck( &lbA,nC,nP, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,nP, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + } + + if ( auxInput_idx >= 0 ) + setupAuxiliaryInputs( prhs[auxInput_idx],nV,nC, &hessianType,&x0,&guessedBounds,&guessedConstraints,&R_for ); + + /* convert Cholesky factor to C storage format */ + if ( R_for != 0 ) + { + R = new real_t[nV*nV]; + convertFortranToC( R_for, nV,nV, R ); + } + + /* III) ACTUALLY PERFORM QPOASES FUNCTION CALL: */ + int_t nWSRin = 5*(nV+nC); + real_t maxCpuTimeIn = -1.0; + + if ( options_idx > 0 ) + setupOptions( &options,prhs[options_idx],nWSRin,maxCpuTimeIn ); + + /* make a deep-copy of the user-specified Hessian matrix (possibly sparse) */ + if ( H_idx >= 0 ) + setupHessianMatrix( prhs[H_idx],nV, &H,&Hir,&Hjc,&Hv ); + + /* make a deep-copy of the user-specified constraint matrix (possibly sparse) */ + if ( ( nC > 0 ) && ( A_idx >= 0 ) ) + setupConstraintMatrix( prhs[A_idx],nV,nC, &A,&Air,&Ajc,&Av ); + + allocateOutputs( nlhs,plhs,nV,nC,nP ); + + if ( nC == 0 ) + { + /* Call qpOASES (using QProblemB class). */ + QProblemB_qpOASES( nV,hessianType, nP, + H,g, + lb,ub, + nWSRin,maxCpuTimeIn, + x0,&options, + nlhs,plhs, + guessedBounds,R + ); + + if (R != 0) delete R; + if (H != 0) delete H; + if (Hv != 0) delete[] Hv; + if (Hjc != 0) delete[] Hjc; + if (Hir != 0) delete[] Hir; + return; + } + else + { + if ( A == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Internal interface error related to constraint matrix!" ); + return; + } + + /* Call qpOASES (using QProblem class). */ + QProblem_qpOASES( nV,nC,hessianType, nP, + H,g,A, + lb,ub,lbA,ubA, + nWSRin,maxCpuTimeIn, + x0,&options, + nlhs,plhs, + guessedBounds,guessedConstraints,R + ); + + if (R != 0) delete R; + if (A != 0) delete A; + if (H != 0) delete H; + if (Av != 0) delete[] Av; + if (Ajc != 0) delete[] Ajc; + if (Air != 0) delete[] Air; + if (Hv != 0) delete[] Hv; + if (Hjc != 0) delete[] Hjc; + if (Hir != 0) delete[] Hir; + return; + } +} + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES.m b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES.m new file mode 100644 index 0000000..88f4df9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES.m @@ -0,0 +1,75 @@ +%qpOASES -- An Implementation of the Online Active Set Strategy. +%Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. +% +%qpOASES is distributed under the terms of the +%GNU Lesser General Public License 2.1 in the hope that it will be +%useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%See the GNU Lesser General Public License for more details. +% +%--------------------------------------------------------------------------------- +% +%qpOASES solves (a series) of quadratic programming (QP) problems of the +%following form: +% +% min 1/2*x'Hx + x'g +% s.t. lb <= x <= ub +% lbA <= Ax <= ubA {optional} +% +%Call +% +% [x,fval,exitflag,iter,lambda,auxOutput] = +% qpOASES( H,g,A,lb,ub,lbA,ubA{,options{,auxInput}} ) +% +%for solving the above-mentioned QP. H must be a symmetric (but possibly +%indefinite) matrix and all vectors g, lb, ub, lbA, ubA have to be given +%as column vectors. Options can be generated using the qpOASES_options command, +%otherwise default values are used. Optionally, further auxiliary inputs +%may be generated using qpOASES_auxInput command and passed to the solver. +%Both matrices H or A may be passed in sparse matrix format. +% +%Call +% +% [x,fval,exitflag,iter,lambda,auxOutput] = +% qpOASES( H,g,lb,ub{,options{,auxInput}} ) +% +%for solving the above-mentioned QP without general constraints. +% +% +%Optional outputs (only x is mandatory): +% x - Optimal primal solution vector (if exitflag==0). +% fval - Optimal objective function value (if exitflag==0). +% exitflag - 0: QP problem solved, +% 1: QP could not be solved within given number of iterations, +% -1: QP could not be solved due to an internal error, +% -2: QP is infeasible (and thus could not be solved), +% -3: QP is unbounded (and thus could not be solved). +% iter - Number of active set iterations actually performed. +% lambda - Optimal dual solution vector (if exitflag==0). +% auxOutput - Struct containing auxiliary outputs as described below. +% +%The auxOutput struct contains the following entries: +% workingSetB - Working set of bounds at point x. +% workingSetC - Working set of constraints at point x. +% The working set is a subset of the active set (indices +% of bounds/constraints that hold with equality) yielding +% a set linearly independent of bounds/constraints. +% The working sets are encoded as follows: +% 1: bound/constraint at its upper bound +% 0: bound/constraint not at any bound +% -1: bound/constraint at its lower bound +% cpuTime - Internally measured CPU time for solving QP problem. +% +% +%If not a single QP but a sequence of QPs with varying vectors is to be solved, +%the i-th QP is given by the i-th columns of the QP vectors g, lb, ub, lbA, ubA +%(i.e. they are matrices in this case). Both matrices H and A remain constant. +% +%See also QPOASES_OPTIONS, QPOASES_AUXINPUT, QPOASES_SEQUENCE +% +% +%For additional information see the qpOASES User's Manual or +%visit http://www.qpOASES.org/. +% +%Please send remarks and questions to support@qpOASES.org! diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_auxInput.m b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_auxInput.m new file mode 100644 index 0000000..1ebb8d9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_auxInput.m @@ -0,0 +1,118 @@ +%qpOASES -- An Implementation of the Online Active Set Strategy. +%Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. +% +%qpOASES is distributed under the terms of the +%GNU Lesser General Public License 2.1 in the hope that it will be +%useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%See the GNU Lesser General Public License for more details. +% +%--------------------------------------------------------------------------------- +% +%Returns a struct containing all possible auxiliary inputs to be passed +%to qpOASES. +% +%Call +% auxInput = qpOASES_auxInput(); +%to obtain a struct with all auxiliary inputs empty. +% +%Call +% auxInput = qpOASES_auxInput( 'input1',value1,'input2',value2,... ) +%to obtain a struct with 'input1' set to value1 etc. and all remaining +%auxiliary inputs empty. +% +%Call +% auxInput = qpOASES_auxInput( oldInputs,'input1',value1,... ) +%to obtain a copy of the options struct oldInputs but with 'input1' set to +%value1 etc. +% +% +%qpOASES features the following auxiliary inputs: +% hessianType - Provide information on Hessian matrix: +% 0: Hessian is zero matrix (i.e. LP formulation) +% 1: Hessian is identity matrix +% 2: Hessian is (strictly) positive definite +% 3: Hessian is positive definite on null space +% of active bounds/constraints +% 4: Hessian is positive semi-definite. +% 5: Hessian is indefinite +% Leave hessianType empty if Hessian type is unknown. +% x0 - Initial guess for optimal primal solution. +% guessedWorkingSetB - Initial guess for working set of bounds at +% optimal solution (nV elements or empty). +% guessedWorkingSetC - Initial guess for working set of constraints at +% optimal solution (nC elements or empty). +% The working sets needs to be encoded as follows: +% 1: bound/constraint at its upper bound +% 0: bound/constraint not at any bound +% -1: bound/constraint at its lower bound +% R - Cholesky factor of Hessian matrix (upper-triangular); +% only used if both guessedWorkingSets are empty +% and option initialStatusBounds is set to 0. +% +% +%See also QPOASES, QPOASES_SEQUENCE, QPOASES_OPTIONS +% +% +%For additional information see the qpOASES User's Manual or +%visit http://www.qpOASES.org/. +% +%Please send remarks and questions to support@qpOASES.org! +function [ auxInput ] = qpOASES_auxInput( varargin ) + + firstIsStruct = 0; + + if ( nargin == 0 ) + auxInput = qpOASES_emptyAuxInput(); + else + if ( isstruct( varargin{1} ) ) + if ( mod( nargin,2 ) ~= 1 ) + error('ERROR (qpOASES_auxInput): Auxiliary inputs must be specified in pairs!'); + end + auxInput = varargin{1}; + firstIsStruct = 1; + else + if ( mod( nargin,2 ) ~= 0 ) + error('ERROR (qpOASES_auxInput): Auxiliary inputs must be specified in pairs!'); + end + auxInput = qpOASES_emptyAuxInput(); + end + end + + % set options to user-defined values + for i=(1+firstIsStruct):2:nargin + + argName = varargin{i}; + argValue = varargin{i+1}; + + if ( ( isempty( argName ) ) || ( ~ischar( argName ) ) ) + error('ERROR (qpOASES_auxInput): Argmument no. %d has to be a non-empty string!',i ); + end + + if ( ( ischar(argValue) ) || ( ~isnumeric( argValue ) ) ) + error('ERROR (qpOASES_auxInput): Argmument no. %d has to be a numerical constant!',i+1 ); + end + + if ( ~isfield( auxInput,argName ) ) + error('ERROR (qpOASES_auxInput): Argmument no. %d is not a valid auxiliary input!',i ); + end + + eval( ['auxInput.',argName,' = argValue;'] ); + + end + +end + + +function [ auxInput ] = qpOASES_emptyAuxInput( ) + + % setup auxiliary input struct with all entries empty + auxInput = struct( 'hessianType', [], ... + 'x0', [], ... + 'guessedWorkingSetB', [], ... + 'guessedWorkingSetC', [], ... + 'R', [] ... + ); + +end diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_octave_utils.cpp b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_octave_utils.cpp new file mode 100644 index 0000000..bc48616 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_octave_utils.cpp @@ -0,0 +1,950 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/octave/qpOASES_octave_utils.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Alexander Buchner + * \version 3.2 + * \date 2007-2017 + * + * Collects utility functions for Interface to octave that + * enables to call qpOASES as a MEX function. + * + */ + + + +QPInstance::QPInstance( uint_t _nV, uint_t _nC, HessianType _hessianType, + BooleanType _isSimplyBounded + ) +{ + handle = s_nexthandle++; + + if ( _nC > 0 ) + isSimplyBounded = BT_FALSE; + else + isSimplyBounded = _isSimplyBounded; + + if ( isSimplyBounded == BT_TRUE ) + { + sqp = 0; + qpb = new QProblemB( _nV,_hessianType ); + } + else + { + sqp = new SQProblem( _nV,_nC,_hessianType ); + qpb = 0; + } + + H = 0; + A = 0; + Hir = 0; + Hjc = 0; + Air = 0; + Ajc = 0; + Hv = 0; + Av = 0; +} + + +QPInstance::~QPInstance( ) +{ + deleteQPMatrices(); + + if ( sqp != 0 ) + { + delete sqp; + sqp = 0; + } + + if ( qpb != 0 ) + { + delete qpb; + qpb = 0; + } +} + + +returnValue QPInstance::deleteQPMatrices( ) +{ + if ( H != 0 ) + { + delete H; + H = 0; + } + + if ( Hv != 0 ) + { + delete[] Hv; + Hv = 0; + } + + if ( Hjc != 0 ) + { + delete[] Hjc; + Hjc = 0; + } + + if ( Hir != 0 ) + { + delete[] Hir; + Hir = 0; + } + + if ( A != 0 ) + { + delete A; + A = 0; + } + + if ( Av != 0 ) + { + delete[] Av; + Av = 0; + } + + if ( Ajc != 0 ) + { + delete[] Ajc; + Ajc = 0; + } + + if ( Air != 0 ) + { + delete[] Air; + Air = 0; + } + + return SUCCESSFUL_RETURN; +} + + +int_t QPInstance::getNV() const +{ + if ( sqp != 0 ) + return sqp->getNV(); + + if ( qpb != 0 ) + return qpb->getNV(); + + return 0; +} + + +int_t QPInstance::getNC() const +{ + if ( sqp != 0 ) + return sqp->getNC(); + + return 0; +} + + + +/* + * m x I s S c a l a r + */ +bool mxIsScalar( const mxArray *pm ) +{ + if ( ( mxGetM(pm) == 1 ) && ( mxGetN(pm) == 1 ) ) + return true; + else + return false; +} + + + +/* + * a l l o c a t e Q P r o b l e m I n s t a n c e + */ +int_t allocateQPInstance( int_t nV, int_t nC, HessianType hessianType, + BooleanType isSimplyBounded, const Options* options + ) +{ + QPInstance* inst = new QPInstance( nV,nC,hessianType, isSimplyBounded ); + + if ( ( inst->sqp != 0 ) && ( options != 0 ) ) + inst->sqp->setOptions( *options ); + + if ( ( inst->qpb != 0 ) && ( options != 0 ) ) + inst->qpb->setOptions( *options ); + + g_instances.push_back(inst); + return inst->handle; +} + + +/* + * g e t Q P r o b l e m I n s t a n c e + */ +QPInstance* getQPInstance( int_t handle ) +{ + uint_t ii; + // TODO: this may become slow ... + for (ii = 0; ii < g_instances.size (); ++ii) + if (g_instances[ii]->handle == handle) + return g_instances[ii]; + return 0; +} + + +/* + * d e l e t e Q P r o b l e m I n s t a n c e + */ +void deleteQPInstance( int_t handle ) +{ + QPInstance *instance = getQPInstance (handle); + if (instance != 0) { + for (std::vector::iterator itor = g_instances.begin (); + itor != g_instances.end (); ++itor) + if ((*itor)->handle == handle) { + g_instances.erase (itor); + break; + } + delete instance; + } +} + + + +/* + * s m a r t D i m e n s i o n C h e c k + */ +returnValue smartDimensionCheck( real_t** input, uint_t m, uint_t n, BooleanType emptyAllowed, + const mxArray* prhs[], int_t idx + ) +{ + /* If index is negative, the input does not exist. */ + if ( idx < 0 ) + { + *input = 0; + return SUCCESSFUL_RETURN; + } + + /* Otherwise the input has been passed by the user. */ + if ( mxIsEmpty( prhs[ idx ] ) ) + { + /* input is empty */ + if ( ( emptyAllowed == BT_TRUE ) || ( idx == 0 ) ) /* idx==0 used for auxInput */ + { + *input = 0; + return SUCCESSFUL_RETURN; + } + else + { + char msg[MAX_STRING_LENGTH]; + if ( idx > 0 ) + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Empty argument %d not allowed!", idx+1); + myMexErrMsgTxt( msg ); + return RET_INVALID_ARGUMENTS; + } + } + else + { + /* input is non-empty */ + if ( mxIsSparse( prhs[ idx ] ) == 0 ) + { + if ( ( mxGetM( prhs[ idx ] ) == m ) && ( mxGetN( prhs[ idx ] ) == n ) ) + { + *input = (real_t*) mxGetPr( prhs[ idx ] ); + return SUCCESSFUL_RETURN; + } + else + { + char msg[MAX_STRING_LENGTH]; + if ( idx > 0 ) + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Input dimension mismatch for argument %d ([%ld,%ld] ~= [%d,%d]).", + idx+1, (long int)mxGetM(prhs[idx]), (long int)mxGetN(prhs[idx]), (int)m,(int)n); + else /* idx==0 used for auxInput */ + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Input dimension mismatch for some auxInput entry ([%ld,%ld] ~= [%d,%d]).", + (long int)mxGetM(prhs[idx]), (long int)mxGetN(prhs[idx]), (int)m,(int)n); + myMexErrMsgTxt( msg ); + return RET_INVALID_ARGUMENTS; + } + } + else + { + char msg[MAX_STRING_LENGTH]; + if ( idx > 0 ) + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Vector argument %d must not be in sparse format!", idx+1); + else /* idx==0 used for auxInput */ + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): auxInput entries must not be in sparse format!" ); + myMexErrMsgTxt( msg ); + return RET_INVALID_ARGUMENTS; + } + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * c o n t a i n s N a N + */ +BooleanType containsNaN( const real_t* const data, uint_t dim ) +{ + uint_t i; + + if ( data == 0 ) + return BT_FALSE; + + for ( i = 0; i < dim; ++i ) + if ( mxIsNaN(data[i]) == 1 ) + return BT_TRUE; + + return BT_FALSE; +} + + +/* + * c o n t a i n s I n f + */ +BooleanType containsInf( const real_t* const data, uint_t dim ) +{ + uint_t i; + + if ( data == 0 ) + return BT_FALSE; + + for ( i = 0; i < dim; ++i ) + if ( mxIsInf(data[i]) == 1 ) + return BT_TRUE; + + return BT_FALSE; +} + + +/* + * c o n t a i n s N a N o r I n f + */ +BooleanType containsNaNorInf( const mxArray* prhs[], int_t rhs_index, + bool mayContainInf + ) +{ + uint_t dim; + char msg[MAX_STRING_LENGTH]; + + if ( rhs_index < 0 ) + return BT_FALSE; + + /* overwrite dim for sparse matrices */ + if (mxIsSparse(prhs[rhs_index]) == 1) + dim = (uint_t)mxGetNzmax(prhs[rhs_index]); + else + dim = (uint_t)(mxGetM(prhs[rhs_index]) * mxGetN(prhs[rhs_index])); + + if (containsNaN((real_t*) mxGetPr(prhs[rhs_index]), dim) == BT_TRUE) { + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Argument %d contains 'NaN' !", rhs_index + 1); + myMexErrMsgTxt(msg); + return BT_TRUE; + } + + if (mayContainInf == 0) { + if (containsInf((real_t*) mxGetPr(prhs[rhs_index]), dim) == BT_TRUE) { + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Argument %d contains 'Inf' !", + rhs_index + 1); + myMexErrMsgTxt(msg); + return BT_TRUE; + } + } + + return BT_FALSE; +} + + +/* + * c o n v e r t F o r t r a n T o C + */ +returnValue convertFortranToC( const real_t* const M_for, int_t nV, int_t nC, real_t* const M ) +{ + int_t i,j; + + if ( ( M_for == 0 ) || ( M == 0 ) ) + return RET_INVALID_ARGUMENTS; + + if ( ( nV < 0 ) || ( nC < 0 ) ) + return RET_INVALID_ARGUMENTS; + + for ( i=0; i = ; */ + if ( mxGetNumberOfFields(optionsPtr) != 31 ) + mexWarnMsgTxt( "Options might be set incorrectly as struct has wrong number of entries!\n Type 'help qpOASES_options' for further information." ); + + + if ( hasOptionsValue( optionsPtr,"maxIter",&optionValue ) == BT_TRUE ) + if ( *optionValue >= 0.0 ) + nWSRin = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"maxCpuTime",&optionValue ) == BT_TRUE ) + if ( *optionValue >= 0.0 ) + maxCpuTime = *optionValue; + + if ( hasOptionsValue( optionsPtr,"printLevel",&optionValue ) == BT_TRUE ) + { + #ifdef __SUPPRESSANYOUTPUT__ + options->printLevel = PL_NONE; + #else + optionValueInt = (int_t)*optionValue; + options->printLevel = (REFER_NAMESPACE_QPOASES PrintLevel)optionValueInt; + if ( options->printLevel < PL_DEBUG_ITER ) + options->printLevel = PL_DEBUG_ITER; + if ( options->printLevel > PL_HIGH ) + options->printLevel = PL_HIGH; + #endif + } + + if ( hasOptionsValue( optionsPtr,"enableRamping",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableRamping = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableFarBounds",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableFarBounds = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableFlippingBounds",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableFlippingBounds = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableRegularisation",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableRegularisation = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableFullLITests",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableFullLITests = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableNZCTests",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableNZCTests = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"enableDriftCorrection",&optionValue ) == BT_TRUE ) + options->enableDriftCorrection = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"enableCholeskyRefactorisation",&optionValue ) == BT_TRUE ) + options->enableCholeskyRefactorisation = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"enableEqualities",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + options->enableEqualities = (REFER_NAMESPACE_QPOASES BooleanType)optionValueInt; + } + + + if ( hasOptionsValue( optionsPtr,"terminationTolerance",&optionValue ) == BT_TRUE ) + options->terminationTolerance = *optionValue; + + if ( hasOptionsValue( optionsPtr,"boundTolerance",&optionValue ) == BT_TRUE ) + options->boundTolerance = *optionValue; + + if ( hasOptionsValue( optionsPtr,"boundRelaxation",&optionValue ) == BT_TRUE ) + options->boundRelaxation = *optionValue; + + if ( hasOptionsValue( optionsPtr,"epsNum",&optionValue ) == BT_TRUE ) + options->epsNum = *optionValue; + + if ( hasOptionsValue( optionsPtr,"epsDen",&optionValue ) == BT_TRUE ) + options->epsDen = *optionValue; + + if ( hasOptionsValue( optionsPtr,"maxPrimalJump",&optionValue ) == BT_TRUE ) + options->maxPrimalJump = *optionValue; + + if ( hasOptionsValue( optionsPtr,"maxDualJump",&optionValue ) == BT_TRUE ) + options->maxDualJump = *optionValue; + + + if ( hasOptionsValue( optionsPtr,"initialRamping",&optionValue ) == BT_TRUE ) + options->initialRamping = *optionValue; + + if ( hasOptionsValue( optionsPtr,"finalRamping",&optionValue ) == BT_TRUE ) + options->finalRamping = *optionValue; + + if ( hasOptionsValue( optionsPtr,"initialFarBounds",&optionValue ) == BT_TRUE ) + options->initialFarBounds = *optionValue; + + if ( hasOptionsValue( optionsPtr,"growFarBounds",&optionValue ) == BT_TRUE ) + options->growFarBounds = *optionValue; + + if ( hasOptionsValue( optionsPtr,"initialStatusBounds",&optionValue ) == BT_TRUE ) + { + optionValueInt = (int_t)*optionValue; + if ( optionValueInt < -1 ) + optionValueInt = -1; + if ( optionValueInt > 1 ) + optionValueInt = 1; + options->initialStatusBounds = (REFER_NAMESPACE_QPOASES SubjectToStatus)optionValueInt; + } + + if ( hasOptionsValue( optionsPtr,"epsFlipping",&optionValue ) == BT_TRUE ) + options->epsFlipping = *optionValue; + + if ( hasOptionsValue( optionsPtr,"numRegularisationSteps",&optionValue ) == BT_TRUE ) + options->numRegularisationSteps = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"epsRegularisation",&optionValue ) == BT_TRUE ) + options->epsRegularisation = *optionValue; + + if ( hasOptionsValue( optionsPtr,"numRefinementSteps",&optionValue ) == BT_TRUE ) + options->numRefinementSteps = (int_t)*optionValue; + + if ( hasOptionsValue( optionsPtr,"epsIterRef",&optionValue ) == BT_TRUE ) + options->epsIterRef = *optionValue; + + if ( hasOptionsValue( optionsPtr,"epsLITests",&optionValue ) == BT_TRUE ) + options->epsLITests = *optionValue; + + if ( hasOptionsValue( optionsPtr,"epsNZCTests",&optionValue ) == BT_TRUE ) + options->epsNZCTests = *optionValue; + + return SUCCESSFUL_RETURN; +} + + + +/* + * s e t u p A u x i l i a r y I n p u t s + */ +returnValue setupAuxiliaryInputs( const mxArray* auxInput, uint_t nV, uint_t nC, + HessianType* hessianType, double** x0, double** guessedBounds, double** guessedConstraints, double** R + ) +{ + mxArray* curField = 0; + + /* hessianType */ + curField = mxGetField( auxInput,0,"hessianType" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'hessianType'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + if ( mxIsEmpty(curField) == true ) + { + *hessianType = HST_UNKNOWN; + } + else + { + if ( mxIsScalar(curField) == false ) + return RET_INVALID_ARGUMENTS; + + double* hessianTypeTmp = mxGetPr(curField); + int_t hessianTypeInt = (int_t)*hessianTypeTmp; + if ( hessianTypeInt < 0 ) + hessianTypeInt = 6; /* == HST_UNKNOWN */ + if ( hessianTypeInt > 5 ) + hessianTypeInt = 6; /* == HST_UNKNOWN */ + *hessianType = (REFER_NAMESPACE_QPOASES HessianType)hessianTypeInt; + } + } + + /* x0 */ + curField = mxGetField( auxInput,0,"x0" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'x0'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + *x0 = mxGetPr(curField); + if ( smartDimensionCheck( x0,nV,1, BT_TRUE,((const mxArray**)&curField),0 ) != SUCCESSFUL_RETURN ) + return RET_INVALID_ARGUMENTS; + } + + /* guessedWorkingSetB */ + curField = mxGetField( auxInput,0,"guessedWorkingSetB" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'guessedWorkingSetB'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + *guessedBounds = mxGetPr(curField); + if ( smartDimensionCheck( guessedBounds,nV,1, BT_TRUE,((const mxArray**)&curField),0 ) != SUCCESSFUL_RETURN ) + return RET_INVALID_ARGUMENTS; + } + + /* guessedWorkingSetC */ + curField = mxGetField( auxInput,0,"guessedWorkingSetC" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'guessedWorkingSetC'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + *guessedConstraints = mxGetPr(curField); + if ( smartDimensionCheck( guessedConstraints,nC,1, BT_TRUE,((const mxArray**)&curField),0 ) != SUCCESSFUL_RETURN ) + return RET_INVALID_ARGUMENTS; + } + + /* R */ + curField = mxGetField( auxInput,0,"R" ); + if ( curField == NULL ) + mexWarnMsgTxt( "auxInput struct does not contain entry 'R'!\n Type 'help qpOASES_auxInput' for further information." ); + else + { + *R = mxGetPr(curField); + if ( smartDimensionCheck( R,nV,nV, BT_TRUE,((const mxArray**)&curField),0 ) != SUCCESSFUL_RETURN ) + return RET_INVALID_ARGUMENTS; + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * a l l o c a t e O u t p u t s + */ +returnValue allocateOutputs( int nlhs, mxArray* plhs[], int_t nV, int_t nC = 0, int_t nP = 1, int_t handle = -1 + ) +{ + /* Create output vectors and assign pointers to them. */ + int_t curIdx = 0; + + /* handle */ + if ( handle >= 0 ) + plhs[curIdx++] = mxCreateDoubleMatrix( 1, 1, mxREAL ); + + /* x */ + plhs[curIdx++] = mxCreateDoubleMatrix( nV, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* fval */ + plhs[curIdx++] = mxCreateDoubleMatrix( 1, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* exitflag */ + plhs[curIdx++] = mxCreateDoubleMatrix( 1, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* iter */ + plhs[curIdx++] = mxCreateDoubleMatrix( 1, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* lambda */ + plhs[curIdx++] = mxCreateDoubleMatrix( nV+nC, nP, mxREAL ); + + if ( nlhs > curIdx ) + { + /* setup auxiliary output struct */ + mxArray* auxOutput = mxCreateStructMatrix( 1,1,0,0 ); + int_t curFieldNum; + + /* working set */ + curFieldNum = mxAddField( auxOutput,"workingSetB" ); + if ( curFieldNum >= 0 ) + mxSetFieldByNumber( auxOutput,0,curFieldNum,mxCreateDoubleMatrix( nV, nP, mxREAL ) ); + + curFieldNum = mxAddField( auxOutput,"workingSetC" ); + if ( curFieldNum >= 0 ) + mxSetFieldByNumber( auxOutput,0,curFieldNum,mxCreateDoubleMatrix( nC, nP, mxREAL ) ); + + curFieldNum = mxAddField( auxOutput,"cpuTime" ); + if ( curFieldNum >= 0 ) + mxSetFieldByNumber( auxOutput,0,curFieldNum,mxCreateDoubleMatrix( 1, nP, mxREAL ) ); + + plhs[curIdx] = auxOutput; + } + } + } + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * o b t a i n O u t p u t s + */ +returnValue obtainOutputs( int_t k, QProblemB* qp, returnValue returnvalue, int_t _nWSRout, double _cpuTime, + int nlhs, mxArray* plhs[], int_t nV, int_t nC = 0, int_t handle = -1 + ) +{ + /* Create output vectors and assign pointers to them. */ + int_t curIdx = 0; + + /* handle */ + if ( handle >= 0 ) + plhs[curIdx++] = mxCreateDoubleScalar( handle ); + + /* x */ + double* x = mxGetPr( plhs[curIdx++] ); + qp->getPrimalSolution( &(x[k*nV]) ); + + if ( nlhs > curIdx ) + { + /* fval */ + double* obj = mxGetPr( plhs[curIdx++] ); + obj[k] = qp->getObjVal( ); + + if ( nlhs > curIdx ) + { + /* exitflag */ + double* status = mxGetPr( plhs[curIdx++] ); + status[k] = (double)getSimpleStatus( returnvalue ); + + if ( nlhs > curIdx ) + { + /* iter */ + double* nWSRout = mxGetPr( plhs[curIdx++] ); + nWSRout[k] = (double) _nWSRout; + + if ( nlhs > curIdx ) + { + /* lambda */ + double* y = mxGetPr( plhs[curIdx++] ); + qp->getDualSolution( &(y[k*(nV+nC)]) ); + + /* auxOutput */ + if ( nlhs > curIdx ) + { + QProblem* problemPointer; + problemPointer = dynamic_cast(qp); + + mxArray* auxOutput = plhs[curIdx]; + mxArray* curField = 0; + + /* working set bounds */ + if ( nV > 0 ) + { + curField = mxGetField( auxOutput,0,"workingSetB" ); + double* workingSetB = mxGetPr(curField); + + /* cast successful? */ + if (problemPointer != NULL) { + problemPointer->getWorkingSetBounds( &(workingSetB[k*nV]) ); + } else { + qp->getWorkingSetBounds( &(workingSetB[k*nV]) ); + } + } + + /* working set constraints */ + if ( nC > 0 ) + { + curField = mxGetField( auxOutput,0,"workingSetC" ); + double* workingSetC = mxGetPr(curField); + + /* cast successful? */ + if (problemPointer != NULL) { + problemPointer->getWorkingSetConstraints( &(workingSetC[k*nC]) ); + } else { + qp->getWorkingSetConstraints( &(workingSetC[k*nC]) ); + } + } + + /* cpu time */ + curField = mxGetField( auxOutput,0,"cpuTime" ); + double* cpuTime = mxGetPr(curField); + cpuTime[0] = (double) _cpuTime; + } + } + } + } + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * s e t u p H e s s i a n M a t r i x + */ +returnValue setupHessianMatrix( const mxArray* prhsH, int_t nV, + SymmetricMatrix** H, sparse_int_t** Hir, sparse_int_t** Hjc, real_t** Hv + ) +{ + if ( prhsH == 0 ) + return SUCCESSFUL_RETURN; + + if ( mxIsSparse( prhsH ) != 0 ) + { + mwIndex *mat_ir = mxGetIr( prhsH ); + mwIndex *mat_jc = mxGetJc( prhsH ); + double *v = (double*)mxGetPr( prhsH ); + long nfill = 0; + mwIndex i, j; + BooleanType needInsertDiag; + + /* copy indices to avoid 64/32-bit integer confusion */ + /* also add explicit zeros on diagonal for regularization strategy */ + /* copy values, too */ + *Hir = new sparse_int_t[mat_jc[nV] + nV]; + *Hjc = new sparse_int_t[nV+1]; + *Hv = new real_t[mat_jc[nV] + nV]; + for (j = 0; j < nV; j++) + { + needInsertDiag = BT_TRUE; + + (*Hjc)[j] = (sparse_int_t)(mat_jc[j]) + nfill; + /* fill up to diagonal */ + for (i = mat_jc[j]; i < mat_jc[j+1]; i++) + { + if ( mat_ir[i] == j ) + needInsertDiag = BT_FALSE; + + /* add zero diagonal element if not present */ + if ( ( mat_ir[i] > j ) && ( needInsertDiag == BT_TRUE ) ) + { + (*Hir)[i + nfill] = (sparse_int_t)j; + (*Hv)[i + nfill] = 0.0; + nfill++; + /* only add diag once */ + needInsertDiag = BT_FALSE; + } + + (*Hir)[i + nfill] = (sparse_int_t)(mat_ir[i]); + (*Hv)[i + nfill] = (real_t)(v[i]); + } + } + (*Hjc)[nV] = (sparse_int_t)(mat_jc[nV]) + nfill; + + SymSparseMat *sH; + *H = sH = new SymSparseMat(nV, nV, *Hir, *Hjc, *Hv); + sH->createDiagInfo(); + } + else + { + /* make a deep-copy in order to avoid modifying input data when regularising */ + real_t* H_for = (real_t*) mxGetPr( prhsH ); + real_t* H_mem = new real_t[nV*nV]; + memcpy( H_mem,H_for, nV*nV*sizeof(real_t) ); + + *H = new SymDenseMat( nV,nV,nV, H_mem ); + (*H)->doFreeMemory( ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p C o n s t r a i n t M a t r i x + */ +returnValue setupConstraintMatrix( const mxArray* prhsA, int_t nV, int_t nC, + Matrix** A, sparse_int_t** Air, sparse_int_t** Ajc, real_t** Av + ) +{ + if ( prhsA == 0 ) + return SUCCESSFUL_RETURN; + + if ( mxIsSparse( prhsA ) != 0 ) + { + mwIndex i; + long j; + + mwIndex *mat_ir = mxGetIr( prhsA ); + mwIndex *mat_jc = mxGetJc( prhsA ); + double *v = (double*)mxGetPr( prhsA ); + + /* copy indices to avoid 64/32-bit integer confusion */ + *Air = new sparse_int_t[mat_jc[nV]]; + *Ajc = new sparse_int_t[nV+1]; + for (i = 0; i < mat_jc[nV]; i++) + (*Air)[i] = (sparse_int_t)(mat_ir[i]); + for (i = 0; i < nV + 1; i++) + (*Ajc)[i] = (sparse_int_t)(mat_jc[i]); + + /* copy values, too */ + *Av = new real_t[(*Ajc)[nV]]; + for (j = 0; j < (*Ajc)[nV]; j++) + (*Av)[j] = (real_t)(v[j]); + + *A = new SparseMatrix(nC, nV, *Air, *Ajc, *Av); + } + else + { + /* Convert constraint matrix A from FORTRAN to C style + * (not necessary for H as it should be symmetric!). */ + real_t* A_for = (real_t*) mxGetPr( prhsA ); + real_t* A_mem = new real_t[nC*nV]; + convertFortranToC( A_for,nV,nC, A_mem ); + *A = new DenseMatrix(nC, nV, nV, A_mem ); + (*A)->doFreeMemory(); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_octave_utils.hpp b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_octave_utils.hpp new file mode 100644 index 0000000..0d77895 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_octave_utils.hpp @@ -0,0 +1,93 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/octave/qpOASES_octave_utils.hpp + * \author Hans Joachim Ferreau, Andreas Potschka, Alexander Buchner + * \version 3.2 + * \date 2007-2017 + * + * Collects utility functions for Interface to octave that + * enables to call qpOASES as a MEX function. + * + */ + + + +/* Work-around for settings where mexErrMsgTxt causes unexpected behaviour. */ +#ifdef __AVOID_MEXERRMSGTXT__ + #define myMexErrMsgTxt( TEXT ) mexPrintf( "%s\n\n",(TEXT) ); +#else + #define myMexErrMsgTxt mexErrMsgTxt +#endif + + +#include "mex.h" +/* #include "matrix.h" */ +#include "string.h" +#include + + +/* + * QProblem instance class + */ +class QPInstance +{ + private: + static int_t s_nexthandle; + + public: + QPInstance( uint_t _nV = 0, + uint_t _nC = 0, + HessianType _hessianType = HST_UNKNOWN, + BooleanType _isSimplyBounded = BT_FALSE + ); + + ~QPInstance( ); + + returnValue deleteQPMatrices(); + + int_t getNV() const; + int_t getNC() const; + + int_t handle; + + SQProblem* sqp; + QProblemB* qpb; + BooleanType isSimplyBounded; + + SymmetricMatrix* H; + Matrix* A; + sparse_int_t* Hir; + sparse_int_t* Hjc; + sparse_int_t* Air; + sparse_int_t* Ajc; + real_t* Hv; + real_t* Av; +}; + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_options.m b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_options.m new file mode 100644 index 0000000..0cccf95 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_options.m @@ -0,0 +1,251 @@ +%qpOASES -- An Implementation of the Online Active Set Strategy. +%Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. +% +%qpOASES is distributed under the terms of the +%GNU Lesser General Public License 2.1 in the hope that it will be +%useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%See the GNU Lesser General Public License for more details. +% +%--------------------------------------------------------------------------------- +% +%Returns a struct containing values for all options to be used within qpOASES. +% +%Call +% options = qpOASES_options( 'default' ); +% options = qpOASES_options( 'reliable' ); +% options = qpOASES_options( 'MPC' ); +%to obtain a set of default options or a pre-defined set of options tuned +%for reliable or fast QP solution, respectively. +% +%Call +% options = qpOASES_options( 'option1',value1,'option2',value2,... ) +%to obtain a set of default options but with 'option1' set to value1 etc. +% +%Call +% options = qpOASES_options( oldOptions,'option1',value1,... ) +%to obtain a copy of the options struct oldOptions but with 'option1' set +%to value1 etc. +% +%Call +% options = qpOASES_options( 'default', 'option1',value1,... ) +% options = qpOASES_options( 'reliable','option1',value1,... ) +% options = qpOASES_options( 'MPC', 'option1',value1,... ) +%to obtain a set of default options or a pre-defined set of options tuned +%for reliable or fast QP solution, respectively, but with 'option1' set to +%value1 etc. +% +% +%qpOASES features the following options: +% maxIter - Maximum number of iterations (if set +% to -1, a value is chosen heuristically) +% maxCpuTime - Maximum CPU time in seconds (if set +% to -1, only iteration limit is used) +% printLevel - 0: no printed output, +% 1: only error messages are printed, +% 2: iterations and error messages are printed, +% 3: all available messages are printed. +% +% enableRamping - Enables (1) or disables (0) ramping. +% enableFarBounds - Enables (1) or disables (0) the use of +% far bounds. +% enableFlippingBounds - Enables (1) or disables (0) the use of +% flipping bounds. +% enableRegularisation - Enables (1) or disables (0) automatic +% Hessian regularisation. +% enableFullLITests - Enables (1) or disables (0) condition-hardened +% (but more expensive) LI test. +% enableNZCTests - Enables (1) or disables (0) nonzero curvature +% tests. +% enableDriftCorrection - Specifies the frequency of drift corrections: +% 0: turns them off, +% 1: uses them at each iteration etc. +% enableCholeskyRefactorisation - Specifies the frequency of a full re- +% factorisation of projected Hessian matrix: +% 0: turns them off, +% 1: uses them at each iteration etc. +% enableEqualities - Specifies whether equalities should be treated +% as always active (1) or not (0) +% +% terminationTolerance - Relative termination tolerance to stop homotopy. +% boundTolerance - If upper and lower bounds differ less than this +% tolerance, they are regarded equal, i.e. as +% equality constraint. +% boundRelaxation - Initial relaxation of bounds to start homotopy +% and initial value for far bounds. +% epsNum - Numerator tolerance for ratio tests. +% epsDen - Denominator tolerance for ratio tests. +% maxPrimalJump - Maximum allowed jump in primal variables in +% nonzero curvature tests. +% maxDualJump - Maximum allowed jump in dual variables in +% linear independence tests. +% +% initialRamping - Start value for ramping strategy. +% finalRamping - Final value for ramping strategy. +% initialFarBounds - Initial size for far bounds. +% growFarBounds - Factor to grow far bounds. +% initialStatusBounds - Initial status of bounds at first iteration: +% 0: all bounds inactive, +% -1: all bounds active at their lower bound, +% +1: all bounds active at their upper bound. +% epsFlipping - Tolerance of squared Cholesky diagonal factor +% which triggers flipping bound. +% numRegularisationSteps - Maximum number of successive regularisation steps. +% epsRegularisation - Scaling factor of identity matrix used for +% Hessian regularisation. +% numRefinementSteps - Maximum number of iterative refinement steps. +% epsIterRef - Early termination tolerance for iterative +% refinement. +% epsLITests - Tolerance for linear independence tests. +% epsNZCTests - Tolerance for nonzero curvature tests. +% +% +%See also QPOASES, QPOASES_SEQUENCE, QPOASES_AUXINPUT +% +% +%For additional information see the qpOASES User's Manual or +%visit http://www.qpOASES.org/. +% +%Please send remarks and questions to support@qpOASES.org! +function [ options ] = qpOASES_options( varargin ) + + firstIsStructOrScheme = 0; + + if ( nargin == 0 ) + options = qpOASES_default_options(); + else + if ( isstruct( varargin{1} ) ) + if ( mod( nargin,2 ) ~= 1 ) + error('ERROR (qpOASES_options): Options must be specified in pairs!'); + end + options = varargin{1}; + firstIsStructOrScheme = 1; + else + if ( ischar( varargin{1} ) ) + if ( mod( nargin,2 ) == 0 ) + options = qpOASES_default_options(); + else + if ( ( nargin > 1 ) && ( ischar( varargin{nargin} ) ) ) + error('ERROR (qpOASES_options): Options must be specified in pairs!'); + end + + switch ( varargin{1} ) + case 'default' + options = qpOASES_default_options(); + case 'reliable' + options = qpOASES_reliable_options(); + case {'MPC','mpc','fast'} + options = qpOASES_MPC_options(); + otherwise + error( ['ERROR (qpOASES_options): Only the following option schemes are defined: ''default'', ''reliable'', ''MPC''!'] ); + + end + firstIsStructOrScheme = 1; + end + else + error('ERROR (qpOASES_options): First argument needs to be a string or an options struct!'); + end + end + end + + % set options to user-defined values + for i=(1+firstIsStructOrScheme):2:nargin + + argName = varargin{i}; + argValue = varargin{i+1}; + + if ( ( isempty( argName ) ) || ( ~ischar( argName ) ) ) + error('ERROR (qpOASES_options): Argmument no. %d has to be a non-empty string!',i ); + end + + if ( ( ischar(argValue) ) || ( ~isscalar( argValue ) ) ) + error('ERROR (qpOASES_options): Argmument no. %d has to be a scalar constant!',i+1 ); + end + + if ( ~isfield( options,argName ) ) + error('ERROR (qpOASES_options): Argmument no. %d is an invalid option!',i ); + end + + eval( ['options.',argName,' = ',num2str(argValue),';'] ); + + end + +end + + +function [ options ] = qpOASES_default_options( ) + + % setup options struct with default values + options = struct( 'maxIter', -1, ... + 'maxCpuTime', -1, ... + 'printLevel', 1, ... + ... + 'enableRamping', 1, ... + 'enableFarBounds', 1, ... + 'enableFlippingBounds', 1, ... + 'enableRegularisation', 0, ... + 'enableFullLITests', 0, ... + 'enableNZCTests', 1, ... + 'enableDriftCorrection', 1, ... + 'enableCholeskyRefactorisation', 0, ... + 'enableEqualities', 0, ... + ... + 'terminationTolerance', 5.0e6*eps, ... + 'boundTolerance', 1.0e6*eps, ... + 'boundRelaxation', 1.0e4, ... + 'epsNum', -1.0e3*eps, ... + 'epsDen', 1.0e3*eps, ... + 'maxPrimalJump', 1.0e8, ... + 'maxDualJump', 1.0e8, ... + ... + 'initialRamping', 0.5, ... + 'finalRamping', 1.0, ... + 'initialFarBounds', 1.0e6, ... + 'growFarBounds', 1.0e3, ... + 'initialStatusBounds', -1, ... + 'epsFlipping', 1.0e3*eps, ... + 'numRegularisationSteps', 0, ... + 'epsRegularisation', 1.0e3*eps, ... + 'numRefinementSteps', 1, ... + 'epsIterRef', 1.0e2*eps, ... + 'epsLITests', 1.0e5*eps, ... + 'epsNZCTests', 3.1e3*eps ); + +end + + + +function [ options ] = qpOASES_reliable_options( ) + + % setup options struct with values for most reliable QP solution + options = qpOASES_default_options( ); + + options.enableFullLITests = 1; + options.enableCholeskyRefactorisation = 1; + + options.numRefinementSteps = 2; + +end + + +function [ options ] = qpOASES_MPC_options( ) + + % setup options struct with values for most reliable QP solution + options = qpOASES_default_options( ); + + options.enableRamping = 0; + options.enableFarBounds = 1; + options.enableFlippingBounds = 0; + options.enableRegularisation = 1; + options.enableNZCTests = 0; + options.enableDriftCorrection = 0; + options.enableEqualities = 1; + + options.terminationTolerance = 1.0e9*eps; + + options.initialStatusBounds = 0; + options.numRegularisationSteps = 1; + options.numRefinementSteps = 0; + +end diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_sequence.cpp b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_sequence.cpp new file mode 100644 index 0000000..7ddfa32 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_sequence.cpp @@ -0,0 +1,1104 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/octave/qpOASES_sequence.cpp + * \author Hans Joachim Ferreau, Christian Kirches, Andreas Potschka, Alexander Buchner + * \version 3.2 + * \date 2007-2017 + * + * Interface for octave that enables to call qpOASES as a MEX function + * (variant for solving QP sequences). + * + */ + + + +#include + + +USING_NAMESPACE_QPOASES + + +#include "qpOASES_octave_utils.hpp" + +/** initialise handle counter of QPInstance class */ +int_t QPInstance::s_nexthandle = 1; + +/** global pointer to QP objects */ +static std::vector g_instances; + +#include "qpOASES_octave_utils.cpp" + + +/* + * Q P r o b l e m B _ i n i t + */ +int_t QProblemB_init( int_t handle, + SymmetricMatrix* H, real_t* g, + const real_t* const lb, const real_t* const ub, + int_t nWSRin, real_t maxCpuTimeIn, + const double* const x0, Options* options, + int_t nOutputs, mxArray* plhs[], + const double* const guessedBounds, + const double* const _R + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + /* 1) setup initial QP. */ + QProblemB* globalQPB = getQPInstance(handle)->qpb; + + if ( globalQPB == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return -1; + } + + globalQPB->setOptions( *options ); + + /* 2) Solve initial QP. */ + returnValue returnvalue; + int_t nV = globalQPB->getNV(); + + /* 3) Fill the working set. */ + Bounds bounds(nV); + if (guessedBounds != 0) { + for (int_t i = 0; i < nV; i++) { + if ( isEqual(guessedBounds[i],-1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_LOWER); + } else if ( isEqual(guessedBounds[i],1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_UPPER); + } else if ( isEqual(guessedBounds[i],0.0) == BT_TRUE ) { + bounds.setupBound(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of bounds!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + returnvalue = globalQPB->init( H,g,lb,ub, + nWSRout,&maxCpuTimeOut, + x0,0, + (guessedBounds != 0) ? &bounds : 0, + _R + ); + + /* 3) Assign lhs arguments. */ + obtainOutputs( 0,globalQPB,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,0,handle ); + + return 0; +} + + +/* + * S Q P r o b l e m _ i n i t + */ +int_t SQProblem_init( int_t handle, + SymmetricMatrix* H, real_t* g, Matrix* A, + const real_t* const lb, const real_t* const ub, + const real_t* const lbA, const real_t* const ubA, + int_t nWSRin, real_t maxCpuTimeIn, + const double* const x0, Options* options, + int_t nOutputs, mxArray* plhs[], + const double* const guessedBounds, const double* const guessedConstraints, + const double* const _R + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + /* 1) setup initial QP. */ + SQProblem* globalSQP = getQPInstance(handle)->sqp; + + if ( globalSQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return -1; + } + + globalSQP->setOptions( *options ); + + /* 2) Solve initial QP. */ + returnValue returnvalue; + int_t nV = globalSQP->getNV(); + int_t nC = globalSQP->getNC(); + + /* 3) Fill the working set. */ + Bounds bounds(nV); + Constraints constraints(nC); + if (guessedBounds != 0) { + for (int_t i = 0; i < nV; i++) { + if ( isEqual(guessedBounds[i],-1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_LOWER); + } else if ( isEqual(guessedBounds[i],1.0) == BT_TRUE ) { + bounds.setupBound(i, ST_UPPER); + } else if ( isEqual(guessedBounds[i],0.0) == BT_TRUE ) { + bounds.setupBound(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of bounds!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + if (guessedConstraints != 0) { + for (int_t i = 0; i < nC; i++) { + if ( isEqual(guessedConstraints[i],-1.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_LOWER); + } else if ( isEqual(guessedConstraints[i],1.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_UPPER); + } else if ( isEqual(guessedConstraints[i],0.0) == BT_TRUE ) { + constraints.setupConstraint(i, ST_INACTIVE); + } else { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, + "ERROR (qpOASES): Only {-1, 0, 1} allowed for status of constraints!"); + myMexErrMsgTxt(msg); + return -1; + } + } + } + + returnvalue = globalSQP->init( H,g,A,lb,ub,lbA,ubA, + nWSRout,&maxCpuTimeOut, + x0,0, + (guessedBounds != 0) ? &bounds : 0, (guessedConstraints != 0) ? &constraints : 0, + _R + ); + + /* 3) Assign lhs arguments. */ + obtainOutputs( 0,globalSQP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,nC,handle ); + + return 0; +} + + + +/* + * Q P r o b l e m B _ h o t s t a r t + */ +int_t QProblemB_hotstart( int_t handle, + const real_t* const g, + const real_t* const lb, const real_t* const ub, + int_t nWSRin, real_t maxCpuTimeIn, + Options* options, + int_t nOutputs, mxArray* plhs[] + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + QProblemB* globalQPB = getQPInstance(handle)->qpb; + + if ( globalQPB == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): QP needs to be initialised first!" ); + return -1; + } + + int_t nV = globalQPB->getNV(); + + /* 1) Solve QP with given options. */ + globalQPB->setOptions( *options ); + returnValue returnvalue = globalQPB->hotstart( g,lb,ub, nWSRout,&maxCpuTimeOut ); + + /* 2) Assign lhs arguments. */ + obtainOutputs( 0,globalQPB,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,0 ); + + return 0; +} + + +/* + * Q P r o b l e m _ h o t s t a r t + */ +int_t QProblem_hotstart( int_t handle, + const real_t* const g, + const real_t* const lb, const real_t* const ub, + const real_t* const lbA, const real_t* const ubA, + int_t nWSRin, real_t maxCpuTimeIn, + Options* options, + int_t nOutputs, mxArray* plhs[] + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + QProblem* globalSQP = getQPInstance(handle)->sqp; + + if ( globalSQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): QP needs to be initialised first!" ); + return -1; + } + + int_t nV = globalSQP->getNV(); + int_t nC = globalSQP->getNC(); + + /* 1) Solve QP with given options. */ + globalSQP->setOptions( *options ); + returnValue returnvalue = globalSQP->hotstart( g,lb,ub,lbA,ubA, nWSRout,&maxCpuTimeOut ); + + /* 2) Assign lhs arguments. */ + obtainOutputs( 0,globalSQP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,nC ); + + return 0; +} + + +/* + * S Q P r o b l e m _ h o t s t a r t + */ +int_t SQProblem_hotstart( int_t handle, + SymmetricMatrix* H, real_t* g, Matrix* A, + const real_t* const lb, const real_t* const ub, const real_t* const lbA, const real_t* const ubA, + int_t nWSRin, real_t maxCpuTimeIn, + Options* options, + int_t nOutputs, mxArray* plhs[] + ) +{ + int_t nWSRout = nWSRin; + real_t maxCpuTimeOut = (maxCpuTimeIn >= 0.0) ? maxCpuTimeIn : INFTY; + + SQProblem* globalSQP = getQPInstance(handle)->sqp; + + if ( globalSQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): QP needs to be initialised first!" ); + return -1; + } + + int_t nV = globalSQP->getNV(); + int_t nC = globalSQP->getNC(); + + /* 1) Solve QP. */ + globalSQP->setOptions( *options ); + returnValue returnvalue = globalSQP->hotstart( H,g,A,lb,ub,lbA,ubA, nWSRout,&maxCpuTimeOut ); + + switch (returnvalue) + { + case SUCCESSFUL_RETURN: + case RET_QP_UNBOUNDED: + case RET_QP_INFEASIBLE: + break; + + default: + myMexErrMsgTxt( "ERROR (qpOASES): Hotstart failed." ); + return -1; + } + + /* 2) Assign lhs arguments. */ + obtainOutputs( 0,globalSQP,returnvalue,nWSRout,maxCpuTimeOut, + nOutputs,plhs,nV,nC ); + + return 0; +} + + + +/* + * m e x F u n c t i o n + */ +void mexFunction( int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[] ) +{ + /* inputs */ + char typeString[2]; + + real_t *g=0, *lb=0, *ub=0, *lbA=0, *ubA=0; + HessianType hessianType = HST_UNKNOWN; + double *x0=0, *R=0, *R_for=0; + double *guessedBounds=0, *guessedConstraints=0; + + int_t H_idx=-1, g_idx=-1, A_idx=-1, lb_idx=-1, ub_idx=-1, lbA_idx=-1, ubA_idx=-1; + int_t x0_idx=-1, auxInput_idx=-1; + + BooleanType isSimplyBoundedQp = BT_FALSE; + + Options options; + options.printLevel = PL_LOW; + #ifdef __DEBUG__ + options.printLevel = PL_HIGH; + #endif + #ifdef __SUPPRESSANYOUTPUT__ + options.printLevel = PL_NONE; + #endif + + /* dimensions */ + uint_t nV=0, nC=0, handle=0; + int_t nWSRin; + real_t maxCpuTimeIn = -1.0; + QPInstance* globalQP = 0; + + /* I) CONSISTENCY CHECKS: */ + /* 1) Ensure that qpOASES is called with a feasible number of input arguments. */ + if ( ( nrhs < 5 ) || ( nrhs > 10 ) ) + { + if ( nrhs != 2 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + } + + /* 2) Ensure that first input is a string ... */ + if ( mxIsChar( prhs[0] ) != 1 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): First input argument must be a string!" ); + return; + } + + mxGetString( prhs[0], typeString, 2 ); + + /* ... and if so, check if it is an allowed one. */ + if ( ( strcmp( typeString,"i" ) != 0 ) && ( strcmp( typeString,"I" ) != 0 ) && + ( strcmp( typeString,"h" ) != 0 ) && ( strcmp( typeString,"H" ) != 0 ) && + ( strcmp( typeString,"m" ) != 0 ) && ( strcmp( typeString,"M" ) != 0 ) && + ( strcmp( typeString,"e" ) != 0 ) && ( strcmp( typeString,"E" ) != 0 ) && + ( strcmp( typeString,"c" ) != 0 ) && ( strcmp( typeString,"C" ) != 0 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Undefined first input argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + + /* II) SELECT RESPECTIVE QPOASES FUNCTION CALL: */ + /* 1) Init (without or with initial guess for primal solution). */ + if ( ( strcmp( typeString,"i" ) == 0 ) || ( strcmp( typeString,"I" ) == 0 ) ) + { + /* consistency checks */ + if ( ( nlhs < 1 ) || ( nlhs > 7 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( nrhs < 5 ) || ( nrhs > 10 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + g_idx = 2; + + if ( mxIsEmpty(prhs[1]) == 1 ) + { + H_idx = -1; + nV = (uint_t)mxGetM( prhs[ g_idx ] ); /* row number of Hessian matrix */ + } + else + { + H_idx = 1; + nV = (uint_t)mxGetM( prhs[ H_idx ] ); /* row number of Hessian matrix */ + } + + + /* ensure that data is given in double precision */ + if ( ( ( H_idx >= 0 ) && ( mxIsDouble( prhs[ H_idx ] ) == 0 ) ) || + ( mxIsDouble( prhs[ g_idx ] ) == 0 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in double precision!" ); + return; + } + + if ( ( H_idx >= 0 ) && ( ( mxGetN( prhs[ H_idx ] ) != nV ) || ( mxGetM( prhs[ H_idx ] ) != nV ) ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Hessian matrix dimension mismatch!" ); + return; + } + + + /* Check for 'Inf' and 'Nan' in Hessian */ + if (containsNaNorInf( prhs,H_idx, 0 ) == BT_TRUE) + return; + + /* Check for 'Inf' and 'Nan' in gradient */ + if (containsNaNorInf(prhs,g_idx, 0 ) == BT_TRUE) + return; + + /* determine whether is it a simply bounded QP */ + if ( nrhs <= 7 ) + isSimplyBoundedQp = BT_TRUE; + else + isSimplyBoundedQp = BT_FALSE; + + if ( isSimplyBoundedQp == BT_TRUE ) + { + lb_idx = 3; + ub_idx = 4; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + /* Check inputs dimensions and assign pointers to inputs. */ + nC = 0; /* row number of constraint matrix */ + + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,2 ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,3 ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,4 ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*nV; + + /* Check whether x0 and options are specified .*/ + if ( nrhs >= 6 ) + { + if ((!mxIsEmpty(prhs[5])) && (mxIsStruct(prhs[5]))) + setupOptions( &options,prhs[5],nWSRin,maxCpuTimeIn ); + + if ( ( nrhs >= 7 ) && ( !mxIsEmpty(prhs[6]) ) ) + { + /* auxInput specified */ + if ( mxIsStruct(prhs[6]) ) + { + auxInput_idx = 6; + x0_idx = -1; + } + else + { + auxInput_idx = -1; + x0_idx = 6; + } + } + else + { + auxInput_idx = -1; + x0_idx = -1; + } + } + } + else + { + A_idx = 3; + + /* ensure that data is given in double precision */ + if ( mxIsDouble( prhs[ A_idx ] ) == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in double precision!" ); + return; + } + + /* Check inputs dimensions and assign pointers to inputs. */ + nC = (uint_t)mxGetM( prhs[ A_idx ] ); /* row number of constraint matrix */ + + lb_idx = 4; + ub_idx = 5; + lbA_idx = 6; + ubA_idx = 7; + + if (containsNaNorInf( prhs,A_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ubA_idx, 1 ) == BT_TRUE) + return; + + if ( ( mxGetN( prhs[ A_idx ] ) != 0 ) && ( mxGetN( prhs[ A_idx ] ) != nV ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Constraint matrix dimension mismatch!" ); + return; + } + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lbA,nC,1, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,1, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*(nV+nC); + + /* Check whether x0 and options are specified .*/ + if ( nrhs >= 9 ) + { + if ((!mxIsEmpty(prhs[8])) && (mxIsStruct(prhs[8]))) + setupOptions( &options,prhs[8],nWSRin,maxCpuTimeIn ); + + if ( ( nrhs >= 10 ) && ( !mxIsEmpty(prhs[9]) ) ) + { + /* auxInput specified */ + if ( mxIsStruct(prhs[9]) ) + { + auxInput_idx = 9; + x0_idx = -1; + } + else + { + auxInput_idx = -1; + x0_idx = 9; + } + } + else + { + auxInput_idx = -1; + x0_idx = -1; + } + } + } + + + /* check dimensions and copy auxInputs */ + if ( smartDimensionCheck( &x0,nV,1, BT_TRUE,prhs,x0_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( auxInput_idx >= 0 ) + setupAuxiliaryInputs( prhs[auxInput_idx],nV,nC, &hessianType,&x0,&guessedBounds,&guessedConstraints,&R_for ); + + /* convert Cholesky factor to C storage format */ + if ( R_for != 0 ) + { + R = new real_t[nV*nV]; + convertFortranToC( R_for, nV,nV, R ); + } + + /* allocate instance */ + handle = allocateQPInstance( nV,nC,hessianType, isSimplyBoundedQp,&options ); + globalQP = getQPInstance( handle ); + + /* make a deep-copy of the user-specified Hessian matrix (possibly sparse) */ + if ( H_idx >= 0 ) + setupHessianMatrix( prhs[H_idx],nV, &(globalQP->H),&(globalQP->Hir),&(globalQP->Hjc),&(globalQP->Hv) ); + + /* make a deep-copy of the user-specified constraint matrix (possibly sparse) */ + if ( ( nC > 0 ) && ( A_idx >= 0 ) ) + setupConstraintMatrix( prhs[A_idx],nV,nC, &(globalQP->A),&(globalQP->Air),&(globalQP->Ajc),&(globalQP->Av) ); + + /* Create output vectors and assign pointers to them. */ + allocateOutputs( nlhs,plhs, nV,nC,1,handle ); + + /* Call qpOASES. */ + if ( isSimplyBoundedQp == BT_TRUE ) + { + QProblemB_init( handle, + globalQP->H,g, + lb,ub, + nWSRin,maxCpuTimeIn, + x0,&options, + nlhs,plhs, + guessedBounds,R + ); + } + else + { + SQProblem_init( handle, + globalQP->H,g,globalQP->A, + lb,ub,lbA,ubA, + nWSRin,maxCpuTimeIn, + x0,&options, + nlhs,plhs, + guessedBounds,guessedConstraints,R + ); + } + + if (R != 0) delete R; + return; + } + + /* 2) Hotstart. */ + if ( ( strcmp( typeString,"h" ) == 0 ) || ( strcmp( typeString,"H" ) == 0 ) ) + { + /* consistency checks */ + if ( ( nlhs < 1 ) || ( nlhs > 6 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( nrhs < 5 ) || ( nrhs > 8 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + /* determine whether is it a simply bounded QP */ + if ( nrhs < 7 ) + isSimplyBoundedQp = BT_TRUE; + else + isSimplyBoundedQp = BT_FALSE; + + + if ( ( mxIsDouble( prhs[1] ) == false ) || ( mxIsScalar( prhs[1] ) == false ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Expecting a handle to QP object as second argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + /* get QP instance */ + handle = (uint_t)mxGetScalar( prhs[1] ); + globalQP = getQPInstance( handle ); + if ( globalQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return; + } + + nV = globalQP->getNV(); + + g_idx = 2; + lb_idx = 3; + ub_idx = 4; + + if (containsNaNorInf( prhs,g_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + + /* Check inputs dimensions and assign pointers to inputs. */ + if ( isSimplyBoundedQp == BT_TRUE ) + { + nC = 0; + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*nV; + + /* Check whether options are specified .*/ + if ( nrhs == 6 ) + if ( ( !mxIsEmpty( prhs[5] ) ) && ( mxIsStruct( prhs[5] ) ) ) + setupOptions( &options,prhs[5],nWSRin,maxCpuTimeIn ); + } + else + { + nC = globalQP->getNC( ); + + lbA_idx = 5; + ubA_idx = 6; + + if (containsNaNorInf( prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ubA_idx, 1 ) == BT_TRUE) + return; + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lbA,nC,1, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,1, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*(nV+nC); + + /* Check whether options are specified .*/ + if ( nrhs == 8 ) + if ( ( !mxIsEmpty( prhs[7] ) ) && ( mxIsStruct( prhs[7] ) ) ) + setupOptions( &options,prhs[7],nWSRin,maxCpuTimeIn ); + } + + /* Create output vectors and assign pointers to them. */ + allocateOutputs( nlhs,plhs, nV,nC ); + + /* call qpOASES */ + if ( isSimplyBoundedQp == BT_TRUE ) + { + QProblemB_hotstart( handle, g, + lb,ub, + nWSRin,maxCpuTimeIn, + &options, + nlhs,plhs + ); + } + else + { + QProblem_hotstart( handle, g, + lb,ub,lbA,ubA, + nWSRin,maxCpuTimeIn, + &options, + nlhs,plhs + ); + } + + return; + } + + /* 3) Modify matrices. */ + if ( ( strcmp( typeString,"m" ) == 0 ) || ( strcmp( typeString,"M" ) == 0 ) ) + { + /* consistency checks */ + if ( ( nlhs < 1 ) || ( nlhs > 6 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( nrhs < 9 ) || ( nrhs > 10 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( mxIsDouble( prhs[1] ) == false ) || ( mxIsScalar( prhs[1] ) == false ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Expecting a handle to QP object as second argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + + /* get QP instance */ + handle = (uint_t)mxGetScalar( prhs[1] ); + globalQP = getQPInstance( handle ); + if ( globalQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return; + } + + /* Check inputs dimensions and assign pointers to inputs. */ + g_idx = 3; + + if ( mxIsEmpty(prhs[2]) == 1 ) + { + H_idx = -1; + nV = (uint_t)mxGetM( prhs[ g_idx ] ); /* if Hessian is empty, row number of gradient vector */ + } + else + { + H_idx = 2; + nV = (uint_t)mxGetM( prhs[ H_idx ] ); /* row number of Hessian matrix */ + } + + A_idx = 4; + nC = (uint_t)mxGetM( prhs[ A_idx ] ); /* row number of constraint matrix */ + + lb_idx = 5; + ub_idx = 6; + lbA_idx = 7; + ubA_idx = 8; + + + /* ensure that data is given in double precision */ + if ( ( ( H_idx >= 0 ) && ( mxIsDouble( prhs[H_idx] ) == 0 ) ) || + ( mxIsDouble( prhs[g_idx] ) == 0 ) || + ( mxIsDouble( prhs[A_idx] ) == 0 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in real_t precision!" ); + return; + } + + /* check if supplied data contains 'NaN' or 'Inf' */ + if (containsNaNorInf(prhs,H_idx, 0) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,g_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,A_idx, 0 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ubA_idx, 1 ) == BT_TRUE) + return; + + /* Check that dimensions are consistent with existing QP instance */ + if (nV != (uint_t) globalQP->getNV () || nC != (uint_t) globalQP->getNC ()) + { + myMexErrMsgTxt( "ERROR (qpOASES): QP dimensions must be constant during a sequence! Try creating a new QP instance instead." ); + return; + } + + if ( ( H_idx >= 0 ) && ( ( mxGetN( prhs[ H_idx ] ) != nV ) || ( mxGetM( prhs[ H_idx ] ) != nV ) ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Hessian matrix dimension mismatch!" ); + return; + } + + if ( ( mxGetN( prhs[ A_idx ] ) != 0 ) && ( mxGetN( prhs[ A_idx ] ) != nV ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Constraint matrix dimension mismatch!" ); + return; + } + + if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lbA,nC,1, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,1, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + + /* default value for nWSR */ + nWSRin = 5*(nV+nC); + + /* Check whether options are specified .*/ + if ( nrhs > 9 ) + if ( ( !mxIsEmpty( prhs[9] ) ) && ( mxIsStruct( prhs[9] ) ) ) + setupOptions( &options,prhs[9],nWSRin,maxCpuTimeIn ); + + globalQP->deleteQPMatrices( ); + + /* make a deep-copy of the user-specified Hessian matrix (possibly sparse) */ + if ( H_idx >= 0 ) + setupHessianMatrix( prhs[H_idx],nV, &(globalQP->H),&(globalQP->Hir),&(globalQP->Hjc),&(globalQP->Hv) ); + + /* make a deep-copy of the user-specified constraint matrix (possibly sparse) */ + if ( ( nC > 0 ) && ( A_idx >= 0 ) ) + setupConstraintMatrix( prhs[A_idx],nV,nC, &(globalQP->A),&(globalQP->Air),&(globalQP->Ajc),&(globalQP->Av) ); + + /* Create output vectors and assign pointers to them. */ + allocateOutputs( nlhs,plhs, nV,nC ); + + /* Call qpOASES */ + SQProblem_hotstart( handle, globalQP->H,g,globalQP->A, + lb,ub,lbA,ubA, + nWSRin,maxCpuTimeIn, + &options, + nlhs,plhs + ); + + return; + } + + /* 4) Solve current equality constrained QP. */ + if ( ( strcmp( typeString,"e" ) == 0 ) || ( strcmp( typeString,"E" ) == 0 ) ) + { + /* consistency checks */ + if ( ( nlhs < 1 ) || ( nlhs > 4 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( nrhs < 7 ) || ( nrhs > 8 ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( mxIsDouble( prhs[1] ) == false ) || ( mxIsScalar( prhs[1] ) == false ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Expecting a handle to QP object as second argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + /* get QP instance */ + handle = (uint_t)mxGetScalar( prhs[1] ); + globalQP = getQPInstance( handle ); + if ( globalQP == 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid handle to QP instance!" ); + return; + } + + /* Check inputs dimensions and assign pointers to inputs. */ + int_t nRHS = (int_t)mxGetN(prhs[2]); + nV = globalQP->getNV( ); + nC = globalQP->getNC( ); + real_t *x_out, *y_out; + + g_idx = 2; + lb_idx = 3; + ub_idx = 4; + lbA_idx = 5; + ubA_idx = 6; + + /* check if supplied data contains 'NaN' or 'Inf' */ + if (containsNaNorInf(prhs,g_idx, 0) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lb_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ub_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,lbA_idx, 1 ) == BT_TRUE) + return; + + if (containsNaNorInf( prhs,ubA_idx, 1 ) == BT_TRUE) + return; + + if ( smartDimensionCheck( &g,nV,nRHS, BT_FALSE,prhs,g_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lb,nV,nRHS, BT_TRUE,prhs,lb_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ub,nV,nRHS, BT_TRUE,prhs,ub_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &lbA,nC,nRHS, BT_TRUE,prhs,lbA_idx ) != SUCCESSFUL_RETURN ) + return; + + if ( smartDimensionCheck( &ubA,nC,nRHS, BT_TRUE,prhs,ubA_idx ) != SUCCESSFUL_RETURN ) + return; + + /* Check whether options are specified .*/ + if ( ( nrhs == 8 ) && ( !mxIsEmpty( prhs[7] ) ) && ( mxIsStruct( prhs[7] ) ) ) + { + nWSRin = 5*(nV+nC); + setupOptions( &options,prhs[7],nWSRin,maxCpuTimeIn ); + globalQP->sqp->setOptions( options ); + } + + /* Create output vectors and assign pointers to them. */ + plhs[0] = mxCreateDoubleMatrix( nV, nRHS, mxREAL ); + x_out = mxGetPr(plhs[0]); + if (nlhs >= 2) + { + plhs[1] = mxCreateDoubleMatrix( nV+nC, nRHS, mxREAL ); + y_out = mxGetPr(plhs[1]); + + if (nlhs >= 3) + { + plhs[2] = mxCreateDoubleMatrix( nV, nRHS, mxREAL ); + real_t* workingSetB = mxGetPr(plhs[2]); + globalQP->sqp->getWorkingSetBounds(workingSetB); + + if ( nlhs >= 4 ) + { + plhs[3] = mxCreateDoubleMatrix( nC, nRHS, mxREAL ); + real_t* workingSetC = mxGetPr(plhs[3]); + globalQP->sqp->getWorkingSetConstraints(workingSetC); + } + } + } + else + y_out = new real_t[nV+nC]; + + /* Solve equality constrained QP */ + returnValue returnvalue = globalQP->sqp->solveCurrentEQP( nRHS,g,lb,ub,lbA,ubA, x_out,y_out ); + + if (nlhs < 2) + delete[] y_out; + + if (returnvalue != SUCCESSFUL_RETURN) + { + char msg[MAX_STRING_LENGTH]; + snprintf(msg, MAX_STRING_LENGTH, "ERROR (qpOASES): Couldn't solve current EQP (code %d)!", returnvalue); + myMexErrMsgTxt(msg); + return; + } + + return; + } + + /* 5) Cleanup. */ + if ( ( strcmp( typeString,"c" ) == 0 ) || ( strcmp( typeString,"C" ) == 0 ) ) + { + /* consistency checks */ + if ( nlhs != 0 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( nrhs != 2 ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + if ( ( mxIsDouble( prhs[1] ) == false ) || ( mxIsScalar( prhs[1] ) == false ) ) + { + myMexErrMsgTxt( "ERROR (qpOASES): Expecting a handle to QP object as second argument!\nType 'help qpOASES_sequence' for further information." ); + return; + } + + /* Cleanup SQProblem instance. */ + handle = (uint_t)mxGetScalar( prhs[1] ); + deleteQPInstance( handle ); + + return; + } + +} + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_sequence.m b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_sequence.m new file mode 100644 index 0000000..e064e8b --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/octave/qpOASES_sequence.m @@ -0,0 +1,111 @@ +%qpOASES -- An Implementation of the Online Active Set Strategy. +%Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. +% +%qpOASES is distributed under the terms of the +%GNU Lesser General Public License 2.1 in the hope that it will be +%useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%See the GNU Lesser General Public License for more details. +% +%--------------------------------------------------------------------------------- +% +%qpOASES_sequence is intended to solve a sequence of quadratic +%programming (QP) problems of the following form: +% +% min 1/2*x'Hx + x'g +% s.t. lb <= x <= ub +% lbA <= Ax <= ubA {optional} +% +%I) Call +% +% [QP,x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'i',H,g,A,lb,ub,lbA,ubA{,options{,auxInput}} ) +%or +% [QP,x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'i',H,g,lb,ub{,options{,auxInput}} ) +% +%for initialising and solving the first above-mentioned QP of the sequence +%starting from an initial guess x0. H must be a symmetric (possibly indefinite) +%matrix and all vectors g, lb, ub, lbA, ubA have to be given as column vectors. +%Options can be generated using the qpOASES_options command, otherwise default +%values are used. Optionally, further auxiliary inputs may be generated +%using qpOASES_auxInput command and passed to the solver. +%Both matrices H or A may be passed in sparse matrix format. +% +%II) Call +% +% [x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'h',QP,g,lb,ub,lbA,ubA{,options} ) +%or +% [x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'h',QP,g,lb,ub{,options} ) +% +%for hotstarting from the previous QP solution to the one of the next QP +%given by the vectors g, lb, ub, lbA, ubA. Options can be generated using the +%qpOASES_options command, otherwise default values are used. +% +%III) Call +% +% [x,fval,exitflag,iter,lambda,auxOutput] = ... +% qpOASES_sequence( 'm',QP,H,g,A,lb,ub,lbA,ubA{,options} ) +% +%for hotstarting from the previous QP solution to the one of the next QP +%given by the matrices H, A and the vectors g, lb, ub, lbA, ubA. The previous +%active set serves as a starting guess. If the new projected Hessian matrix +%turns out to be not positive definite, qpOASES recedes to a safe initial active +%set guess automatically. This can result in a high number of iterations iter. +%Options can be generated using the qpOASES_options command, otherwise default +%values are used. +% +%IV) Call +% +% [x,lambda,workingSetB,workingSetC] = ... +% qpOASES_sequence( 'e',QP,g,lb,ub,lbA,ubA{,options} ) +% +%for solving the equality constrained QP with constraints determined by the +%current active set. All inequalities and bounds which were not active in the +%previous solution might be violated. This command does not alter the internal +%state of qpOASES. Instead of calling this command multiple times, it is +%possible to supply several columns simultaneously in g, lb, ub, lbA, and ubA. +%Options can be generated using the qpOASES_options command, otherwise default +%values are used. +% +%V) Having solved the last QP of your sequence, call +% +% qpOASES_sequence( 'c',QP ) +% +%in order to cleanup the internal memory. +% +% +%Optional outputs (only x is mandatory): +% x - Optimal primal solution vector (if exitflag==0). +% fval - Optimal objective function value (if exitflag==0). +% exitflag - 0: QP solved, +% 1: QP could not be solved within given number of iterations, +% -1: QP could not be solved due to an internal error, +% -2: QP is infeasible (and thus could not be solved), +% -3: QP is unbounded (and thus could not be solved). +% iter - Number of active set iterations actually performed. +% lambda - Optimal dual solution vector (if exitflag==0). +% auxOutput - Struct containing auxiliary outputs as described below. +% +%The auxOutput struct contains the following entries: +% workingSetB - Working set of bounds at point x. +% workingSetC - Working set of constraints at point x. +% The working set is a subset of the active set (indices +% of bounds/constraints that hold with equality) yielding +% a set linearly independent of bounds/constraints. +% The working sets are encoded as follows: +% 1: bound/constraint at its upper bound +% 0: bound/constraint not at any bound +% -1: bound/constraint at its lower bound +% cpuTime - Internally measured CPU time for solving QP problem. +% +%See also QPOASES_OPTIONS, QPOASES_AUXINPUT, QPOASES +% +% +%For additional information see the qpOASES User's Manual or +%visit http://www.qpOASES.org/. +% +%Please send remarks and questions to support@qpOASES.org! diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/README.rst b/locomotion/src/third_party/qpOASES/interfaces/python/README.rst new file mode 100644 index 0000000..2b17d11 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/README.rst @@ -0,0 +1,75 @@ +pyqpOASES: a Python interface to qpOASES + +:Author: Sebastian F. Walter, Manuel Kudruss + +Known to work with +------------------ + +* python2.7 +* qpOASES 3.2 (rev 259) + + +Installation +------------ + +Requirements: + + You'll need numpy and cython. Install for instance with:: + + sudo pip install cython + sudo pip install numpy + +Method 1: + + This is a local installation and creates `./interfaces/python/qpoases.so`:: + + make python + + Then, you'll have to update your PYTHONPATH, e.g., on LINUX you have to add:: + + export PYTHONPATH=$PYTHONPATH:/home/swalter/projects/qpOASES/interfaces/python + + to your ``~/.bashrc``. + +Method 2: + + global installation:: + + sudo make pythoninstall + +Method 3:: + + cd ./interfaces/python/ + python setup.py build_ext --inplace + # or python setup.py install + + +Testing your installation +------------------------- + +For a quick test run:: + + cd ./interfaces/python + python example1.py + + +To run a complete unit test you need ``nose``. Install for instance with:: + + sudo pip install nose + +Then:: + + cd ./interfaces/python/ + nosestests ./tests + +The results of the tests can be found in `./interfaces/python/tests/results`. + +Tested setups +------------- + +The Python interface is known to work on + +* Windows, Python 3 +* Linux (Ubuntu 12.04) using Python 2.7.3, Python 3.2.3. NumPy 1.8, Cython 0.19 +* MacOS Mojave (10.14.3) using Python 3.7 (anaconda suite) + diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/examples/cython/example1.pyx b/locomotion/src/third_party/qpOASES/interfaces/python/examples/cython/example1.pyx new file mode 100644 index 0000000..c837611 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/examples/cython/example1.pyx @@ -0,0 +1,73 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + +## Example adapted from examples/example1.cpp. +## author of this file: Sebastian F. Walter + +import numpy as np +from qpoases import PyQProblem as QProblem +from qpoases import PyPrintLevel as PrintLevel +from qpoases import PyOptions as Options +cimport numpy as np + +def run(): + + #Setup data of QP. + + cdef np.ndarray[np.double_t, ndim=2] H + cdef np.ndarray[np.double_t, ndim=2] A + cdef np.ndarray[np.double_t, ndim=1] g + cdef np.ndarray[np.double_t, ndim=1] lb + cdef np.ndarray[np.double_t, ndim=1] ub + cdef np.ndarray[np.double_t, ndim=1] lbA + cdef np.ndarray[np.double_t, ndim=1] ubA + + H = np.array([1.0, 0.0, 0.0, 0.5 ]).reshape((2,2)) + A = np.array([1.0, 1.0 ]).reshape((2,1)) + g = np.array([1.5, 1.0 ]) + lb = np.array([0.5, -2.0]) + ub = np.array([5.0, 2.0 ]) + lbA = np.array([-1.0 ]) + ubA = np.array([2.0]) + + # Setting up QProblem object. + + cdef example = QProblem(2, 1) + cdef options = Options() + options.printLevel = PrintLevel.NONE + example.setOptions(options) + + # Solve first QP. + + cdef int nWSR = 10 + example.init(H, g, A, lb, ub, lbA, ubA, nWSR) + + # Solve subsequent QPs + + cdef int i,j + for i in range(100000): + for j in range(1, 100): + g[0] = i%j + example.hotstart(g, lb, ub, lbA, ubA, nWSR) + +run() + diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/examples/cython/setup.py b/locomotion/src/third_party/qpOASES/interfaces/python/examples/cython/setup.py new file mode 100644 index 0000000..d605d2c --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/examples/cython/setup.py @@ -0,0 +1,16 @@ +from distutils.core import setup +from distutils.extension import Extension +from Cython.Distutils import build_ext + +ext_module = Extension( + "example1", + ["example1.pyx"], + extra_compile_args=['-fopenmp'], + extra_link_args=['-fopenmp'], +) + +setup( + name = 'Hello world app', + cmdclass = {'build_ext': build_ext}, + ext_modules = [ext_module], +) diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/examples/example1.py b/locomotion/src/third_party/qpOASES/interfaces/python/examples/example1.py new file mode 100644 index 0000000..c1a7df4 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/examples/example1.py @@ -0,0 +1,74 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + +## Example adapted from examples/example1.cpp. +## author of this file: Sebastian F. Walter + +import numpy as np +from qpoases import PyQProblem as QProblem +from qpoases import PyOptions as Options +from qpoases import PyPrintLevel as PrintLevel + +#Setup data of first QP. + +H = np.array([1.0, 0.0, 0.0, 0.5 ]).reshape((2,2)) +A = np.array([1.0, 1.0 ]).reshape((2,1)) +g = np.array([1.5, 1.0 ]) +lb = np.array([0.5, -2.0]) +ub = np.array([5.0, 2.0 ]) +lbA = np.array([-1.0 ]) +ubA = np.array([2.0]) + + +# Setup data of second QP. + +g_new = np.array([1.0, 1.5]) +lb_new = np.array([0.0, -1.0]) +ub_new = np.array([5.0, -0.5]) +lbA_new = np.array([-2.0]) +ubA_new = np.array([1.0]) + + +# Setting up QProblem object. + +example = QProblem(2, 1) +options = Options() +#options.printLevel = PrintLevel.NONE +example.setOptions(options) + +# Solve first QP. +nWSR = np.array([10]) +example.init(H, g, A, lb, ub, lbA, ubA, nWSR) + +xOpt = np.zeros(2) +example.getPrimalSolution(xOpt) +print("\nxOpt = [ %e, %e ]; objVal = %e\n\n"%(xOpt[0],xOpt[1],example.getObjVal())) + +# Solve second QP. +nWSR = np.array([10]) +example.hotstart( g_new, lb_new, ub_new, lbA_new, ubA_new, nWSR) + +# Get and print solution of second QP. + +example.getPrimalSolution(xOpt) +print("\nxOpt = [ %e, %e ]; objVal = %e\n\n"%(xOpt[0],xOpt[1],example.getObjVal())) +example.printOptions() diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/examples/example1b.py b/locomotion/src/third_party/qpOASES/interfaces/python/examples/example1b.py new file mode 100644 index 0000000..989c914 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/examples/example1b.py @@ -0,0 +1,72 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + +## Example adapted from examples/example1b.cpp. +## author of this file: Sebastian F. Walter + +import numpy as np +from qpoases import PyQProblemB as QProblemB +from qpoases import PyBooleanType as BooleanType +from qpoases import PySubjectToStatus as SubjectToStatus +from qpoases import PyOptions as Options + +# Example for qpOASES main function using the QProblemB class. + +#Setup data of first QP. + +H = np.array([1.0, 0.0, 0.0, 0.5 ]).reshape((2,2)) +g = np.array([1.5, 1.0 ]) +lb = np.array([0.5, -2.0]) +ub = np.array([5.0, 2.0 ]) + +# Setup data of second QP. + +g_new = np.array([1.0, 1.5]) +lb_new = np.array([0.0, -1.0]) +ub_new = np.array([5.0, -0.5]) + + +# Setting up QProblemB object. +example = QProblemB(2) + +options = Options() +options.enableFlippingBounds = BooleanType.FALSE +options.initialStatusBounds = SubjectToStatus.INACTIVE +options.numRefinementSteps = 1 + +example.setOptions(options) + +# Solve first QP. +nWSR = np.array([10]) +example.init(H, g, lb, ub, nWSR) +print("\nnWSR = %d\n\n"%nWSR) + +# Solve second QP. +nWSR = np.array([10]) +example.hotstart(g_new, lb_new, ub_new, nWSR) +print("\nnWSR = %d\n\n"% nWSR) + +# Get and print solution of second QP. +xOpt = np.zeros(2) +example.getPrimalSolution(xOpt) +print("\nxOpt = [ %e, %e ]; objVal = %e\n\n" %(xOpt[0], xOpt[1], + example.getObjVal())) diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/examples/example2.py b/locomotion/src/third_party/qpOASES/interfaces/python/examples/example2.py new file mode 100644 index 0000000..748b7cb --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/examples/example2.py @@ -0,0 +1,94 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + +## Example adapted from examples/example2.cpp. +## author of this file: Sebastian F. Walter + +import os +import sys +import numpy as np +from qpoases import PySQProblem as SQProblem +from qpoases import PySolutionAnalysis as SolutionAnalysis + + +# Setup data of first QP. +H = np.array([ 1.0, 0.0, 0.0, 0.5 ]).reshape((2,2)) +A = np.array([ 1.0, 1.0 ]).reshape((2,1)) +g = np.array([ 1.5, 1.0 ]) +lb = np.array([ 0.5, -2.0 ]) +ub = np.array([ 5.0, 2.0 ]) +lbA = np.array([ -1.0 ]) +ubA = np.array([ 2.0 ]) + +# Setup data of second QP. +H_new = np.array([ 1.0, 0.5, 0.5, 0.5 ]).reshape((2,2)) +A_new = np.array([ 1.0, 5.0 ]).reshape((2,1)) +g_new = np.array([ 1.0, 1.5 ]) +lb_new = np.array([ 0.0, -1.0 ]) +ub_new = np.array([ 5.0, -0.5 ]) +lbA_new = np.array([ -2.0 ]) +ubA_new = np.array([ 1.0 ]) + +# Setting up SQProblem object and solution analyser. +example = SQProblem(2, 1) +analyser = SolutionAnalysis() + +# Solve first QP ... +nWSR = np.array([10]) +example.init(H, g, A, lb, ub, lbA, ubA, nWSR) + +# ... and analyse it. +maxStat = np.zeros(1) +maxFeas = np.zeros(1) +maxCmpl = np.zeros(1) + +analyser.getKktViolation(example, maxStat, maxFeas, maxCmpl) +print("maxStat: %e, maxFeas:%e, maxCmpl: %e\n"%(maxStat, maxFeas, maxCmpl)) + +# Solve second QP ... +nWSR = np.array([10]) +example.hotstart(H_new, g_new, A_new, lb_new, ub_new, + lbA_new, ubA_new, nWSR) + +# ... and analyse it. +analyser.getKktViolation(example, maxStat, maxFeas, maxCmpl) +print("maxStat: %e, maxFeas:%e, maxCmpl: %e\n"%(maxStat, maxFeas, maxCmpl)) + + +# ------------ VARIANCE-COVARIANCE EVALUATION -------------------- + +Var = np.zeros(5*5) +Primal_Dual_Var = np.zeros(5*5) + +Var.reshape((5,5))[0,0] = 1. +Var.reshape((5,5))[1,1] = 1. + +# ( 1 0 0 0 0 ) +# ( 0 1 0 0 0 ) +# Var = ( 0 0 0 0 0 ) +# ( 0 0 0 0 0 ) +# ( 0 0 0 0 0 ) + + +analyser.getVarianceCovariance(example, Var, Primal_Dual_Var) +print('Primal_Dual_Var=\n', Primal_Dual_Var.reshape((5,5))) +print("maxStat: %e, maxFeas:%e, maxCmpl: %e\n"%(maxStat, maxFeas, maxCmpl)) diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/qpoases.pxd b/locomotion/src/third_party/qpOASES/interfaces/python/qpoases.pxd new file mode 100644 index 0000000..9c92cfc --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/qpoases.pxd @@ -0,0 +1,515 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + +## +## Filename: qpoases.pxd +## Author: Sebastian F. Walter, Manuel Kudruss (thanks to Felix Lenders) +## Version: 3.2 +## Date: 2013-2017 +## + +cdef extern from "qpOASES.hpp" namespace "qpOASES": + + ctypedef double real_t + # NOTE we use long type for integers to be compatible with the C/C++ + # interface in all cases, i.e, either __USE_LONG_INTEGERS__ is defined + # or not. + ctypedef long int_t + + cdef enum BooleanType: + + BT_FALSE + BT_TRUE + + cdef enum PrintLevel: + + PL_DEBUG_ITER = -2 + PL_TABULAR + PL_NONE + PL_LOW + PL_MEDIUM + PL_HIGH + + cdef enum VisibilityStatus: + + VS_HIDDEN + VS_VISIBLE + + cdef enum QProblemStatus: + + QPS_NOTINITIALISED + QPS_PREPARINGAUXILIARYQP + + QPS_AUXILIARYQPSOLVED + + QPS_PERFORMINGHOMOTOPY + + QPS_HOMOTOPYQPSOLVED + QPS_SOLVED + + cdef enum HessianType: + HST_ZERO + HST_IDENTITY + HST_POSDEF + HST_POSDEF_NULLSPACE + HST_SEMIDEF + HST_INDEF + HST_UNKNOWN + + cdef enum SubjectToType: + + ST_UNBOUNDED + ST_BOUNDED + ST_EQUALITY + ST_DISABLED + ST_UNKNOWN + + cdef enum SubjectToStatus: + + ST_LOWER = -1 + ST_INACTIVE + ST_UPPER + ST_INFEASIBLE_LOWER + ST_INFEASIBLE_UPPER + ST_UNDEFINED + + cdef enum returnValue: + TERMINAL_LIST_ELEMENT = -1 + SUCCESSFUL_RETURN = 0 + RET_DIV_BY_ZERO + RET_INDEX_OUT_OF_BOUNDS + RET_INVALID_ARGUMENTS + RET_ERROR_UNDEFINED + RET_WARNING_UNDEFINED + RET_INFO_UNDEFINED + RET_EWI_UNDEFINED + RET_AVAILABLE_WITH_LINUX_ONLY + RET_UNKNOWN_BUG + RET_PRINTLEVEL_CHANGED + RET_NOT_YET_IMPLEMENTED + RET_INDEXLIST_MUST_BE_REORDERD + RET_INDEXLIST_EXCEEDS_MAX_LENGTH + RET_INDEXLIST_CORRUPTED + RET_INDEXLIST_OUTOFBOUNDS + RET_INDEXLIST_ADD_FAILED + RET_INDEXLIST_INTERSECT_FAILED + RET_INDEX_ALREADY_OF_DESIRED_STATUS + RET_ADDINDEX_FAILED + RET_REMOVEINDEX_FAILED + RET_SWAPINDEX_FAILED + RET_NOTHING_TO_DO + RET_SETUP_BOUND_FAILED + RET_SETUP_CONSTRAINT_FAILED + RET_MOVING_BOUND_FAILED + RET_MOVING_CONSTRAINT_FAILED + RET_SHIFTING_FAILED + RET_ROTATING_FAILED + RET_QPOBJECT_NOT_SETUP + RET_QP_ALREADY_INITIALISED + RET_NO_INIT_WITH_STANDARD_SOLVER + RET_RESET_FAILED + RET_INIT_FAILED + RET_INIT_FAILED_TQ + RET_INIT_FAILED_CHOLESKY + RET_INIT_FAILED_HOTSTART + RET_INIT_FAILED_INFEASIBILITY + RET_INIT_FAILED_UNBOUNDEDNESS + RET_INIT_FAILED_REGULARISATION + RET_INIT_SUCCESSFUL + RET_OBTAINING_WORKINGSET_FAILED + RET_SETUP_WORKINGSET_FAILED + RET_SETUP_AUXILIARYQP_FAILED + RET_NO_CHOLESKY_WITH_INITIAL_GUESS + RET_NO_EXTERN_SOLVER + RET_QP_UNBOUNDED + RET_QP_INFEASIBLE + RET_QP_NOT_SOLVED + RET_QP_SOLVED + RET_UNABLE_TO_SOLVE_QP + RET_INITIALISATION_STARTED + RET_HOTSTART_FAILED + RET_HOTSTART_FAILED_TO_INIT + RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED + RET_ITERATION_STARTED + RET_SHIFT_DETERMINATION_FAILED + RET_STEPDIRECTION_DETERMINATION_FAILED + RET_STEPLENGTH_DETERMINATION_FAILED + RET_OPTIMAL_SOLUTION_FOUND + RET_HOMOTOPY_STEP_FAILED + RET_HOTSTART_STOPPED_INFEASIBILITY + RET_HOTSTART_STOPPED_UNBOUNDEDNESS + RET_WORKINGSET_UPDATE_FAILED + RET_MAX_NWSR_REACHED + RET_CONSTRAINTS_NOT_SPECIFIED + RET_INVALID_FACTORISATION_FLAG + RET_UNABLE_TO_SAVE_QPDATA + RET_STEPDIRECTION_FAILED_TQ + RET_STEPDIRECTION_FAILED_CHOLESKY + RET_CYCLING_DETECTED + RET_CYCLING_NOT_RESOLVED + RET_CYCLING_RESOLVED + RET_STEPSIZE + RET_STEPSIZE_NONPOSITIVE + RET_SETUPSUBJECTTOTYPE_FAILED + RET_ADDCONSTRAINT_FAILED + RET_ADDCONSTRAINT_FAILED_INFEASIBILITY + RET_ADDBOUND_FAILED + RET_ADDBOUND_FAILED_INFEASIBILITY + RET_REMOVECONSTRAINT_FAILED + RET_REMOVEBOUND_FAILED + RET_REMOVE_FROM_ACTIVESET + RET_ADD_TO_ACTIVESET + RET_REMOVE_FROM_ACTIVESET_FAILED + RET_ADD_TO_ACTIVESET_FAILED + RET_CONSTRAINT_ALREADY_ACTIVE + RET_ALL_CONSTRAINTS_ACTIVE + RET_LINEARLY_DEPENDENT + RET_LINEARLY_INDEPENDENT + RET_LI_RESOLVED + RET_ENSURELI_FAILED + RET_ENSURELI_FAILED_TQ + RET_ENSURELI_FAILED_NOINDEX + RET_ENSURELI_FAILED_CYCLING + RET_BOUND_ALREADY_ACTIVE + RET_ALL_BOUNDS_ACTIVE + RET_CONSTRAINT_NOT_ACTIVE + RET_BOUND_NOT_ACTIVE + RET_HESSIAN_NOT_SPD + RET_HESSIAN_INDEFINITE + RET_MATRIX_SHIFT_FAILED + RET_MATRIX_FACTORISATION_FAILED + RET_PRINT_ITERATION_FAILED + RET_NO_GLOBAL_MESSAGE_OUTPUTFILE + RET_DISABLECONSTRAINTS_FAILED + RET_ENABLECONSTRAINTS_FAILED + RET_ALREADY_ENABLED + RET_ALREADY_DISABLED + RET_NO_HESSIAN_SPECIFIED + RET_USING_REGULARISATION + RET_EPS_MUST_BE_POSITVE + RET_REGSTEPS_MUST_BE_POSITVE + RET_HESSIAN_ALREADY_REGULARISED + RET_CANNOT_REGULARISE_IDENTITY + RET_CANNOT_REGULARISE_SPARSE + RET_NO_REGSTEP_NWSR + RET_FEWER_REGSTEPS_NWSR + RET_CHOLESKY_OF_ZERO_HESSIAN + RET_ZERO_HESSIAN_ASSUMED + RET_CONSTRAINTS_ARE_NOT_SCALED + RET_INITIAL_BOUNDS_STATUS_NYI + RET_ERROR_IN_CONSTRAINTPRODUCT + RET_FIX_BOUNDS_FOR_LP + RET_USE_REGULARISATION_FOR_LP + RET_UPDATEMATRICES_FAILED + RET_UPDATEMATRICES_FAILED_AS_QP_NOT_SOLVED + RET_UNABLE_TO_OPEN_FILE + RET_UNABLE_TO_WRITE_FILE + RET_UNABLE_TO_READ_FILE + RET_FILEDATA_INCONSISTENT + RET_UNABLE_TO_ANALYSE_QPROBLEM + RET_OPTIONS_ADJUSTED + RET_NWSR_SET_TO_ONE + RET_UNABLE_TO_READ_BENCHMARK + RET_BENCHMARK_ABORTED + RET_INITIAL_QP_SOLVED + RET_QP_SOLUTION_STARTED + RET_BENCHMARK_SUCCESSFUL + RET_NO_DIAGONAL_AVAILABLE + RET_DIAGONAL_NOT_INITIALISED + RET_ENSURELI_DROPPED + RET_KKT_MATRIX_SINGULAR + RET_QR_FACTORISATION_FAILED + RET_INERTIA_CORRECTION_FAILED + RET_NO_SPARSE_SOLVER + RET_SIMPLE_STATUS_P1 + RET_SIMPLE_STATUS_P0 + RET_SIMPLE_STATUS_M1 + RET_SIMPLE_STATUS_M2 + RET_SIMPLE_STATUS_M3 + + + cdef cppclass Options: + + Options() + Options(const Options&) + # Options& operator=( const Options&) # equality operator cannot be overloaded in Python + returnValue setToDefault() + returnValue setToReliable() + returnValue setToMPC() + returnValue setToFast() + returnValue ensureConsistency() + # returnValue print() # print is a reserved keyword in Python + returnValue copy(const Options& ) + + PrintLevel printLevel + + BooleanType enableRamping + BooleanType enableFarBounds + BooleanType enableFlippingBounds + BooleanType enableRegularisation + BooleanType enableFullLITests + BooleanType enableNZCTests + int_t enableDriftCorrection + int_t enableCholeskyRefactorisation + BooleanType enableEqualities + + real_t terminationTolerance + real_t boundTolerance + real_t boundRelaxation + real_t epsNum + real_t epsDen + real_t maxPrimalJump + real_t maxDualJump + + real_t initialRamping + real_t finalRamping + real_t initialFarBounds + real_t growFarBounds + SubjectToStatus initialStatusBounds + real_t epsFlipping + int_t numRegularisationSteps + real_t epsRegularisation + int_t numRefinementSteps + real_t epsIterRef + real_t epsLITests + real_t epsNZCTests + + real_t rcondSMin + BooleanType enableInertiaCorrection + + BooleanType enableDropInfeasibles + int_t dropBoundPriority + int_t dropEqConPriority + int_t dropIneqConPriority + + + cdef cppclass Bounds: + Bounds() + + + cdef cppclass Constraints: + Constraints() + + + cdef cppclass QProblemB: + QProblemB() + QProblemB(int_t, HessianType, BooleanType) + + QProblemB(const QProblemB&) + + returnValue init(real_t*, + real_t*, + real_t*, + real_t*, + int_t&) + + returnValue init(real_t*, + real_t*, + real_t*, + real_t*, + int_t&, + real_t*) + + returnValue hotstart(real_t*, + real_t*, + real_t*, + int_t&) + + returnValue hotstart(real_t*, + real_t*, + real_t*, + int_t&, + real_t*) + + + returnValue getPrimalSolution(real_t*) + returnValue getDualSolution(real_t*) + returnValue printOptions() + real_t getObjVal() + + Options getOptions() + returnValue setOptions(Options&) + + cdef cppclass QProblem: + QProblem() + QProblem(int_t, int_t, HessianType, BooleanType) + + QProblem(const QProblem&) + + returnValue init(real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + int_t&) + + returnValue init(real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + int_t&, + real_t*) + + returnValue hotstart(real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + int_t&) + + returnValue hotstart(real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + int_t&, + real_t*) + + returnValue getPrimalSolution(real_t*) + returnValue getDualSolution(real_t*) + returnValue printOptions() + real_t getObjVal() + + Options getOptions() + returnValue setOptions(Options&) + + + cdef cppclass SQProblem: + SQProblem() + SQProblem(int_t, int_t, HessianType, BooleanType) + + SQProblem(const QProblem&) + + returnValue init(real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + int_t&) + + returnValue init(real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + int_t&, + real_t*) + + returnValue init(real_t* _H, + real_t* _g, + real_t* _A, + real_t* _lb, + real_t* _ub, + real_t* _lbA, + real_t* _ubA, + int_t& nWSR, + real_t* cputime, + real_t* xOpt, + real_t* yOpt, + Bounds* guessedBounds, + Constraints* guessedConstraints, + real_t* _R) + + + returnValue hotstart(real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + int_t&) + + returnValue hotstart(real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + real_t*, + int_t&, + real_t*) + + returnValue getPrimalSolution(real_t*) + returnValue getDualSolution(real_t*) + returnValue printOptions() + real_t getObjVal() + + Options getOptions() + returnValue setOptions(Options&) + +cdef extern from "qpOASES/extras/SolutionAnalysis.hpp" namespace "qpOASES": + cdef cppclass SolutionAnalysis: + SolutionAnalysis() + SolutionAnalysis(const SolutionAnalysis&) + # ~SolutionAnalysis() + # SolutionAnalysis& operator=(const SolutionAnalysis&) + real_t getKktViolation(const QProblem*, const real_t*, const real_t*, const real_t*) + real_t getKktViolation(const QProblemB*, const real_t*, const real_t*, const real_t*) + real_t getKktViolation(const SQProblem*, const real_t*, const real_t*, const real_t*) + returnValue getVarianceCovariance(QProblem*, real_t*, real_t*) + returnValue getVarianceCovariance(QProblemB*, real_t*, real_t*) + returnValue getVarianceCovariance(SQProblem*, real_t*, real_t*) + + +cdef extern from "qpOASES/Utils.hpp" namespace "qpOASES": + pass + #void getKktViolation(int_t nV, # Number of variables. + # int_t nC, # Number of constraints. + # const real_t* const H, # Hessian matrix. + # const real_t* const g, # Sequence of gradient vectors. + # const real_t* const A, # Constraint matrix. + # const real_t* const lb, # Sequence of lower bound vectors (on variables). + # const real_t* const ub, # Sequence of upper bound vectors (on variables). + # const real_t* const lbA, # Sequence of lower constraints' bound vectors. + # const real_t* const ubA, # Sequence of upper constraints' bound vectors. + # const real_t* const x, # Sequence of primal trial vectors. + # const real_t* const y, # Sequence of dual trial vectors. + # real_t& stat, # Maximum value of stationarity condition residual. + # real_t& feas, # Maximum value of primal feasibility violation. + # real_t& cmpl # Maximum value of complementarity residual. + # ) + + +cdef extern from "qpOASES/extras/OQPinterface.hpp" namespace "qpOASES": + returnValue runOqpBenchmark(const char* path, # Full path of the benchmark files (without trailing slash!). + BooleanType isSparse, # Shall convert matrices to sparse format before solution? + BooleanType useHotstarts, # Shall QP solution be hotstarted? + const Options& options, # QP solver options to be used while solving benchmark problems. + int_t maxAllowedNWSR, # Maximum number of working set recalculations to be performed. + real_t& maxNWSR, # Output: Maximum number of performed working set recalculations. + real_t& avgNWSR, # Output: Average number of performed working set recalculations. + real_t& maxCPUtime, # Output: Maximum CPU time required for solving each QP. + real_t& avgCPUtime, # Output: Average CPU time required for solving each QP. + real_t& maxStationarity, # Output: Maximum residual of stationarity condition. + real_t& maxFeasibility, # Output: Maximum residual of primal feasibility condition. + real_t& maxComplementarity # Output: Maximum residual of complementarity condition. + ) diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/qpoases.pyx b/locomotion/src/third_party/qpOASES/interfaces/python/qpoases.pyx new file mode 100644 index 0000000..eb85542 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/qpoases.pyx @@ -0,0 +1,920 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + +## authors of this file: Sebastian F. Walter (thanks to Felix Lenders) + +""" +Python interface to qpOASES +using Cython +:author: Sebastian F. Walter, Manuel Kudruss (thanks to Felix Lenders) +""" + +import warnings +warnings.simplefilter("once", DeprecationWarning) +import numpy as np +cimport numpy as np + +from cython.operator cimport dereference as deref + +cimport qpoases + +def deprecation_warning_nWSR(): + warnings.warn("\nInteger nWSR will be deprecated in qpOASES 4.0.\nUse nWSR = numpy.array([10]) as input to qp.init() and qp.hotstart()", DeprecationWarning, stacklevel=2) + +def deprecation_warning_cputime(): + warnings.warn("\nFloat cputime will be deprecated in qpOASES 4.0.\nUse cputime = numpy.array([2.0]) as input to qp.init() and qp.hotstart()", DeprecationWarning, stacklevel=2) + + +cdef str __version__ = "3.2.2" + +cdef class PyBooleanType: + FALSE = BT_FALSE + TRUE = BT_TRUE + +cdef class PyPrintLevel: + DEBUG_ITER = PL_DEBUG_ITER + TABULAR = PL_TABULAR + NONE = PL_NONE + LOW = PL_LOW + MEDIUM = PL_MEDIUM + HIGH = PL_HIGH + +cdef class PyHessianType: + ZERO = HST_ZERO + IDENTITY = HST_IDENTITY + POSDEF = HST_POSDEF + POSDEF_NULLSPACE = HST_POSDEF_NULLSPACE + SEMIDEF = HST_SEMIDEF + INDEF = HST_INDEF + UNKNOWN = HST_UNKNOWN + +cdef class PySubjectToStatus: + LOWER = ST_LOWER + INACTIVE = ST_INACTIVE + UPPER = ST_UPPER + INFEASIBLE_LOWER = ST_INFEASIBLE_LOWER + INFEASIBLE_UPPER = ST_INFEASIBLE_UPPER + UNDEFINED = ST_UNDEFINED + +cdef class PyReturnValue: + TERMINAL_LIST_ELEMENT = -1 + SUCCESSFUL_RETURN = 0 + DIV_BY_ZERO = RET_DIV_BY_ZERO + INDEX_OUT_OF_BOUNDS = RET_INDEX_OUT_OF_BOUNDS + INVALID_ARGUMENTS = RET_INVALID_ARGUMENTS + ERROR_UNDEFINED = RET_ERROR_UNDEFINED + WARNING_UNDEFINED = RET_WARNING_UNDEFINED + INFO_UNDEFINED = RET_INFO_UNDEFINED + EWI_UNDEFINED = RET_EWI_UNDEFINED + AVAILABLE_WITH_LINUX_ONLY = RET_AVAILABLE_WITH_LINUX_ONLY + UNKNOWN_BUG = RET_UNKNOWN_BUG + PRINTLEVEL_CHANGED = RET_PRINTLEVEL_CHANGED + NOT_YET_IMPLEMENTED = RET_NOT_YET_IMPLEMENTED + INDEXLIST_MUST_BE_REORDERD = RET_INDEXLIST_MUST_BE_REORDERD + INDEXLIST_EXCEEDS_MAX_LENGTH = RET_INDEXLIST_EXCEEDS_MAX_LENGTH + INDEXLIST_CORRUPTED = RET_INDEXLIST_CORRUPTED + INDEXLIST_OUTOFBOUNDS = RET_INDEXLIST_OUTOFBOUNDS + INDEXLIST_ADD_FAILED = RET_INDEXLIST_ADD_FAILED + INDEXLIST_INTERSECT_FAILED = RET_INDEXLIST_INTERSECT_FAILED + INDEX_ALREADY_OF_DESIRED_STATUS = RET_INDEX_ALREADY_OF_DESIRED_STATUS + ADDINDEX_FAILED = RET_ADDINDEX_FAILED + REMOVEINDEX_FAILED = RET_REMOVEINDEX_FAILED + SWAPINDEX_FAILED = RET_SWAPINDEX_FAILED + NOTHING_TO_DO = RET_NOTHING_TO_DO + SETUP_BOUND_FAILED = RET_SETUP_BOUND_FAILED + SETUP_CONSTRAINT_FAILED = RET_SETUP_CONSTRAINT_FAILED + MOVING_BOUND_FAILED = RET_MOVING_BOUND_FAILED + MOVING_CONSTRAINT_FAILED = RET_MOVING_CONSTRAINT_FAILED + SHIFTING_FAILED = RET_SHIFTING_FAILED + ROTATING_FAILED = RET_ROTATING_FAILED + QPOBJECT_NOT_SETUP = RET_QPOBJECT_NOT_SETUP + QP_ALREADY_INITIALISED = RET_QP_ALREADY_INITIALISED + NO_INIT_WITH_STANDARD_SOLVER = RET_NO_INIT_WITH_STANDARD_SOLVER + RESET_FAILED = RET_RESET_FAILED + INIT_FAILED = RET_INIT_FAILED + INIT_FAILED_TQ = RET_INIT_FAILED_TQ + INIT_FAILED_CHOLESKY = RET_INIT_FAILED_CHOLESKY + INIT_FAILED_HOTSTART = RET_INIT_FAILED_HOTSTART + INIT_FAILED_INFEASIBILITY = RET_INIT_FAILED_INFEASIBILITY + INIT_FAILED_UNBOUNDEDNESS = RET_INIT_FAILED_UNBOUNDEDNESS + INIT_FAILED_REGULARISATION = RET_INIT_FAILED_REGULARISATION + INIT_SUCCESSFUL = RET_INIT_SUCCESSFUL + OBTAINING_WORKINGSET_FAILED = RET_OBTAINING_WORKINGSET_FAILED + SETUP_WORKINGSET_FAILED = RET_SETUP_WORKINGSET_FAILED + SETUP_AUXILIARYQP_FAILED = RET_SETUP_AUXILIARYQP_FAILED + NO_CHOLESKY_WITH_INITIAL_GUESS = RET_NO_CHOLESKY_WITH_INITIAL_GUESS + NO_EXTERN_SOLVER = RET_NO_EXTERN_SOLVER + QP_UNBOUNDED = RET_QP_UNBOUNDED + QP_INFEASIBLE = RET_QP_INFEASIBLE + QP_NOT_SOLVED = RET_QP_NOT_SOLVED + QP_SOLVED = RET_QP_SOLVED + UNABLE_TO_SOLVE_QP = RET_UNABLE_TO_SOLVE_QP + INITIALISATION_STARTED = RET_INITIALISATION_STARTED + HOTSTART_FAILED = RET_HOTSTART_FAILED + HOTSTART_FAILED_TO_INIT = RET_HOTSTART_FAILED_TO_INIT + HOTSTART_FAILED_AS_QP_NOT_INITIALISED = RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED + ITERATION_STARTED = RET_ITERATION_STARTED + SHIFT_DETERMINATION_FAILED = RET_SHIFT_DETERMINATION_FAILED + STEPDIRECTION_DETERMINATION_FAILED = RET_STEPDIRECTION_DETERMINATION_FAILED + STEPLENGTH_DETERMINATION_FAILED = RET_STEPLENGTH_DETERMINATION_FAILED + OPTIMAL_SOLUTION_FOUND = RET_OPTIMAL_SOLUTION_FOUND + HOMOTOPY_STEP_FAILED = RET_HOMOTOPY_STEP_FAILED + HOTSTART_STOPPED_INFEASIBILITY = RET_HOTSTART_STOPPED_INFEASIBILITY + HOTSTART_STOPPED_UNBOUNDEDNESS = RET_HOTSTART_STOPPED_UNBOUNDEDNESS + WORKINGSET_UPDATE_FAILED = RET_WORKINGSET_UPDATE_FAILED + MAX_NWSR_REACHED = RET_MAX_NWSR_REACHED + CONSTRAINTS_NOT_SPECIFIED = RET_CONSTRAINTS_NOT_SPECIFIED + INVALID_FACTORISATION_FLAG = RET_INVALID_FACTORISATION_FLAG + UNABLE_TO_SAVE_QPDATA = RET_UNABLE_TO_SAVE_QPDATA + STEPDIRECTION_FAILED_TQ = RET_STEPDIRECTION_FAILED_TQ + STEPDIRECTION_FAILED_CHOLESKY = RET_STEPDIRECTION_FAILED_CHOLESKY + CYCLING_DETECTED = RET_CYCLING_DETECTED + CYCLING_NOT_RESOLVED = RET_CYCLING_NOT_RESOLVED + CYCLING_RESOLVED = RET_CYCLING_RESOLVED + STEPSIZE = RET_STEPSIZE + STEPSIZE_NONPOSITIVE = RET_STEPSIZE_NONPOSITIVE + SETUPSUBJECTTOTYPE_FAILED = RET_SETUPSUBJECTTOTYPE_FAILED + ADDCONSTRAINT_FAILED = RET_ADDCONSTRAINT_FAILED + ADDCONSTRAINT_FAILED_INFEASIBILITY = RET_ADDCONSTRAINT_FAILED_INFEASIBILITY + ADDBOUND_FAILED = RET_ADDBOUND_FAILED + ADDBOUND_FAILED_INFEASIBILITY = RET_ADDBOUND_FAILED_INFEASIBILITY + REMOVECONSTRAINT_FAILED = RET_REMOVECONSTRAINT_FAILED + REMOVEBOUND_FAILED = RET_REMOVEBOUND_FAILED + REMOVE_FROM_ACTIVESET = RET_REMOVE_FROM_ACTIVESET + ADD_TO_ACTIVESET = RET_ADD_TO_ACTIVESET + REMOVE_FROM_ACTIVESET_FAILED = RET_REMOVE_FROM_ACTIVESET_FAILED + ADD_TO_ACTIVESET_FAILED = RET_ADD_TO_ACTIVESET_FAILED + CONSTRAINT_ALREADY_ACTIVE = RET_CONSTRAINT_ALREADY_ACTIVE + ALL_CONSTRAINTS_ACTIVE = RET_ALL_CONSTRAINTS_ACTIVE + LINEARLY_DEPENDENT = RET_LINEARLY_DEPENDENT + LINEARLY_INDEPENDENT = RET_LINEARLY_INDEPENDENT + LI_RESOLVED = RET_LI_RESOLVED + ENSURELI_FAILED = RET_ENSURELI_FAILED + ENSURELI_FAILED_TQ = RET_ENSURELI_FAILED_TQ + ENSURELI_FAILED_NOINDEX = RET_ENSURELI_FAILED_NOINDEX + ENSURELI_FAILED_CYCLING = RET_ENSURELI_FAILED_CYCLING + BOUND_ALREADY_ACTIVE = RET_BOUND_ALREADY_ACTIVE + ALL_BOUNDS_ACTIVE = RET_ALL_BOUNDS_ACTIVE + CONSTRAINT_NOT_ACTIVE = RET_CONSTRAINT_NOT_ACTIVE + BOUND_NOT_ACTIVE = RET_BOUND_NOT_ACTIVE + HESSIAN_NOT_SPD = RET_HESSIAN_NOT_SPD + HESSIAN_INDEFINITE = RET_HESSIAN_INDEFINITE + MATRIX_SHIFT_FAILED = RET_MATRIX_SHIFT_FAILED + MATRIX_FACTORISATION_FAILED = RET_MATRIX_FACTORISATION_FAILED + PRINT_ITERATION_FAILED = RET_PRINT_ITERATION_FAILED + NO_GLOBAL_MESSAGE_OUTPUTFILE = RET_NO_GLOBAL_MESSAGE_OUTPUTFILE + DISABLECONSTRAINTS_FAILED = RET_DISABLECONSTRAINTS_FAILED + ENABLECONSTRAINTS_FAILED = RET_ENABLECONSTRAINTS_FAILED + ALREADY_ENABLED = RET_ALREADY_ENABLED + ALREADY_DISABLED = RET_ALREADY_DISABLED + NO_HESSIAN_SPECIFIED = RET_NO_HESSIAN_SPECIFIED + USING_REGULARISATION = RET_USING_REGULARISATION + EPS_MUST_BE_POSITVE = RET_EPS_MUST_BE_POSITVE + REGSTEPS_MUST_BE_POSITVE = RET_REGSTEPS_MUST_BE_POSITVE + HESSIAN_ALREADY_REGULARISED = RET_HESSIAN_ALREADY_REGULARISED + CANNOT_REGULARISE_IDENTITY = RET_CANNOT_REGULARISE_IDENTITY + CANNOT_REGULARISE_SPARSE = RET_CANNOT_REGULARISE_SPARSE + NO_REGSTEP_NWSR = RET_NO_REGSTEP_NWSR + FEWER_REGSTEPS_NWSR = RET_FEWER_REGSTEPS_NWSR + CHOLESKY_OF_ZERO_HESSIAN = RET_CHOLESKY_OF_ZERO_HESSIAN + ZERO_HESSIAN_ASSUMED = RET_ZERO_HESSIAN_ASSUMED + CONSTRAINTS_ARE_NOT_SCALED = RET_CONSTRAINTS_ARE_NOT_SCALED + INITIAL_BOUNDS_STATUS_NYI = RET_INITIAL_BOUNDS_STATUS_NYI + ERROR_IN_CONSTRAINTPRODUCT = RET_ERROR_IN_CONSTRAINTPRODUCT + FIX_BOUNDS_FOR_LP = RET_FIX_BOUNDS_FOR_LP + USE_REGULARISATION_FOR_LP = RET_USE_REGULARISATION_FOR_LP + UPDATEMATRICES_FAILED = RET_UPDATEMATRICES_FAILED + UPDATEMATRICES_FAILED_AS_QP_NOT_SOLVED= RET_UPDATEMATRICES_FAILED_AS_QP_NOT_SOLVED + UNABLE_TO_OPEN_FILE = RET_UNABLE_TO_OPEN_FILE + UNABLE_TO_WRITE_FILE = RET_UNABLE_TO_WRITE_FILE + UNABLE_TO_READ_FILE = RET_UNABLE_TO_READ_FILE + FILEDATA_INCONSISTENT = RET_FILEDATA_INCONSISTENT + UNABLE_TO_ANALYSE_QPROBLEM = RET_UNABLE_TO_ANALYSE_QPROBLEM + OPTIONS_ADJUSTED = RET_OPTIONS_ADJUSTED + NWSR_SET_TO_ONE = RET_NWSR_SET_TO_ONE + UNABLE_TO_READ_BENCHMARK = RET_UNABLE_TO_READ_BENCHMARK + BENCHMARK_ABORTED = RET_BENCHMARK_ABORTED + INITIAL_QP_SOLVED = RET_INITIAL_QP_SOLVED + QP_SOLUTION_STARTED = RET_QP_SOLUTION_STARTED + BENCHMARK_SUCCESSFUL = RET_BENCHMARK_SUCCESSFUL + NO_DIAGONAL_AVAILABLE = RET_NO_DIAGONAL_AVAILABLE + DIAGONAL_NOT_INITIALISED = RET_DIAGONAL_NOT_INITIALISED + ENSURELI_DROPPED = RET_ENSURELI_DROPPED + KKT_MATRIX_SINGULAR = RET_KKT_MATRIX_SINGULAR + QR_FACTORISATION_FAILED = RET_QR_FACTORISATION_FAILED + INERTIA_CORRECTION_FAILED = RET_INERTIA_CORRECTION_FAILED + NO_SPARSE_SOLVER = RET_NO_SPARSE_SOLVER + SIMPLE_STATUS_P1 = RET_SIMPLE_STATUS_P1 + SIMPLE_STATUS_P0 = RET_SIMPLE_STATUS_P0 + SIMPLE_STATUS_M1 = RET_SIMPLE_STATUS_M1 + SIMPLE_STATUS_M2 = RET_SIMPLE_STATUS_M2 + SIMPLE_STATUS_M3 = RET_SIMPLE_STATUS_M3 + + + +cdef class PyOptions: + cdef Options *thisptr # hold a C++ instance which we're wrapping + def __cinit__(self): + # FIXME: add support for the other constructors + self.thisptr = new Options() + + def __dealloc__(self): + del self.thisptr + + def setToDefault(self): + return self.thisptr.setToDefault() + + def setToReliable(self): + return self.thisptr.setToReliable() + + def setToMPC(self): + return self.thisptr.setToMPC() + + def setToFast(self): + return self.thisptr.setToFast() + + def ensureConsistency(self): + return self.thisptr.ensureConsistency() + + property printLevel: + def __get__(self): return self.thisptr.printLevel + def __set__(self, printLevel): self.thisptr.printLevel = printLevel + + property enableRamping: + def __get__(self): return self.thisptr.enableRamping + def __set__(self, enableRamping): self.thisptr.enableRamping = enableRamping + + property enableFarBounds: + def __get__(self): return self.thisptr.enableFarBounds + def __set__(self, enableFarBounds): self.thisptr.enableFarBounds = enableFarBounds + + property enableFlippingBounds: + def __get__(self): return self.thisptr.enableFlippingBounds + def __set__(self, enableFlippingBounds): self.thisptr.enableFlippingBounds = enableFlippingBounds + + property enableRegularisation: + def __get__(self): return self.thisptr.enableRegularisation + def __set__(self, enableRegularisation): self.thisptr.enableRegularisation = enableRegularisation + + property enableFullLITests: + def __get__(self): return self.thisptr.enableFullLITests + def __set__(self, enableFullLITests): self.thisptr.enableFullLITests = enableFullLITests + + property enableNZCTests: + def __get__(self): return self.thisptr.enableNZCTests + def __set__(self, enableNZCTests): self.thisptr.enableNZCTests = enableNZCTests + + property enableDriftCorrection: + def __get__(self): return self.thisptr.enableDriftCorrection + def __set__(self, enableDriftCorrection): self.thisptr.enableDriftCorrection = enableDriftCorrection + + property enableCholeskyRefactorisation: + def __get__(self): return self.thisptr.enableCholeskyRefactorisation + def __set__(self, enableCholeskyRefactorisation): self.thisptr.enableCholeskyRefactorisation = enableCholeskyRefactorisation + + property enableEqualities: + def __get__(self): return self.thisptr.enableEqualities + def __set__(self, enableEqualities): self.thisptr.enableEqualities = enableEqualities + + property terminationTolerance: + def __get__(self): return self.thisptr.terminationTolerance + def __set__(self, terminationTolerance): self.thisptr.terminationTolerance = terminationTolerance + + property boundTolerance: + def __get__(self): return self.thisptr.boundTolerance + def __set__(self, boundTolerance): self.thisptr.boundTolerance = boundTolerance + + property boundRelaxation: + def __get__(self): return self.thisptr.boundRelaxation + def __set__(self, boundRelaxation): self.thisptr.boundRelaxation = boundRelaxation + + property epsNum: + def __get__(self): return self.thisptr.epsNum + def __set__(self, epsNum): self.thisptr.epsNum = epsNum + + property epsDen: + def __get__(self): return self.thisptr.epsDen + def __set__(self, epsDen): self.thisptr.epsDen = epsDen + + property maxPrimalJump: + def __get__(self): return self.thisptr.maxPrimalJump + def __set__(self, maxPrimalJump): self.thisptr.maxPrimalJump = maxPrimalJump + + property maxDualJump: + def __get__(self): return self.thisptr.maxDualJump + def __set__(self, maxDualJump): self.thisptr.maxDualJump = maxDualJump + + property initialRamping: + def __get__(self): return self.thisptr.initialRamping + def __set__(self, initialRamping): self.thisptr.initialRamping = initialRamping + + property finalRamping: + def __get__(self): return self.thisptr.finalRamping + def __set__(self, finalRamping): self.thisptr.finalRamping = finalRamping + + property initialFarBounds: + def __get__(self): return self.thisptr.initialFarBounds + def __set__(self, initialFarBounds): self.thisptr.initialFarBounds = initialFarBounds + + property growFarBounds: + def __get__(self): return self.thisptr.growFarBounds + def __set__(self, growFarBounds): self.thisptr.growFarBounds = growFarBounds + + property initialStatusBounds: + def __get__(self): return self.thisptr.initialStatusBounds + def __set__(self, initialStatusBounds): self.thisptr.initialStatusBounds = initialStatusBounds + + property epsFlipping: + def __get__(self): return self.thisptr.epsFlipping + def __set__(self, epsFlipping): self.thisptr.epsFlipping = epsFlipping + + property numRegularisationSteps: + def __get__(self): return self.thisptr.numRegularisationSteps + def __set__(self, numRegularisationSteps): self.thisptr.numRegularisationSteps = numRegularisationSteps + + property epsRegularisation: + def __get__(self): return self.thisptr.epsRegularisation + def __set__(self, epsRegularisation): self.thisptr.epsRegularisation = epsRegularisation + + property numRefinementSteps: + def __get__(self): return self.thisptr.numRefinementSteps + def __set__(self, numRefinementSteps): self.thisptr.numRefinementSteps = numRefinementSteps + + property epsIterRef: + def __get__(self): return self.thisptr.epsIterRef + def __set__(self, epsIterRef): self.thisptr.epsIterRef = epsIterRef + + property epsLITests: + def __get__(self): return self.thisptr.epsLITests + def __set__(self, epsLITests): self.thisptr.epsLITests = epsLITests + + property epsNZCTests: + def __get__(self): return self.thisptr.epsNZCTests + def __set__(self, epsNZCTests): self.thisptr.epsNZCTests = epsNZCTests + + property dropBoundPriority: + def __get__(self): return self.thisptr.dropBoundPriority + def __set__(self, dropBoundPriority): self.thisptr.dropBoundPriority = dropBoundPriority + + property dropEqConPriority: + def __get__(self): return self.thisptr.dropEqConPriority + def __set__(self, dropEqConPriority): self.thisptr.dropEqConPriority = dropEqConPriority + + property dropIneqConPriority: + def __get__(self): return self.thisptr.dropIneqConPriority + def __set__(self, dropIneqConPriority): self.thisptr.dropIneqConPriority = dropIneqConPriority + + + +cdef class PyQProblemB: + cdef QProblemB *thisptr # hold a C++ instance which we're wrapping + def __cinit__(self, long nV): + # FIXME: allow other HessianTypes! + self.thisptr = new QProblemB( nV, HST_UNKNOWN, BT_TRUE) + + def __dealloc__(self): + del self.thisptr + + def init(self, + np.ndarray[np.double_t, ndim=2] H, + np.ndarray[np.double_t, ndim=1] g, + np.ndarray[np.double_t, ndim=1] lb, + np.ndarray[np.double_t, ndim=1] ub, + nWSR, + cputime = 0.0 + ): + # FIXME: add asserts + cdef np.ndarray nWSR_tmp + cdef np.ndarray cput_tmp + + # enable nWSR as return value in argument list + if isinstance(nWSR, long) or isinstance(nWSR, int): + deprecation_warning_nWSR() + nWSR_tmp = np.array([nWSR], dtype=long) + else: + nWSR_tmp = nWSR + + if cputime > 1.e-16: + # enable cputime as return value in argument list + if isinstance(cputime, float): + deprecation_warning_cputime() + cput_tmp = np.array([cputime], dtype=float) + else: + cput_tmp = cputime + + return self.thisptr.init( + H.data, + g.data, + lb.data, + ub.data, + nWSR_tmp.data[0], + &cput_tmp.data[0] + ) + + return self.thisptr.init( + H.data, + g.data, + lb.data, + ub.data, + nWSR_tmp.data[0] + ) + + def hotstart(self, + np.ndarray[np.double_t, ndim=1] g, + np.ndarray[np.double_t, ndim=1] lb, + np.ndarray[np.double_t, ndim=1] ub, + nWSR, + cputime = 0.0 + ): + # FIXME: add asserts + cdef np.ndarray nWSR_tmp + cdef np.ndarray cput_tmp + + # enable nWSR as return value in argument list + if isinstance(nWSR, long) or isinstance(nWSR, int): + deprecation_warning_nWSR() + nWSR_tmp = np.array([nWSR], dtype=long) + else: + nWSR_tmp = nWSR#np.asarray(nWSR, dtype=int) + + if cputime > 1.e-16: + # enable cputime as return value in argument list + if isinstance(cputime, float): + deprecation_warning_cputime() + cput_tmp = np.array([cputime], dtype=float) + else: + cput_tmp = cputime#np.asarray(cputime, dtype=float) + + return self.thisptr.hotstart( + g.data, + lb.data, + ub.data, + nWSR_tmp.data[0], + &cput_tmp.data[0] + ) + + return self.thisptr.hotstart( + g.data, + lb.data, + ub.data, + nWSR_tmp.data[0] + ) + + def getPrimalSolution(self, np.ndarray[np.double_t, ndim=1] xOpt): + return self.thisptr.getPrimalSolution( xOpt.data) + + def getDualSolution(self, np.ndarray[np.double_t, ndim=1] yOpt): + return self.thisptr.getDualSolution( yOpt.data) + + def getObjVal(self): + return self.thisptr.getObjVal() + + def printOptions(self): + return self.thisptr.printOptions() + + def getOptions(self): + # FIXME: memory management? who deallocates o + cdef Options *o = new Options(self.thisptr.getOptions()) + retval = PyOptions() + retval.thisptr = o + return retval + + def setOptions(self, PyOptions options): + self.thisptr.setOptions(deref(options.thisptr)) + + +cdef class PyQProblem: + cdef QProblem *thisptr # hold a C++ instance which we're wrapping + + def __cinit__(self, long nV, long nC): + self.thisptr = new QProblem(nV, nC, HST_UNKNOWN, BT_TRUE) + + def __dealloc__(self): + del self.thisptr + + cpdef init(self, + np.ndarray[np.double_t, ndim=2] H, + np.ndarray[np.double_t, ndim=1] g, + np.ndarray[np.double_t, ndim=2] A, + np.ndarray[np.double_t, ndim=1] lb, + np.ndarray[np.double_t, ndim=1] ub, + np.ndarray[np.double_t, ndim=1] lbA, + np.ndarray[np.double_t, ndim=1] ubA, + nWSR, + cputime=0.0): + + # FIXME: add asserts + cdef np.ndarray nWSR_tmp + cdef np.ndarray cput_tmp + + # enable nWSR as return value in argument list + if isinstance(nWSR, long) or isinstance(nWSR, int): + deprecation_warning_nWSR() + nWSR_tmp = np.array([nWSR], dtype=long) + else: + nWSR_tmp = nWSR + + if cputime > 1.e-16: + # enable cputime as return value in argument list + if isinstance(cputime, float): + deprecation_warning_cputime() + cput_tmp = np.array([cputime], dtype=float) + else: + cput_tmp = cputime + + return self.thisptr.init( + H.data, + g.data, + A.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + nWSR_tmp.data[0], + &cput_tmp.data[0] + ) + + return self.thisptr.init( + H.data, + g.data, + A.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + nWSR_tmp.data[0] + ) + + cpdef hotstart(self, + np.ndarray[np.double_t, ndim=1] g, + np.ndarray[np.double_t, ndim=1] lb, + np.ndarray[np.double_t, ndim=1] ub, + np.ndarray[np.double_t, ndim=1] lbA, + np.ndarray[np.double_t, ndim=1] ubA, + nWSR, + cputime=0.0 + ): + # FIXME: add asserts + cdef np.ndarray nWSR_tmp + cdef np.ndarray cput_tmp + + # enable nWSR as return value in argument list + if isinstance(nWSR, long) or isinstance(nWSR, int): + deprecation_warning_nWSR() + nWSR_tmp = np.array([nWSR], dtype=long) + else: + nWSR_tmp = nWSR + + if cputime > 1.e-16: + # enable cputime as return value in argument list + if isinstance(cputime, float): + deprecation_warning_cputime() + cput_tmp = np.array([cputime], dtype=float) + else: + cput_tmp = cputime + + return self.thisptr.hotstart( + g.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + nWSR_tmp.data[0], + &cput_tmp.data[0] + ) + + return self.thisptr.hotstart( + g.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + nWSR_tmp.data[0] + ) + + cpdef getPrimalSolution(self, np.ndarray[np.double_t, ndim=1] xOpt): + return self.thisptr.getPrimalSolution( xOpt.data) + + cpdef getDualSolution(self, np.ndarray[np.double_t, ndim=1] yOpt): + return self.thisptr.getDualSolution( yOpt.data) + + cpdef getObjVal(self): + return self.thisptr.getObjVal() + + cpdef printOptions(self): + return self.thisptr.printOptions() + + cpdef setOptions(self, PyOptions options): + self.thisptr.setOptions(deref(options.thisptr)) + + +cdef class PySQProblem: + cdef SQProblem *thisptr # hold a C++ instance which we're wrapping + + def __cinit__(self, long nV, long nC): + self.thisptr = new SQProblem(nV, nC, HST_UNKNOWN, BT_TRUE) + + def __dealloc__(self): + del self.thisptr + + cpdef init(self, + np.ndarray[np.double_t, ndim=2] H, + np.ndarray[np.double_t, ndim=1] g, + np.ndarray[np.double_t, ndim=2] A, + np.ndarray[np.double_t, ndim=1] lb, + np.ndarray[np.double_t, ndim=1] ub, + np.ndarray[np.double_t, ndim=1] lbA, + np.ndarray[np.double_t, ndim=1] ubA, + nWSR, + cputime=0.0 + ): + # FIXME: add asserts + cpdef np.ndarray nWSR_tmp + cpdef np.ndarray cput_tmp + # nWSR_tmp = np.zeros(1, dtype=long) + # cput_tmp = np.zeros(1, dtype=float) + + # enable nWSR as return value in argument list + if isinstance(nWSR, long) or isinstance(nWSR, int): + deprecation_warning_nWSR() + nWSR_tmp = np.array([nWSR], dtype=long) + else: + nWSR_tmp = np.asarray(nWSR, dtype=long) + + if cputime > 1.e-16: + # enable cputime as return value in argument list + if isinstance(cputime, float): + deprecation_warning_cputime() + cput_tmp = np.array([cputime], dtype=float) + else: + cput_tmp = cputime + # print "cput_tmp: ", cput_tmp + + return self.thisptr.init( + H.data, + g.data, + A.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + nWSR_tmp.data[0], + &cput_tmp.data[0] + ) + + return self.thisptr.init( + H.data, + g.data, + A.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + nWSR_tmp.data[0], + ) + + cpdef hotstart(self, + np.ndarray[np.double_t, ndim=2] H, + np.ndarray[np.double_t, ndim=1] g, + np.ndarray[np.double_t, ndim=2] A, + np.ndarray[np.double_t, ndim=1] lb, + np.ndarray[np.double_t, ndim=1] ub, + np.ndarray[np.double_t, ndim=1] lbA, + np.ndarray[np.double_t, ndim=1] ubA, + nWSR, + cputime=0.0): + + # FIXME: add asserts + cdef np.ndarray nWSR_tmp + cdef np.ndarray cput_tmp + + # enable nWSR as return value in argument list + if isinstance(nWSR, long) or isinstance(nWSR, int): + deprecation_warning_nWSR() + nWSR_tmp = np.array([nWSR], dtype=long) + else: + nWSR_tmp = nWSR + + if cputime > 1.e-16: + # enable cputime as return value in argument list + if isinstance(cputime, float): + deprecation_warning_cputime() + cput_tmp = np.array([cputime], dtype=float) + else: + cput_tmp = cputime + + return self.thisptr.hotstart( + H.data, + g.data, + A.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + nWSR_tmp.data[0], + &cput_tmp.data[0] + ) + + return self.thisptr.hotstart( + H.data, + g.data, + A.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + nWSR_tmp.data[0], + ) + + cpdef getPrimalSolution(self, np.ndarray[np.double_t, ndim=1] xOpt): + return self.thisptr.getPrimalSolution( xOpt.data) + + cpdef getDualSolution(self, np.ndarray[np.double_t, ndim=1] yOpt): + return self.thisptr.getDualSolution( yOpt.data) + + cpdef getObjVal(self): + return self.thisptr.getObjVal() + + cpdef printOptions(self): + return self.thisptr.printOptions() + + cpdef setOptions(self, PyOptions options): + self.thisptr.setOptions(deref(options.thisptr)) + + +cdef class PySolutionAnalysis: + cdef SolutionAnalysis *thisptr # hold a C++ instance which we're wrapping + def __cinit__(self): + self.thisptr = new SolutionAnalysis() + def __dealloc__(self): + del self.thisptr + + cpdef getKktViolation(self, qp, + np.ndarray[np.double_t, ndim=1] maxStat, + np.ndarray[np.double_t, ndim=1] maxFeas, + np.ndarray[np.double_t, ndim=1] maxCmpl + ): + """ """ + if isinstance(qp, PyQProblemB): + return self._getKktViolation_QProblemB(qp, maxStat, maxFeas, maxCmpl) + + elif isinstance(qp, PyQProblem): + return self._getKktViolation_QProblem(qp, maxStat, maxFeas, maxCmpl) + + elif isinstance(qp, PySQProblem): + return self._getKktViolation_SQProblem(qp, maxStat, maxFeas, maxCmpl) + + else: + raise ValueError('argument 1 must be QProblemB, QProblem or SQProblem') + + cpdef _getKktViolation_QProblemB(self, + PyQProblemB qp, + np.ndarray[np.double_t, ndim=1] maxStat, + np.ndarray[np.double_t, ndim=1] maxFeas, + np.ndarray[np.double_t, ndim=1] maxCmpl + ): + return self.thisptr.getKktViolation( + qp.thisptr, + maxStat.data[0], + maxFeas.data[0], + maxCmpl.data[0] + ) + + cpdef _getKktViolation_QProblem(self, + PyQProblem qp, + np.ndarray[np.double_t, ndim=1] maxStat, + np.ndarray[np.double_t, ndim=1] maxFeas, + np.ndarray[np.double_t, ndim=1] maxCmpl + ): + return self.thisptr.getKktViolation( + qp.thisptr, + maxStat.data[0], + maxFeas.data[0], + maxCmpl.data[0] + ) + + + cpdef _getKktViolation_SQProblem(self, + PySQProblem qp, + np.ndarray[np.double_t, ndim=1] maxStat, + np.ndarray[np.double_t, ndim=1] maxFeas, + np.ndarray[np.double_t, ndim=1] maxCmpl + ): + return self.thisptr.getKktViolation( + qp.thisptr, + maxStat.data[0], + maxFeas.data[0], + maxCmpl.data[0] + ) + + cpdef getVarianceCovariance(self, + qp, + np.ndarray[np.double_t, ndim=1] g_b_bA_VAR, + np.ndarray[np.double_t, ndim=1] Primal_Dual_VAR ): + + if isinstance(qp, PyQProblemB): + return self._getVarianceCovariance_QProblemB(qp, g_b_bA_VAR, Primal_Dual_VAR) + + elif isinstance(qp, PyQProblem): + return self._getVarianceCovariance_QProblem(qp, g_b_bA_VAR, Primal_Dual_VAR) + + elif isinstance(qp, PySQProblem): + return self._getVarianceCovariance_SQProblem(qp, g_b_bA_VAR, Primal_Dual_VAR) + + else: + raise ValueError('argument 1 must be QProblemB, QProblem or SQProblem') + + cpdef _getVarianceCovariance_QProblemB(self, + PyQProblemB qp, + np.ndarray[np.double_t, ndim=1] g_b_bA_VAR, + np.ndarray[np.double_t, ndim=1] Primal_Dual_VAR ): + return self.thisptr.getVarianceCovariance(qp.thisptr, + g_b_bA_VAR.data, + Primal_Dual_VAR.data) + + cpdef _getVarianceCovariance_QProblem(self, + PyQProblem qp, + np.ndarray[np.double_t, ndim=1] g_b_bA_VAR, + np.ndarray[np.double_t, ndim=1] Primal_Dual_VAR ): + return self.thisptr.getVarianceCovariance(qp.thisptr, + g_b_bA_VAR.data, + Primal_Dual_VAR.data) + + cpdef _getVarianceCovariance_SQProblem(self, + PySQProblem qp, + np.ndarray[np.double_t, ndim=1] g_b_bA_VAR, + np.ndarray[np.double_t, ndim=1] Primal_Dual_VAR ): + return self.thisptr.getVarianceCovariance(qp.thisptr, + g_b_bA_VAR.data, + Primal_Dual_VAR.data) + +# Wrapped some utility functions for unit testing +cpdef py_runOqpBenchmark(path, # Full path of the benchmark files (without trailing slash!). + isSparse, # Shall convert matrices to sparse format before solution? + useHotstarts, # Shall QP solution be hotstarted? + PyOptions options, # QP solver options to be used while solving benchmark problems. + long maxAllowedNWSR, # Maximum number of working set recalculations to be performed. + double maxCPUTime, # Maximum allowed CPU time for qp solving. + ): + """run a QP benchmark example""" + maxNWSR = 0.0 # Output: Maximum number of performed working set recalculations. + avgNWSR = 0.0 # Output: Average number of performed working set recalculations. + maxCPUtime = 0.0 # Output: Maximum CPU time required for solving each QP. + avgCPUtime = 0.0 # Output: Average CPU time required for solving each QP. + maxStationarity = 0.0 # Output: Maximum residual of stationarity condition. + maxFeasibility = 0.0 # Output: Maximum residual of primal feasibility condition. + maxComplementarity = 0.0 # Output: Maximum residual of complementarity condition. + +""" +def py_getKktViolation(long nV, # Number of variables. + long nC, # Number of constraints. + np.ndarray[np.double_t, ndim=2] H, # Hessian matrix. + np.ndarray[np.double_t, ndim=1] g, # Sequence of gradient vectors. + np.ndarray[np.double_t, ndim=2] A, # Constraint matrix. + np.ndarray[np.double_t, ndim=1] lb, # Sequence of lower bound vectors (on variables). + np.ndarray[np.double_t, ndim=1] ub, # Sequence of upper bound vectors (on variables). + np.ndarray[np.double_t, ndim=1] lbA, # Sequence of lower constraints' bound vectors. + np.ndarray[np.double_t, ndim=1] ubA, # Sequence of upper constraints' bound vectors. + np.ndarray[np.double_t, ndim=1] x, # Sequence of primal trial vectors. + np.ndarray[np.double_t, ndim=1] y, # Sequence of dual trial vectors. + ): + stat = 0.0 # Maximum value of stationarity condition residual. + feas = 0.0 # Maximum value of primal feasibility violation. + cmpl = 0.0 # Maximum value of complementarity residual. + getKktViolation(nV, + nC, + H.data, + g.data, + A.data, + lb.data, + ub.data, + lbA.data, + ubA.data, + x.data, + y.data, + stat, + feas, + cmpl + ) + return stat, feas, cmpl +""" + diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/setup.py b/locomotion/src/third_party/qpOASES/interfaces/python/setup.py new file mode 100755 index 0000000..913f8da --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/setup.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +"""qpOASES python distutils setup script.""" + +# +# This file is part of qpOASES. +# +# qpOASES -- An Implementation of the Online Active Set Strategy. +# Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +# Christian Kirches et al. All rights reserved. +# +# qpOASES is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# qpOASES is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with qpOASES; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +# +# Filename: setup.py +# Author: Sebastian F. Walter, Manuel Kudruss (thanks to Felix Lenders) +# Version: 3.2 +# Date: 2013-2017 +# + +import os +import numpy as np +import platform + +from distutils.core import setup +from distutils.extension import Extension +from Cython.Distutils import build_ext +from Cython.Build import cythonize + +BASEDIR = os.path.dirname(os.path.abspath(__file__)) +BASEDIR = os.path.dirname(BASEDIR) +BASEDIR = os.path.dirname(BASEDIR) + +extra_params = {} +extra_params['include_dirs'] = [ + '/usr/include', + os.path.join(BASEDIR, 'include'), + os.path.join(BASEDIR, 'include', 'qpOASES'), + np.get_include()] +extra_params['extra_compile_args'] = ["-O2", "-Wno-unused-variable"] +extra_params['extra_link_args'] = ["-Wl,-O1", "-Wl,--as-needed"] + +extra_params = extra_params.copy() +extra_params['libraries'] = ['qpOASES'] + +extra_params['library_dirs'] = ['/usr/lib', os.path.join(BASEDIR, 'bin')] +extra_params['language'] = 'c++' + +if platform.system() in ['Linux', 'Darwin']: + extra_params['extra_compile_args'] = ['-D__USE_LONG_INTEGERS__', + '-D__USE_LONG_FINTS__'] + +if platform.system() == 'Darwin': + extra_params['include_dirs'].append( + '/Library/Developer/CommandLineTools/usr/include/c++/v1') + extra_params['extra_compile_args'] += ['-stdlib=libc++', + '-Wno-c++11-long-long'] + extra_params['extra_link_args'] = ['-stdlib=libc++'] # override the others! + +if os.name == 'posix': + extra_params['runtime_library_dirs'] = extra_params['library_dirs'] + # NOTE the python wrapper compiles the interface from the header files + # and therefore requires access to all defines made. + # Therefore, we provide the CPPFLAGS from the make_linux.mk file + # directly to the compile process by extra_compile_args. + # NOTE not all FLAGS can be added automatically, e.g. DEF_SOLVER. + # Please fix this yourself in case of problems. + # TODO maybe add automatic make file parsing and choose from those options + extra_params['extra_compile_args'] += [ + "-Wall", + "-pedantic", + "-Wshadow", + "-Wfloat-equal", + "-O3", + "-Wconversion", + "-Wsign-conversion", + "-finline-functions", + "-fPIC", + "-DLINUX", + "-D__USE_LONG_INTEGERS__", + "-D__USE_LONG_FINTS__", + "-D__NO_COPYRIGHT__", + ] + +ext_modules = [ + Extension("qpoases", ["qpoases.pyx", "qpoases.pxd"], **extra_params), +] + +setup( + name='qpOASES interface', + cmdclass={'build_ext': build_ext}, + ext_modules=cythonize(ext_modules), +) diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/tests/__init__.py b/locomotion/src/third_party/qpOASES/interfaces/python/tests/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/tests/__init__.py @@ -0,0 +1 @@ + diff --git a/locomotion/src/third_party/qpOASES/interfaces/python/tests/test_examples.py b/locomotion/src/third_party/qpOASES/interfaces/python/tests/test_examples.py new file mode 100644 index 0000000..a345188 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/python/tests/test_examples.py @@ -0,0 +1,360 @@ +""" +This file is part of qpOASES. + +qpOASES -- An Implementation of the Online Active Set Strategy. +Copyright (C) 2007-2017 by Hans Joachim Ferreau et al. All rights reserved. + +qpOASES is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +qpOASES is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with qpOASES; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +author Manuel Kudruss +version 3.2 +date 2013-2017 +""" + +import os +import re +import numpy as np +from numpy.testing import * +from subprocess import Popen, PIPE, STDOUT + +from qpoases import PyQProblem as QProblem +from qpoases import PyQProblemB as QProblemB +from qpoases import PySQProblem as SQProblem +from qpoases import PySolutionAnalysis as SolutionAnalysis +from qpoases import PyBooleanType as BooleanType +from qpoases import PySubjectToStatus as SubjectToStatus +from qpoases import PyOptions as Options +from qpoases import PyPrintLevel as PrintLevel + +# get qpOASES path +qpoases_path = os.path.dirname(os.path.abspath(__file__)) +qpoases_path = os.path.dirname(qpoases_path) +qpoases_path = os.path.dirname(qpoases_path) +qpoases_path = os.path.dirname(qpoases_path) + +# set qpOASES binary path +bin_path = os.path.join(qpoases_path, "bin") + +class TestExamples(TestCase): + + def test_example1(self): + return 0 + # Example for qpOASES main function using the QProblem class. + #Setup data of first QP. + + H = np.array([1.0, 0.0, 0.0, 0.5 ]).reshape((2,2)) + A = np.array([1.0, 1.0 ]).reshape((2,1)) + g = np.array([1.5, 1.0 ]) + lb = np.array([0.5, -2.0]) + ub = np.array([5.0, 2.0 ]) + lbA = np.array([-1.0 ]) + ubA = np.array([2.0]) + + # Setup data of second QP. + + g_new = np.array([1.0, 1.5]) + lb_new = np.array([0.0, -1.0]) + ub_new = np.array([5.0, -0.5]) + lbA_new = np.array([-2.0]) + ubA_new = np.array([1.0]) + + # Setting up QProblemB object. + qp = QProblem(2, 1) + options = Options() + options.printLevel = PrintLevel.NONE + qp.setOptions(options) + + # Solve first QP. + nWSR = 10 + qp.init(H, g, A, lb, ub, lbA, ubA, nWSR) + + # Solve second QP. + nWSR = 10 + qp.hotstart(g_new, lb_new, ub_new, lbA_new, ubA_new, nWSR) + + # Get and print solution of second QP. + xOpt_actual = np.zeros(2) + qp.getPrimalSolution(xOpt_actual) + xOpt_actual = np.asarray(xOpt_actual, dtype=float) + objVal_actual = qp.getObjVal() + objVal_actual = np.asarray(objVal_actual, dtype=float) + + cmd = os.path.join(bin_path, "example1") + p = Popen(cmd, shell=True, stdout=PIPE) + stdout, stderr = p.communicate() + stdout = str(stdout).replace('\\n', '\n') + stdout = stdout.replace("'", '') + print(stdout) + + # get c++ solution from std + pattern = re.compile(r'xOpt\s*=\s*\[\s+(?P([0-9., e+-])*)\];') + match = pattern.search(stdout) + xOpt_expected = match.group('xOpt') + xOpt_expected = xOpt_expected.split(",") + xOpt_expected = np.asarray(xOpt_expected, dtype=float) + + pattern = re.compile(r'objVal = (?P[0-9-+e.]*)') + match = pattern.search(stdout) + objVal_expected = match.group('objVal') + objVal_expected = np.asarray(objVal_expected, dtype=float) + + print("xOpt_actual =", xOpt_actual) + print("xOpt_expected =", xOpt_expected) + print("objVal_actual = ", objVal_actual) + print("objVal_expected = ", objVal_expected) + + assert_almost_equal(xOpt_actual, xOpt_expected, decimal=7) + assert_almost_equal(objVal_actual, objVal_expected, decimal=7) + + def test_example1b(self): + """Example for qpOASES main function using the QProblemB class.""" + # Setup data of first QP. + H = np.array([1.0, 0.0, 0.0, 0.5]).reshape((2, 2)) + g = np.array([1.5, 1.0]) + lb = np.array([0.5, -2.0]) + ub = np.array([5.0, 2.0]) + + # Setup data of second QP. + + g_new = np.array([1.0, 1.5]) + lb_new = np.array([0.0, -1.0]) + ub_new = np.array([5.0, -0.5]) + + # Setting up QProblemB object. + qp = QProblemB(2) + + options = Options() + # options.enableFlippingBounds = BooleanType.FALSE + options.initialStatusBounds = SubjectToStatus.INACTIVE + options.numRefinementSteps = 1 + options.enableCholeskyRefactorisation = 1 + options.printLevel = PrintLevel.NONE + qp.setOptions(options) + + # Solve first QP. + nWSR = 10 + qp.init(H, g, lb, ub, nWSR) + + xOpt_actual = np.zeros(2) + qp.getPrimalSolution(xOpt_actual) + xOpt_actual = np.asarray(xOpt_actual, dtype=float) + objVal_actual = qp.getObjVal() + objVal_actual = np.asarray(objVal_actual, dtype=float) + print 'xOpt_actual:', xOpt_actual + print 'objVal_actual:', objVal_actual + + # Solve second QP. + nWSR = 10 + qp.hotstart(g_new, lb_new, ub_new, nWSR) + + xOpt_actual = np.zeros(2) + qp.getPrimalSolution(xOpt_actual) + xOpt_actual = np.asarray(xOpt_actual, dtype=float) + objVal_actual = qp.getObjVal() + objVal_actual = np.asarray(objVal_actual, dtype=float) + print 'xOpt_actual:', xOpt_actual + print 'objVal_actual:', objVal_actual + + # Get and print solution of second QP. + xOpt_actual = np.zeros(2) + qp.getPrimalSolution(xOpt_actual) + xOpt_actual = np.asarray(xOpt_actual, dtype=float) + objVal_actual = qp.getObjVal() + objVal_actual = np.asarray(objVal_actual, dtype=float) + + cmd = os.path.join(bin_path, "example1b") + p = Popen(cmd, shell=True, stdout=PIPE) + stdout, stderr = p.communicate() + stdout = str(stdout).replace('\\n', '\n') + stdout = stdout.replace("'", '') + + # get c++ solution from std + pattern = re.compile(r'xOpt\s*=\s*\[\s+(?P([0-9., e+-])*)\];') + match = pattern.findall(stdout) + xOpt_expected = match[-1][0] + xOpt_expected = xOpt_expected.split(",") + xOpt_expected = np.asarray(xOpt_expected, dtype=float) + + pattern = re.compile(r'objVal = (?P[0-9-+e.]*)') + match = pattern.findall(stdout) + print match + objVal_expected = match[-1] + objVal_expected = np.asarray(objVal_expected, dtype=float) + + print("xOpt_actual =", xOpt_actual) + print("xOpt_expected =", xOpt_expected) + print("objVal_actual = ", objVal_actual) + print("objVal_expected = ", objVal_expected) + + assert_almost_equal(xOpt_actual, xOpt_expected, decimal=7) + assert_almost_equal(objVal_actual, objVal_expected, decimal=7) + + + def test_example2(self): + # Example for qpOASES main function using the SQProblem class. + # Setup data of first QP. + H = np.array([ 1.0, 0.0, 0.0, 0.5 ]).reshape((2,2)) + A = np.array([ 1.0, 1.0 ]).reshape((2,1)) + g = np.array([ 1.5, 1.0 ]) + lb = np.array([ 0.5, -2.0 ]) + ub = np.array([ 5.0, 2.0 ]) + lbA = np.array([ -1.0 ]) + ubA = np.array([ 2.0 ]) + + # Setup data of second QP. + H_new = np.array([ 1.0, 0.5, 0.5, 0.5 ]).reshape((2,2)) + A_new = np.array([ 1.0, 5.0 ]).reshape((2,1)) + g_new = np.array([ 1.0, 1.5 ]) + lb_new = np.array([ 0.0, -1.0 ]) + ub_new = np.array([ 5.0, -0.5 ]) + lbA_new = np.array([ -2.0 ]) + ubA_new = np.array([ 1.0 ]) + + # Setting up SQProblem object and solution analyser. + qp = SQProblem(2, 1) + options = Options() + options.printLevel = PrintLevel.NONE + qp.setOptions(options) + + analyser = SolutionAnalysis() + + # get c++ solution from std + cmd = os.path.join(bin_path, "example2") + p = Popen(cmd, shell=True, stdout=PIPE) + stdout, stderr = p.communicate() + stdout = str(stdout).replace('\\n', '\n') + stdout = stdout.replace("'", '') + print(stdout) + + # Solve first QP ... + nWSR = 10 + qp.init(H, g, A, lb, ub, lbA, ubA, nWSR) + + # ... and analyse it. + maxViol = np.zeros(1) + maxStat = np.zeros(1) + maxFeas = np.zeros(1) + maxCmpl = np.zeros(1) + maxViol[0] = analyser.getKktViolation( + qp, maxStat, maxFeas, maxCmpl + ) + print("maxViol: %e\n" % maxViol) + actual = np.asarray(maxViol) + + pattern = re.compile( + r'maxKktViolation: (?P[0-9+-e.]*)' + ) + + match = pattern.findall(stdout) + expected = np.asarray(match[0], dtype=float) + + assert_almost_equal(actual, expected, decimal=7) + + # Solve second QP ... + nWSR = 10 + qp.hotstart( + H_new, g_new, A_new, + lb_new, ub_new, + lbA_new, ubA_new, + nWSR + ) + + # ... and analyse it. + maxViol = np.zeros(1) + maxStat = np.zeros(1) + maxFeas = np.zeros(1) + maxCmpl = np.zeros(1) + maxViol[0] = analyser.getKktViolation( + qp, maxStat, maxFeas, maxCmpl + ) + print("maxViol: %e\n" % maxViol) + actual = np.asarray(maxViol) + + expected = np.asarray(match[1], dtype=float) + + assert_almost_equal(actual, expected, decimal=7) + + # ------------ VARIANCE-COVARIANCE EVALUATION -------------------- + + Var = np.zeros(5*5) + Primal_Dual_Var = np.zeros(5*5) + + Var.reshape((5, 5))[0, 0] = 1. + Var.reshape((5, 5))[1, 1] = 1. + + # ( 1 0 0 0 0 ) + # ( 0 1 0 0 0 ) + # Var = ( 0 0 0 0 0 ) + # ( 0 0 0 0 0 ) + # ( 0 0 0 0 0 ) + + analyser.getVarianceCovariance(qp, Var, Primal_Dual_Var) + print('Primal_Dual_Var=\n', Primal_Dual_Var.reshape((5, 5))) + actual = Primal_Dual_Var.reshape((5, 5)) + + pattern = re.compile( + r'Primal_Dual_VAR = (?P.*)', + re.DOTALL + ) + + print(stdout) + match = pattern.search(stdout) + expected = match.group('VAR').strip().split("\n") + expected = [x.strip().split() for x in expected] + print(expected) + expected = np.asarray(expected, dtype=float) + + assert_almost_equal(actual, expected, decimal=7) + + def test_example7(self): + H = np.array([ + 0.8514828085899353, -0.15739890933036804, -0.081726007163524628, -0.530426025390625, 0.16773293912410736, + -0.15739890933036804, 1.1552412509918213, 0.57780224084854126, -0.0072606131434440613, 0.010559185408055782, + -0.081726007163524628, 0.57780224084854126, 0.28925251960754395, 5.324830453901086e-006, -3.0256599075073609e-006, + -0.530426025390625, -0.0072606131434440613, 5.324830453901086e-006, 0.35609596967697144, -0.15124998986721039, + 0.16773293912410736, 0.010559185408055782, -3.0256599075073609e-006, -0.15124998986721039, 0.15129712224006653 + ], dtype=float + ).reshape((5, 5)) + g = np.array([0.30908384919166565, 0.99325823783874512, 0.49822014570236206, -0.26309865713119507, 0.024296050891280174], dtype=float).reshape((5,)) + A = np.array([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1], dtype=float).reshape((5, 5)) + lb = np.array([-0.052359879016876221, -0.052359879016876221, -0.052359879016876221, -0.052359879016876221, -0.052359938621520996], dtype=float).reshape((5,)) + ub = np.array([ 0.052359879016876221, 0.052359879016876221, 0.052359879016876221, 0, 0], dtype=float).reshape((5,)) + lbA = np.array([-0.052359879016876221, -0.052359879016876221, -0.052359879016876221, -0.052359879016876221, -0.052359938621520996], dtype=float).reshape((5,)) + ubA = np.array([0.052359879016876221, 0.052359879016876221, 0.052359879016876221, 0, 0], dtype=float).reshape((5,)) + + # Setting up QProblem object. + qp = QProblem(5, 5) + options = Options() + options.printLevel = PrintLevel.NONE + qp.setOptions(options) + + # Solve first QP. + nWSR = 100 + qp.init(H, g, A, lb, ub, lbA, ubA, nWSR) + + result = np.zeros((5,)) + qp.getPrimalSolution(result) + + # TODO check against what? + # Where can I find solution? + +if __name__=="__main__": + try: + import nose + nose.runmodule() + + except ImportError: + sys.stderr.write("Please install nosestests for python unittesting.\n") + diff --git a/locomotion/src/third_party/qpOASES/interfaces/scilab/Makefile b/locomotion/src/third_party/qpOASES/interfaces/scilab/Makefile new file mode 100644 index 0000000..c22c2a5 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/scilab/Makefile @@ -0,0 +1,93 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: interfaces/scilab/Makefile +## Author: Holger Diedam, Hans Joachim Ferreau +## Version: 3.2 +## Date: 2007-2017 +## + + + +PATH_LIB = . +PATH_SRC = . +PATH_OBJ = . +PATH_QPOASES_INC = ../../include +PATH_QPOASES_SRC = ../../src +PATH_QPOASES_OBJ = ../../src + + +## +## bins +## + +CC = gcc +CPP = g++ +LD = g++ +CP = cp + + + +## +## flags +## + +CFLAGS = -I$(PATH_QPOASES_INC) -I$(PATH_QPOASES_SRC) -Wall -pedantic -Wshadow -O3 -fPIC +CPPFLAGS = -I$(PATH_QPOASES_INC) -I$(PATH_QPOASES_SRC) -Wall -pedantic -Wshadow -O3 -fPIC -DLINUX -D__SCILAB__ -D__SINGLE_OBJECT__ +LDFLAGS = -shared +LIBEXT = .so + + +LIB = libqpOASESinterface$(LIBEXT) + +OBJ = \ + qpOASESroutines.o \ + qpOASESinterface.o + + + +## +## targets +## + +all: $(PATH_LIB)/$(LIB) + +$(PATH_OBJ)/%.o: $(PATH_SRC)/%.c + $(CC) -c -o $(@) $(CFLAGS) $< + +$(PATH_OBJ)/%.o: $(PATH_SRC)/%.cpp + $(CPP) -c -o $(@) $(CPPFLAGS) $< + +$(PATH_LIB)/$(LIB) : $(addprefix $(PATH_OBJ)/, $(OBJ)) + $(LD) $(LDFLAGS) $^ -o $@ + +clean: + $(RM) $(PATH_OBJ)/*.o $(PATH_LIB)/$(LIB) + + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/interfaces/scilab/example1.dat b/locomotion/src/third_party/qpOASES/interfaces/scilab/example1.dat new file mode 100644 index 0000000000000000000000000000000000000000..1c9e594b6da775ef2a23e6db6ce75a676f91f100 GIT binary patch literal 656 zcmb7AK?;O05bJss77vOy5mvCjnEqU!(jPb{@wiiH&_WOz7}7&C$>dl)#m70<sb9o^zR_9VV>O$x*y427N97KSb=-AQ2z^%n8wouhaIvnpLq1Rst}5DbL4@VzfT>F{bij4{uW zQc5u4)z(O}>f$|oa; +#include + +#include +#include + +#include "../c/qpOASES_wrapper.h" + + + +extern int interface_qpOASES( char* fname ); + +extern int interface_QProblem_init( char* fname ); +extern int interface_QProblemB_init( char* fname ); +extern int interface_SQProblem_init( char* fname ); + +extern int interface_QProblem_hotstart( char* fname ); +extern int interface_QProblemB_hotstart( char* fname ); +extern int interface_SQProblem_hotstart( char* fname ); + +extern int interface_QProblem_cleanup( char* fname ); +extern int interface_QProblemB_cleanup( char* fname ); +extern int interface_SQProblem_cleanup( char* fname ); + + +typedef int (*gate_function) ( char* ); +extern int sci_gateway( char* name, gate_function f ); +extern int C2F(qpOASESgateway)(); + + +/* forward declaration of C++ routines */ +void sci_qpOASES( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t *nV, int_t* nC, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + +void sci_QProblem_init( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t *nV, int_t* nC, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); +void sci_QProblemB_init( real_t* H, real_t* g, real_t* lb, real_t* ub, + int_t *nV, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); +void sci_SQProblem_init( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t *nV, int_t* nC, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + +void sci_QProblem_hotstart( real_t* g, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); +void sci_QProblemB_hotstart( real_t* g, real_t* lb, real_t* ub, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); +void sci_SQProblem_hotstart( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + +void sci_QProblem_cleanup( ); +void sci_QProblemB_cleanup( ); +void sci_SQProblem_cleanup( ); + + +/* global variables containing dimensions of matrices + * (also used to check whether qpOASES object were initialised) */ +static int_t qp_rowsH = -1; +static int_t qp_rowsA = -1; +static int_t qpb_rowsH = -1; +static int_t sqp_rowsH = -1; +static int_t sqp_rowsA = -1; + + +/* + * i n t e r f a c e _ q p O A S E S + */ +int interface_qpOASES( char* fname ) +{ + int_t H, H_rows, H_cols; + int_t g, g_rows, g_cols; + int_t A, A_rows, A_cols; + int_t lb, lb_rows, lb_cols; + int_t ub, ub_rows, ub_cols; + int_t lbA, lbA_rows, lbA_cols; + int_t ubA, ubA_rows, ubA_cols; + int_t nWSR, nWSR_rows, nWSR_cols; + + int_t x, obj, status, nWSRout, y; + + + int minlhs = 1, maxlhs = 5, minrhs = 8, maxrhs = 8, one = 1, y_size; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + + /* check dimensions */ + GetRhsVar( 1,"d", &H_rows,&H_cols,&H ); + if ( ( H_rows != H_cols ) || ( H_rows < 1 ) ) + { + Scierror( 111,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 2,"d", &g_rows,&g_cols,&g ); + if ( !( ( ( g_rows == H_rows ) && ( g_cols == 1 ) ) || ( ( g_rows == 1 ) && ( g_cols == H_rows ) ) ) ) + { + Scierror( 112,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 3,"d", &A_rows,&A_cols,&A ); + if ( ( A_cols != H_rows ) || ( A_rows < 1 ) ) + { + Scierror( 113,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 4,"d", &lb_rows,&lb_cols,&lb); + if ( !( ( ( lb_rows == H_rows ) && ( lb_cols == 1 ) ) || ( ( lb_rows == 0 ) && ( lb_cols == 0 ) ) ) ) + { + Scierror( 114,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 5,"d", &ub_rows,&ub_cols,&ub); + if ( !( ( ( ub_rows == H_rows ) && ( ub_cols == 1 ) ) || ( ( ub_rows == 0 ) && ( ub_cols == 0 ) ) ) ) + { + Scierror( 115,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 6,"d", &lbA_rows,&lbA_cols,&lbA); + if ( !( ( ( lbA_rows == A_rows ) && ( lbA_cols == 1 ) ) || ( ( lbA_rows == 0 ) && ( lbA_cols == 0 ) ) ) ) + { + Scierror( 116,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 7,"d", &ubA_rows,&ubA_cols,&ubA); + if ( !( ( ( ubA_rows == A_rows ) && ( ubA_cols == 1 ) ) || ( ( ubA_rows == 0 ) && ( ubA_cols == 0 ) ) ) ) + { + Scierror( 117,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 8,"i", &nWSR_rows,&nWSR_cols,&nWSR); + if ( ( nWSR_rows != nWSR_cols ) || ( nWSR_cols != 1 ) ) + { + Scierror( 118,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + + y_size = H_rows + A_rows; + + CreateVar( 9,"d", &H_rows,&one,&x ); + CreateVar( 10,"d", &one,&one,&obj ); + CreateVar( 11,"i", &one,&one,&status ); + CreateVar( 12,"i", &one,&one,&nWSRout ); + CreateVar( 13,"d", &y_size,&one,&y ); + + + /* call interfaced qpOASES routines with appropriate arguments */ + sci_qpOASES( stk(H),stk(g),stk(A), (lb_rows!=0) ? stk(lb) : 0, (ub_rows!=0) ? stk(ub) : 0, (lbA_rows!=0) ? stk(lbA) : 0, (ubA_rows!=0) ? stk(ubA) : 0, + &H_rows,&A_rows,istk(nWSR), + stk(x),stk(obj),istk(status),istk(nWSRout),stk(y) + ); + + LhsVar(1) = 9; + LhsVar(2) = 10; + LhsVar(3) = 11; + LhsVar(4) = 12; + LhsVar(5) = 13; + + return 0; +} + + +/* + * i n t e r f a c e _ Q P r o b l e m _ i n i t + */ +int interface_QProblem_init( char* fname ) +{ + int_t H, H_rows, H_cols; + int_t g, g_rows, g_cols; + int_t A, A_rows, A_cols; + int_t lb, lb_rows, lb_cols; + int_t ub, ub_rows, ub_cols; + int_t lbA, lbA_rows, lbA_cols; + int_t ubA, ubA_rows, ubA_cols; + int_t nWSR, nWSR_rows, nWSR_cols; + + int_t x, obj, status, nWSRout, y; + + + int minlhs = 1, maxlhs = 5, minrhs = 8, maxrhs = 8, one = 1, y_size; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + + /* check dimensions */ + GetRhsVar( 1,"d", &H_rows,&H_cols,&H ); + if ( ( H_rows != H_cols ) || ( H_rows < 1 ) ) + { + Scierror( 211,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 2,"d", &g_rows,&g_cols,&g ); + if ( !( ( ( g_rows == H_rows ) && ( g_cols == 1 ) ) || ( ( g_rows == 1 ) && ( g_cols == H_rows ) ) ) ) + { + Scierror( 212,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 3,"d", &A_rows,&A_cols,&A ); + if ( ( A_cols != H_rows ) || ( A_rows < 1 ) ) + { + Scierror( 213,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 4,"d", &lb_rows,&lb_cols,&lb); + if ( !( ( ( lb_rows == H_rows ) && ( lb_cols == 1 ) ) || ( ( lb_rows == 0 ) && ( lb_cols == 0 ) ) ) ) + { + Scierror( 214,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 5,"d", &ub_rows,&ub_cols,&ub); + if ( !( ( ( ub_rows == H_rows ) && ( ub_cols == 1 ) ) || ( ( ub_rows == 0 ) && ( ub_cols == 0 ) ) ) ) + { + Scierror( 215,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 6,"d", &lbA_rows,&lbA_cols,&lbA); + if ( !( ( ( lbA_rows == A_rows ) && ( lbA_cols == 1 ) ) || ( ( lbA_rows == 0 ) && ( lbA_cols == 0 ) ) ) ) + { + Scierror( 216,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 7,"d", &ubA_rows,&ubA_cols,&ubA); + if ( !( ( ( ubA_rows == A_rows ) && ( ubA_cols == 1 ) ) || ( ( ubA_rows == 0 ) && ( ubA_cols == 0 ) ) ) ) + { + Scierror( 217,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 8,"i", &nWSR_rows,&nWSR_cols,&nWSR); + if ( ( nWSR_rows != nWSR_cols ) || ( nWSR_cols != 1 ) ) + { + Scierror( 218,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + + y_size = H_rows + A_rows; + + CreateVar( 9,"d", &H_rows,&one,&x ); + CreateVar( 10,"d", &one,&one,&obj ); + CreateVar( 11,"i", &one,&one,&status ); + CreateVar( 12,"i", &one,&one,&nWSRout ); + CreateVar( 13,"d", &y_size,&one,&y ); + + + qp_rowsH = H_rows; + qp_rowsA = A_rows; + + + /* call interfaced qpOASES routines with appropriate arguments */ + sci_QProblem_init( stk(H),stk(g),stk(A), (lb_rows!=0) ? stk(lb) : 0, (ub_rows!=0) ? stk(ub) : 0, (lbA_rows!=0) ? stk(lbA) : 0, (ubA_rows!=0) ? stk(ubA) : 0, + &H_rows,&A_rows,istk(nWSR), + stk(x),stk(obj),istk(status),istk(nWSRout),stk(y) + ); + + LhsVar(1) = 9; + LhsVar(2) = 10; + LhsVar(3) = 11; + LhsVar(4) = 12; + LhsVar(5) = 13; + + return 0; +} + + +/* + * i n t e r f a c e _ Q P r o b l e m B _ i n i t + */ +int interface_QProblemB_init( char* fname ) +{ + int_t H, H_rows, H_cols; + int_t g, g_rows, g_cols; + int_t lb, lb_rows, lb_cols; + int_t ub, ub_rows, ub_cols; + int_t nWSR, nWSR_rows, nWSR_cols; + + int_t x, obj, status, nWSRout, y; + + + int minlhs = 1, maxlhs = 5, minrhs = 5, maxrhs = 5, one = 1; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + + /* check dimensions */ + GetRhsVar( 1,"d", &H_rows,&H_cols,&H ); + if ( ( H_rows != H_cols ) || ( H_rows < 1 ) ) + { + Scierror( 221,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 2,"d", &g_rows,&g_cols,&g ); + if ( !( ( ( g_rows == H_rows ) && ( g_cols == 1 ) ) || ( ( g_rows == 1 ) && ( g_cols == H_rows ) ) ) ) + { + Scierror( 222,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 3,"d", &lb_rows,&lb_cols,&lb); + if ( !( ( ( lb_rows == H_rows ) && ( lb_cols == 1 ) ) || ( ( lb_rows == 0 ) && ( lb_cols == 0 ) ) ) ) + { + Scierror( 223,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 4,"d", &ub_rows,&ub_cols,&ub); + if ( !( ( ( ub_rows == H_rows ) && ( ub_cols == 1 ) ) || ( ( ub_rows == 0 ) && ( ub_cols == 0 ) ) ) ) + { + Scierror( 224,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 5,"i", &nWSR_rows,&nWSR_cols,&nWSR); + if ( ( nWSR_rows != nWSR_cols ) || ( nWSR_cols != 1 ) ) + { + Scierror( 225,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + + CreateVar( 9,"d", &H_rows,&one,&x ); + CreateVar( 10,"d", &one,&one,&obj ); + CreateVar( 11,"i", &one,&one,&status ); + CreateVar( 12,"i", &one,&one,&nWSRout ); + CreateVar( 13,"d", &H_rows,&one,&y ); + + + qpb_rowsH = H_rows; + + + /* call interfaced qpOASES routines with appropriate arguments */ + sci_QProblemB_init( stk(H),stk(g), (lb_rows!=0) ? stk(lb) : 0, (ub_rows!=0) ? stk(ub) : 0, + &H_rows,istk(nWSR), + stk(x),stk(obj),istk(status),istk(nWSRout),stk(y) + ); + + LhsVar(1) = 9; + LhsVar(2) = 10; + LhsVar(3) = 11; + LhsVar(4) = 12; + LhsVar(5) = 13; + + return 0; +} + + +/* + * i n t e r f a c e _ S Q P r o b l e m _ i n i t + */ +int interface_SQProblem_init( char* fname ) +{ + int_t H, H_rows, H_cols; + int_t g, g_rows, g_cols; + int_t A, A_rows, A_cols; + int_t lb, lb_rows, lb_cols; + int_t ub, ub_rows, ub_cols; + int_t lbA, lbA_rows, lbA_cols; + int_t ubA, ubA_rows, ubA_cols; + int_t nWSR, nWSR_rows, nWSR_cols; + + int_t x, obj, status, nWSRout, y; + + + int minlhs = 1, maxlhs = 5, minrhs = 8, maxrhs = 8, one = 1, y_size; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + + /* check dimensions */ + GetRhsVar( 1,"d", &H_rows,&H_cols,&H ); + if ( ( H_rows != H_cols ) || ( H_rows < 1 ) ) + { + Scierror( 231,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 2,"d", &g_rows,&g_cols,&g ); + if ( !( ( ( g_rows == H_rows ) && ( g_cols == 1 ) ) || ( ( g_rows == 1 ) && ( g_cols == H_rows ) ) ) ) + { + Scierror( 232,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 3,"d", &A_rows,&A_cols,&A ); + if ( ( A_cols != H_rows ) || ( A_rows < 1 ) ) + { + Scierror( 233,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 4,"d", &lb_rows,&lb_cols,&lb ); + if ( !( ( ( lb_rows == H_rows ) && ( lb_cols == 1 ) ) || ( ( lb_rows == 0 ) && ( lb_cols == 0 ) ) ) ) + { + Scierror( 234,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 5,"d", &ub_rows,&ub_cols,&ub ); + if ( !( ( ( ub_rows == H_rows ) && ( ub_cols == 1 ) ) || ( ( ub_rows == 0 ) && ( ub_cols == 0 ) ) ) ) + { + Scierror( 235,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 6,"d", &lbA_rows,&lbA_cols,&lbA ); + if ( !( ( ( lbA_rows == A_rows ) && ( lbA_cols == 1 ) ) || ( ( lbA_rows == 0 ) && ( lbA_cols == 0 ) ) ) ) + { + Scierror( 236,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 7,"d", &ubA_rows,&ubA_cols,&ubA ); + if ( !( ( ( ubA_rows == A_rows ) && ( ubA_cols == 1 ) ) || ( ( ubA_rows == 0 ) && ( ubA_cols == 0 ) ) ) ) + { + Scierror( 237,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 8,"i", &nWSR_rows,&nWSR_cols,&nWSR) ; + if ( ( nWSR_rows != nWSR_cols ) || ( nWSR_cols != 1 ) ) + { + Scierror( 238,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + + y_size = H_rows + A_rows; + + CreateVar( 9,"d", &H_rows,&one,&x ); + CreateVar( 10,"d", &one,&one,&obj ); + CreateVar( 11,"i", &one,&one,&status ); + CreateVar( 12,"i", &one,&one,&nWSRout ); + CreateVar( 13,"d", &y_size,&one,&y ); + + + sqp_rowsH = H_rows; + sqp_rowsA = A_rows; + + + /* call interfaced qpOASES routines with appropriate arguments */ + sci_SQProblem_init( stk(H),stk(g),stk(A), (lb_rows!=0) ? stk(lb) : 0, (ub_rows!=0) ? stk(ub) : 0, (lbA_rows!=0) ? stk(lbA) : 0, (ubA_rows!=0) ? stk(ubA) : 0, + &H_rows,&A_rows,istk(nWSR), + stk(x),stk(obj),istk(status),istk(nWSRout),stk(y) + ); + + LhsVar(1) = 9; + LhsVar(2) = 10; + LhsVar(3) = 11; + LhsVar(4) = 12; + LhsVar(5) = 13; + + return 0; +} + + +/* + * i n t e r f a c e _ Q P r o b l e m _ h o t s t a r t + */ +int interface_QProblem_hotstart( char* fname ) +{ + int_t g, g_rows, g_cols; + int_t lb, lb_rows, lb_cols; + int_t ub, ub_rows, ub_cols; + int_t lbA, lbA_rows, lbA_cols; + int_t ubA, ubA_rows, ubA_cols; + int_t nWSR, nWSR_rows, nWSR_cols; + + int_t x, obj, status, nWSRout, y; + + + int minlhs = 1, maxlhs = 5, minrhs = 6, maxrhs = 6, one = 1, y_size; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + + if ( ( qp_rowsH == -1 ) || ( qp_rowsA == -1 ) ) + { + Scierror( 311,"ERROR (qpOASES): Need to call qpOASES_init first!\n" ); + return 0; + } + + /* check dimensions */ + GetRhsVar( 1,"d", &g_rows,&g_cols,&g ); + if ( !( ( ( g_rows == qp_rowsH ) && ( g_cols == 1 ) ) || ( ( g_rows == 1 ) && ( g_cols == qp_rowsH ) ) ) ) + { + Scierror( 312,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 2,"d", &lb_rows,&lb_cols,&lb ); + if ( !( ( ( lb_rows == qp_rowsH ) && ( lb_cols == 1 ) ) || ( ( lb_rows == 0 ) && ( lb_cols == 0 ) ) ) ) + { + Scierror( 313,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 3,"d", &ub_rows,&ub_cols,&ub ); + if ( !( ( ( ub_rows == qp_rowsH ) && ( ub_cols == 1 ) ) || ( ( ub_rows == 0 ) && ( ub_cols == 0 ) ) ) ) + { + Scierror( 314,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 4,"d", &lbA_rows,&lbA_cols,&lbA ); + if ( !( ( ( lbA_rows == qp_rowsA ) && ( lbA_cols == 1 ) ) || ( ( lbA_rows == 0 ) && ( lbA_cols == 0 ) ) ) ) + { + Scierror( 315,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 5,"d", &ubA_rows,&ubA_cols,&ubA ); + if ( !( ( ( ubA_rows == qp_rowsA ) && ( ubA_cols == 1 ) ) || ( ( ubA_rows == 0 ) && ( ubA_cols == 0 ) ) ) ) + { + Scierror( 316,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 6,"i", &nWSR_rows,&nWSR_cols,&nWSR ); + if ( ( nWSR_rows != nWSR_cols ) || ( nWSR_cols != 1 ) ) + { + Scierror( 317,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + + y_size = qp_rowsH + qp_rowsA; + + CreateVar( 7,"d", &qp_rowsH,&one,&x ); + CreateVar( 8,"d", &one,&one,&obj ); + CreateVar( 9,"i", &one,&one,&status ); + CreateVar( 10,"i", &one,&one,&nWSRout ); + CreateVar( 11,"d", &y_size,&one,&y ); + + + /* call interfaced qpOASES routines with appropriate arguments */ + sci_QProblem_hotstart( stk(g), (lb_rows!=0) ? stk(lb) : 0, (ub_rows!=0) ? stk(ub) : 0, (lbA_rows!=0) ? stk(lbA) : 0, (ubA_rows!=0) ? stk(ubA) : 0, + istk(nWSR), + stk(x),stk(obj),istk(status),istk(nWSRout),stk(y) + ); + + LhsVar(1) = 7; + LhsVar(2) = 8; + LhsVar(3) = 9; + LhsVar(4) = 10; + LhsVar(5) = 11; + + return 0; +} + + +/* + * i n t e r f a c e _ Q P r o b l e m B _ h o t s t a r t + */ +int interface_QProblemB_hotstart( char* fname ) +{ + int_t g, g_rows, g_cols; + int_t lb, lb_rows, lb_cols; + int_t ub, ub_rows, ub_cols; + int_t nWSR, nWSR_rows, nWSR_cols; + + int_t x, obj, status, nWSRout, y; + + + int minlhs = 1, maxlhs = 5, minrhs = 4, maxrhs = 4, one = 1; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + + if ( qpb_rowsH == -1 ) + { + Scierror( 321,"ERROR (qpOASES): Need to call qpOASES_initSB first!\n" ); + return 0; + } + + /* check dimensions */ + GetRhsVar( 1,"d", &g_rows,&g_cols,&g ); + if ( !( ( ( g_rows == qpb_rowsH ) && ( g_cols == 1 ) ) || ( ( g_rows == 1 ) && ( g_cols == qpb_rowsH ) ) ) ) + { + Scierror( 322,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 2,"d", &lb_rows,&lb_cols,&lb ); + if ( !( ( ( lb_rows == qpb_rowsH ) && ( lb_cols == 1 ) ) || ( ( lb_rows == 0 ) && ( lb_cols == 0 ) ) ) ) + { + Scierror( 323,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 3,"d", &ub_rows,&ub_cols,&ub ); + if ( !( ( ( ub_rows == qpb_rowsH ) && ( ub_cols == 1 ) ) || ( ( ub_rows == 0 ) && ( ub_cols == 0 ) ) ) ) + { + Scierror( 324,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 4,"i", &nWSR_rows,&nWSR_cols,&nWSR ); + if ( ( nWSR_rows != nWSR_cols ) || ( nWSR_cols != 1 ) ) + { + Scierror( 325,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + + CreateVar( 5,"d", &qpb_rowsH,&one,&x ); + CreateVar( 6,"d", &one,&one,&obj ); + CreateVar( 7,"i", &one,&one,&status ); + CreateVar( 8,"i", &one,&one,&nWSRout ); + CreateVar( 9,"d", &qpb_rowsH,&one,&y ); + + + /* call interfaced qpOASES routines with appropriate arguments */ + sci_QProblemB_hotstart( stk(g), (lb_rows!=0) ? stk(lb) : 0, (ub_rows!=0) ? stk(ub) : 0, + istk(nWSR), + stk(x),stk(obj),istk(status),istk(nWSRout),stk(y) + ); + + LhsVar(1) = 5; + LhsVar(2) = 6; + LhsVar(3) = 7; + LhsVar(4) = 8; + LhsVar(5) = 9; + + return 0; +} + + +/* + * i n t e r f a c e _ S Q P r o b l e m _ h o t s t a r t + */ +int interface_SQProblem_hotstart( char* fname ) +{ + int_t H, H_rows, H_cols; + int_t g, g_rows, g_cols; + int_t A, A_rows, A_cols; + int_t lb, lb_rows, lb_cols; + int_t ub, ub_rows, ub_cols; + int_t lbA, lbA_rows, lbA_cols; + int_t ubA, ubA_rows, ubA_cols; + int_t nWSR, nWSR_rows, nWSR_cols; + + int_t obj, x, y, status, nWSRout; + + + int minlhs = 1, maxlhs = 5, minrhs = 8, maxrhs = 8, one = 1, y_size; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + + if ( ( sqp_rowsH == -1 ) || ( sqp_rowsA == -1 ) ) + { + Scierror( 331,"ERROR (qpOASES): Need to call qpOASES_initVM first!\n" ); + return 0; + } + + /* check dimensions */ + GetRhsVar( 1,"d", &H_rows,&H_cols,&H ); + if ( ( H_rows != H_cols ) || ( H_rows < 1 ) ) + { + Scierror( 332,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 2,"d", &g_rows,&g_cols,&g ); + if ( !( ( ( g_rows == H_rows ) && ( g_cols == 1 ) ) || ( ( g_rows == 1 ) && ( g_cols == H_rows ) ) ) ) + { + Scierror( 333,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 3,"d", &A_rows,&A_cols,&A ); + if ( ( A_cols != H_rows ) || ( A_rows < 1 ) ) + { + Scierror( 334,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 4,"d", &lb_rows,&lb_cols,&lb); + if ( !( ( ( lb_rows == H_rows ) && ( lb_cols == 1 ) ) || ( ( lb_rows == 0 ) && ( lb_cols == 0 ) ) ) ) + { + Scierror( 335,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 5,"d", &ub_rows,&ub_cols,&ub); + if ( !( ( ( ub_rows == H_rows ) && ( ub_cols == 1 ) ) || ( ( ub_rows == 0 ) && ( ub_cols == 0 ) ) ) ) + { + Scierror( 399,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 6,"d", &lbA_rows,&lbA_cols,&lbA); + if ( !( ( ( lbA_rows == A_rows ) && ( lbA_cols == 1 ) ) || ( ( lbA_rows == 0 ) && ( lbA_cols == 0 ) ) ) ) + { + Scierror( 336,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 7,"d", &ubA_rows,&ubA_cols,&ubA); + if ( !( ( ( ubA_rows == A_rows ) && ( ubA_cols == 1 ) ) || ( ( ubA_rows == 0 ) && ( ubA_cols == 0 ) ) ) ) + { + Scierror( 337,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + GetRhsVar( 8,"i", &nWSR_rows,&nWSR_cols,&nWSR); + if ( ( nWSR_rows != nWSR_cols ) || ( nWSR_cols != 1 ) ) + { + Scierror( 338,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + /* have matrices same dimension as last QP? */ + if ( ( sqp_rowsH != H_rows ) || ( sqp_rowsA != A_rows ) ) + { + Scierror( 339,"ERROR (qpOASES): Dimension mismatch!\n" ); + return 0; + } + + + y_size = H_rows + A_rows; + + CreateVar( 9,"d", &H_rows,&one,&x ); + CreateVar( 10,"d", &one,&one,&obj ); + CreateVar( 11,"i", &one,&one,&status ); + CreateVar( 12,"i", &one,&one,&nWSRout ); + CreateVar( 13,"d", &y_size,&one,&y ); + + + /* call interfaced qpOASES routines with appropriate arguments */ + sci_SQProblem_hotstart( stk(H),stk(g),stk(A), (lb_rows!=0) ? stk(lb) : 0, (ub_rows!=0) ? stk(ub) : 0, (lbA_rows!=0) ? stk(lbA) : 0, (ubA_rows!=0) ? stk(ubA) : 0, + istk(nWSR), + stk(x),stk(obj),istk(status),istk(nWSRout),stk(y) + ); + + LhsVar(1) = 9; + LhsVar(2) = 10; + LhsVar(3) = 11; + LhsVar(4) = 12; + LhsVar(5) = 13; + + return 0; +} + + +/* + * i n t e r f a c e _ Q P r o b l e m _ c l e a n u p + */ +int interface_QProblem_cleanup( char* fname ) +{ + const int minlhs = 0, maxlhs = 1, minrhs = 0, maxrhs = 0; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + sci_QProblem_cleanup( ); + qp_rowsH = -1; + qp_rowsA = -1; + + return 0; +} + + +/* + * i n t e r f a c e _ Q P r o b l e m B _ c l e a n u p + */ +int interface_QProblemB_cleanup( char* fname ) +{ + const int minlhs = 0, maxlhs = 1, minrhs = 0, maxrhs = 0; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + sci_QProblemB_cleanup( ); + qpb_rowsH = -1; + + return 0; +} + + +/* + * i n t e r f a c e _ S Q P r o b l e m _ c l e a n u p + */ +int interface_SQProblem_cleanup( char* fname ) +{ + const int minlhs = 0, maxlhs = 1, minrhs = 0, maxrhs = 0; + + CheckRhs( minrhs,maxrhs ); + CheckLhs( minlhs,maxlhs ); + + sci_SQProblem_cleanup( ); + sqp_rowsH = -1; + sqp_rowsA = -1; + + return 0; +} + + +/* + * q p O A S E S g a t e w a y + */ +int C2F(qpOASESgateway)( ) +{ + gate_function function[] = { interface_qpOASES, + interface_QProblem_init, interface_QProblemB_init, interface_SQProblem_init, + interface_QProblem_hotstart, interface_QProblemB_hotstart, interface_SQProblem_hotstart, + interface_QProblem_cleanup, interface_QProblemB_cleanup, interface_SQProblem_cleanup + }; + char* name[] = { "qpOASES", + "qpOASES_init", "qpOASES_initSB", "qpOASES_initVM", + "qpOASES_hotstart", "qpOASES_hotstartSB", "qpOASES_hotstartVM", + "qpOASES_cleanup", "qpOASES_cleanupSB", "qpOASES_cleanupVM" + }; + + Rhs = Max( 0,Rhs ); + sci_gateway( name[Fin-1],function[Fin-1] ); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESinterface.sce b/locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESinterface.sce new file mode 100644 index 0000000..77907ab --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESinterface.sce @@ -0,0 +1,41 @@ +// +// This file is part of qpOASES. +// +// qpOASES -- An Implementation of the Online Active Set Strategy. +// Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +// Christian Kirches et al. All rights reserved. +// +// qpOASES is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// qpOASES is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with qpOASES; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + + + +// +// Filename: interfaces/scilab/qpOASESinterface.sci +// Author: Holger Diedam, Hans Joachim Ferreau +// Version: 3.2 +// Date: 2007-2017 +// + + + +sharedlib = link( './libqpOASESinterface.so' ); +addinter( './libqpOASESinterface.so', 'qpOASESgateway', ["qpOASES", "qpOASES_init","qpOASES_initSB","qpOASES_initVM", "qpOASES_hotstart","qpOASES_hotstartSB","qpOASES_hotstartVM", "qpOASES_cleanup","qpOASES_cleanupSB","qpOASES_cleanupVM"] ); + + + +// +// end of file +// diff --git a/locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESroutines.cpp b/locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESroutines.cpp new file mode 100644 index 0000000..472a57f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/scilab/qpOASESroutines.cpp @@ -0,0 +1,369 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/scilab/qpOASESroutines.cpp + * \author Holger Diedam, Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Interface that enables to call qpOASES from scilab + * (C++ file to provide an interface between the files that + * have to be compiled with gcc and the qpOASES library). + * + */ + + +#include + +#include + + +USING_NAMESPACE_QPOASES + +/*extern "C" { +#include "../c/qpOASES_wrapper.h" +}*/ + + +/* global pointers to qpOASES objects */ +static QProblem* qp = 0; +static QProblemB* qpb = 0; +static SQProblem* sqp = 0; + + +extern "C" +{ + void sci_qpOASES( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t *nV, int_t* nC, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + + void sci_QProblem_init( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nV, int_t* nC, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + void sci_QProblemB_init( real_t* H, real_t* g, real_t* lb, real_t* ub, + int_t* nV, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + void sci_SQProblem_init( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nV, int_t* nC, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + + void sci_QProblem_hotstart( real_t* g, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + void sci_QProblemB_hotstart( real_t* g, real_t* lb, real_t* ub, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + void sci_SQProblem_hotstart( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ); + + void sci_QProblem_cleanup( ); + void sci_QProblemB_cleanup( ); + void sci_SQProblem_cleanup( ); +} /* extern "C" */ + + + +/* + * t r a n s f o r m A + */ +void transformA( real_t* A, int_t nV, int_t nC ) +{ + int_t i, j; + + real_t* A_tmp = new real_t[nC*nV]; + + for( i=0; isetPrintLevel( PL_LOW ); + returnValue returnvalue = qp->init( H,g,A,lb,ub,lbA,ubA, *nWSR,0 ); + + /* assign lhs arguments */ + qp->getPrimalSolution( x ); + *obj = qp->getObjVal( ); + *status = getSimpleStatus( returnvalue ); + *nWSRout = *nWSR; + qp->getDualSolution( y ); + + return; +} + + +/* + * Q P r o b l e m B _ i n i t + */ +void sci_QProblemB_init( real_t* H, real_t* g, real_t* lb, real_t* ub, + int_t* nV, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ) +{ + sci_QProblemB_cleanup( ); + + /* setup and solve initial QP */ + qpb = new QProblemB( *nV ); + qpb->setPrintLevel( PL_LOW ); + returnValue returnvalue = qpb->init( H,g,lb,ub, *nWSR,0 ); + + /* assign lhs arguments */ + qpb->getPrimalSolution( x ); + *obj = qpb->getObjVal( ); + *status = getSimpleStatus( returnvalue ); + *nWSRout = *nWSR; + qpb->getDualSolution( y ); + + return; +} + + +/* + * S Q P r o b l e m _ i n i t + */ +void sci_SQProblem_init( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nV, int_t* nC, int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ) +{ + sci_SQProblem_cleanup( ); + + /* transform A into C style matrix */ + transformA( A, *nV,*nC ); + + /* setup and solve initial QP */ + sqp = new SQProblem( *nV,*nC ); + sqp->setPrintLevel( PL_LOW ); + returnValue returnvalue = sqp->init( H,g,A,lb,ub,lbA,ubA, *nWSR,0 ); + + /* assign lhs arguments */ + sqp->getPrimalSolution( x ); + *obj = sqp->getObjVal( ); + *status = getSimpleStatus( returnvalue ); + *nWSRout = *nWSR; + sqp->getDualSolution( y ); + + return; +} + + +/* + * Q P r o b l e m _ h o t s t a r t + */ +void sci_QProblem_hotstart( real_t* g, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ) +{ + /* has QP been initialised? */ + if ( qp == 0 ) + { + *status = -1; + Scierror( 999,"ERROR (qpOASES): Need to call qpOASES_init first!\n" ); + return; + } + + /* solve QP */ + returnValue returnvalue = qp->hotstart( g,lb,ub,lbA,ubA, *nWSR,0 ); + + /* assign lhs arguments */ + qp->getPrimalSolution( x ); + *obj = qp->getObjVal( ); + *status = getSimpleStatus( returnvalue ); + *nWSRout = *nWSR; + qp->getDualSolution( y ); + + return; +} + + +/* + * Q P r o b l e m B _ h o t s t a r t + */ +void sci_QProblemB_hotstart( real_t* g, real_t* lb, real_t* ub, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ) +{ + /* has QP been initialised? */ + if ( qpb == 0 ) + { + *status = -1; + Scierror( 999,"ERROR (qpOASES): Need to call qpOASES_initSB first!\n" ); + return; + } + + /* solve QP */ + returnValue returnvalue = qpb->hotstart( g,lb,ub, *nWSR,0 ); + + /* assign lhs arguments */ + qpb->getPrimalSolution( x ); + *obj = qpb->getObjVal( ); + *status = getSimpleStatus( returnvalue ); + *nWSRout = *nWSR; + qpb->getDualSolution( y ); + + return; +} + + +/* + * S Q P r o b l e m _ h o t s t a r t + */ +void sci_SQProblem_hotstart( real_t* H, real_t* g, real_t* A, real_t* lb, real_t* ub, real_t* lbA, real_t* ubA, + int_t* nWSR, + real_t* x, real_t* obj, int_t* status, int_t* nWSRout, real_t* y + ) +{ + /* has QP been initialised? */ + if ( sqp == 0 ) + { + *status = -1; + Scierror( 999,"ERROR (qpOASES): Need to call qpOASES_initVM first!\n" ); + return; + } + + /* transform A into C style matrix */ + transformA( A, sqp->getNV( ),sqp->getNC( ) ); + + /* solve QP */ + returnValue returnvalue = sqp->hotstart( H,g,A,lb,ub,lbA,ubA, *nWSR,0 ); + + /* assign lhs arguments */ + sqp->getPrimalSolution( x ); + *obj = sqp->getObjVal( ); + *status = getSimpleStatus( returnvalue ); + *nWSRout = *nWSR; + sqp->getDualSolution( y ); + + return; +} + + +/* + * Q P r o b l e m _ c l e a n u p + */ +void sci_QProblem_cleanup( ) +{ + if ( qp != 0 ) + { + delete qp; + qp = 0; + } + + return; +} + + +/* + * Q P r o b l e m B _ c l e a n u p + */ +void sci_QProblemB_cleanup( ) +{ + if ( qpb != 0 ) + { + delete qpb; + qpb = 0; + } + + return; +} + + +/* + * S Q P r o b l e m _ c l e a n u p + */ +void sci_SQProblem_cleanup( ) +{ + if ( sqp != 0 ) + { + delete sqp; + sqp = 0; + } + + return; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/example_QProblem.mdl b/locomotion/src/third_party/qpOASES/interfaces/simulink/example_QProblem.mdl new file mode 100644 index 0000000..0e7d0be --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/example_QProblem.mdl @@ -0,0 +1,762 @@ +Model { + Name "example_QProblem" + Version 7.4 + MdlSubVersion 0 + GraphicalInterface { + NumRootInports 0 + NumRootOutports 0 + ParameterArgumentNames "" + ComputedModelVersion "1.69" + NumModelReferences 0 + NumTestPointedSignals 0 + } + SavedCharacterEncoding "UTF-8" + SaveDefaultBlockParams on + ScopeRefreshTime 0.035000 + OverrideScopeRefreshTime on + DisableAllScopes off + DataTypeOverride "UseLocalSettings" + MinMaxOverflowLogging "UseLocalSettings" + MinMaxOverflowArchiveMode "Overwrite" + MaxMDLFileLineLength 120 + Created "Fri Apr 13 11:08:51 2007" + Creator "jferreau" + UpdateHistory "UpdateHistoryNever" + ModifiedByFormat "%" + LastModifiedBy "chjofer2" + ModifiedDateFormat "%" + LastModifiedDate "Tue Jan 06 16:16:07 2015" + RTWModifiedTimeStamp 342461745 + ModelVersionFormat "1.%" + ConfigurationManager "None" + SampleTimeColors off + SampleTimeAnnotations off + LibraryLinkDisplay "none" + WideLines off + ShowLineDimensions off + ShowPortDataTypes off + ShowLoopsOnError on + IgnoreBidirectionalLines off + ShowStorageClass off + ShowTestPointIcons on + ShowSignalResolutionIcons on + ShowViewerIcons on + SortedOrder off + ExecutionContextIcon off + ShowLinearizationAnnotations on + BlockNameDataTip off + BlockParametersDataTip off + BlockDescriptionStringDataTip off + ToolBar on + StatusBar on + BrowserShowLibraryLinks off + BrowserLookUnderMasks off + SimulationMode "normal" + LinearizationMsg "none" + Profile off + ParamWorkspaceSource "MATLABWorkspace" + AccelSystemTargetFile "accel.tlc" + AccelTemplateMakefile "accel_default_tmf" + AccelMakeCommand "make_rtw" + TryForcingSFcnDF off + RecordCoverage off + CovPath "/" + CovSaveName "covdata" + CovMetricSettings "dw" + CovNameIncrementing off + CovHtmlReporting on + CovForceBlockReductionOff on + covSaveCumulativeToWorkspaceVar on + CovSaveSingleToWorkspaceVar on + CovCumulativeVarName "covCumulativeData" + CovCumulativeReport off + CovReportOnPause on + CovModelRefEnable "Off" + CovExternalEMLEnable off + ExtModeBatchMode off + ExtModeEnableFloating on + ExtModeTrigType "manual" + ExtModeTrigMode "normal" + ExtModeTrigPort "1" + ExtModeTrigElement "any" + ExtModeTrigDuration 1000 + ExtModeTrigDurationFloating "auto" + ExtModeTrigHoldOff 0 + ExtModeTrigDelay 0 + ExtModeTrigDirection "rising" + ExtModeTrigLevel 0 + ExtModeArchiveMode "off" + ExtModeAutoIncOneShot off + ExtModeIncDirWhenArm off + ExtModeAddSuffixToVar off + ExtModeWriteAllDataToWs off + ExtModeArmWhenConnect on + ExtModeSkipDownloadWhenConnect off + ExtModeLogAll on + ExtModeAutoUpdateStatusClock off + BufferReuse on + ShowModelReferenceBlockVersion off + ShowModelReferenceBlockIO off + Array { + Type "Handle" + Dimension 1 + Simulink.ConfigSet { + $ObjectID 1 + Version "1.6.0" + Array { + Type "Handle" + Dimension 8 + Simulink.SolverCC { + $ObjectID 2 + Version "1.6.0" + StartTime "0.0" + StopTime "0.5" + AbsTol "auto" + FixedStep "auto" + InitialStep "auto" + MaxNumMinSteps "-1" + MaxOrder 5 + ZcThreshold "auto" + ConsecutiveZCsStepRelTol "10*128*eps" + MaxConsecutiveZCs "1000" + ExtrapolationOrder 4 + NumberNewtonIterations 1 + MaxStep "auto" + MinStep "auto" + MaxConsecutiveMinStep "1" + RelTol "1e-3" + SolverMode "Auto" + Solver "FixedStepDiscrete" + SolverName "FixedStepDiscrete" + ShapePreserveControl "DisableAll" + ZeroCrossControl "UseLocalSettings" + ZeroCrossAlgorithm "Nonadaptive" + AlgebraicLoopSolver "TrustRegion" + SolverResetMethod "Fast" + PositivePriorityOrder off + AutoInsertRateTranBlk off + SampleTimeConstraint "Unconstrained" + InsertRTBMode "Whenever possible" + } + Simulink.DataIOCC { + $ObjectID 3 + Version "1.6.0" + Decimation "1" + ExternalInput "[t, u]" + FinalStateName "xFinal" + InitialState "xInitial" + LimitDataPoints on + MaxDataPoints "1000" + LoadExternalInput off + LoadInitialState off + SaveFinalState off + SaveCompleteFinalSimState off + SaveFormat "Array" + SaveOutput on + SaveState off + SignalLogging on + InspectSignalLogs off + SaveTime on + ReturnWorkspaceOutputs off + StateSaveName "xout" + TimeSaveName "tout" + OutputSaveName "yout" + SignalLoggingName "logsout" + OutputOption "RefineOutputTimes" + OutputTimes "[]" + ReturnWorkspaceOutputsName "out" + Refine "1" + } + Simulink.OptimizationCC { + $ObjectID 4 + Version "1.6.0" + Array { + Type "Cell" + Dimension 4 + Cell "ZeroExternalMemoryAtStartup" + Cell "ZeroInternalMemoryAtStartup" + Cell "NoFixptDivByZeroProtection" + Cell "OptimizeModelRefInitCode" + PropName "DisabledProps" + } + BlockReduction on + BooleanDataType on + ConditionallyExecuteInputs on + InlineParams off + UseIntDivNetSlope off + InlineInvariantSignals off + OptimizeBlockIOStorage on + BufferReuse on + EnhancedBackFolding off + StrengthReduction off + EnforceIntegerDowncast on + ExpressionFolding on + BooleansAsBitfields off + EnableMemcpy on + MemcpyThreshold 64 + PassReuseOutputArgsAs "Structure reference" + ExpressionDepthLimit 2147483647 + FoldNonRolledExpr on + LocalBlockOutputs on + RollThreshold 5 + SystemCodeInlineAuto off + StateBitsets off + DataBitsets off + UseTempVars off + ZeroExternalMemoryAtStartup on + ZeroInternalMemoryAtStartup on + InitFltsAndDblsToZero on + NoFixptDivByZeroProtection off + EfficientFloat2IntCast off + EfficientMapNaN2IntZero on + OptimizeModelRefInitCode off + LifeSpan "inf" + BufferReusableBoundary on + SimCompilerOptimization "Off" + AccelVerboseBuild off + } + Simulink.DebuggingCC { + $ObjectID 5 + Version "1.6.0" + RTPrefix "error" + ConsistencyChecking "none" + ArrayBoundsChecking "none" + SignalInfNanChecking "none" + SignalRangeChecking "none" + ReadBeforeWriteMsg "UseLocalSettings" + WriteAfterWriteMsg "UseLocalSettings" + WriteAfterReadMsg "UseLocalSettings" + AlgebraicLoopMsg "warning" + ArtificialAlgebraicLoopMsg "warning" + SaveWithDisabledLinksMsg "warning" + SaveWithParameterizedLinksMsg "none" + CheckSSInitialOutputMsg on + UnderspecifiedInitializationDetection "Classic" + MergeDetectMultiDrivingBlocksExec "none" + CheckExecutionContextPreStartOutputMsg off + CheckExecutionContextRuntimeOutputMsg off + SignalResolutionControl "TryResolveAllWithWarning" + BlockPriorityViolationMsg "warning" + MinStepSizeMsg "warning" + TimeAdjustmentMsg "none" + MaxConsecutiveZCsMsg "error" + SolverPrmCheckMsg "warning" + InheritedTsInSrcMsg "warning" + DiscreteInheritContinuousMsg "warning" + MultiTaskDSMMsg "error" + MultiTaskCondExecSysMsg "error" + MultiTaskRateTransMsg "error" + SingleTaskRateTransMsg "none" + TasksWithSamePriorityMsg "warning" + SigSpecEnsureSampleTimeMsg "warning" + CheckMatrixSingularityMsg "none" + IntegerOverflowMsg "warning" + Int32ToFloatConvMsg "warning" + ParameterDowncastMsg "error" + ParameterOverflowMsg "error" + ParameterUnderflowMsg "none" + ParameterPrecisionLossMsg "warning" + ParameterTunabilityLossMsg "warning" + FixptConstUnderflowMsg "none" + FixptConstOverflowMsg "none" + FixptConstPrecisionLossMsg "none" + UnderSpecifiedDataTypeMsg "none" + UnnecessaryDatatypeConvMsg "none" + VectorMatrixConversionMsg "none" + InvalidFcnCallConnMsg "error" + FcnCallInpInsideContextMsg "Use local settings" + SignalLabelMismatchMsg "none" + UnconnectedInputMsg "warning" + UnconnectedOutputMsg "warning" + UnconnectedLineMsg "warning" + SFcnCompatibilityMsg "none" + UniqueDataStoreMsg "none" + BusObjectLabelMismatch "warning" + RootOutportRequireBusObject "warning" + AssertControl "UseLocalSettings" + EnableOverflowDetection off + ModelReferenceIOMsg "none" + ModelReferenceVersionMismatchMessage "none" + ModelReferenceIOMismatchMessage "none" + ModelReferenceCSMismatchMessage "none" + UnknownTsInhSupMsg "warning" + ModelReferenceDataLoggingMessage "warning" + ModelReferenceSymbolNameMessage "warning" + ModelReferenceExtraNoncontSigs "error" + StateNameClashWarn "warning" + SimStateInterfaceChecksumMismatchMsg "warning" + StrictBusMsg "Warning" + LoggingUnavailableSignals "error" + BlockIODiagnostic "none" + } + Simulink.HardwareCC { + $ObjectID 6 + Version "1.6.0" + ProdBitPerChar 8 + ProdBitPerShort 16 + ProdBitPerInt 32 + ProdBitPerLong 32 + ProdIntDivRoundTo "Undefined" + ProdEndianess "Unspecified" + ProdWordSize 32 + ProdShiftRightIntArith on + ProdHWDeviceType "32-bit Generic" + TargetBitPerChar 8 + TargetBitPerShort 16 + TargetBitPerInt 32 + TargetBitPerLong 32 + TargetShiftRightIntArith on + TargetIntDivRoundTo "Undefined" + TargetEndianess "Unspecified" + TargetWordSize 32 + TargetTypeEmulationWarnSuppressLevel 0 + TargetPreprocMaxBitsSint 32 + TargetPreprocMaxBitsUint 32 + TargetHWDeviceType "Specified" + TargetUnknown off + ProdEqTarget on + } + Simulink.ModelReferenceCC { + $ObjectID 7 + Version "1.6.0" + UpdateModelReferenceTargets "IfOutOfDateOrStructuralChange" + CheckModelReferenceTargetMessage "error" + ModelReferenceNumInstancesAllowed "Multi" + ModelReferencePassRootInputsByReference on + ModelReferenceMinAlgLoopOccurrences off + } + Simulink.SFSimCC { + $ObjectID 8 + Version "1.6.0" + SFSimEnableDebug on + SFSimOverflowDetection on + SFSimEcho on + SimBlas on + SimCtrlC on + SimExtrinsic on + SimIntegrity on + SimUseLocalCustomCode off + SimBuildMode "sf_incremental_build" + } + Simulink.RTWCC { + $BackupClass "Simulink.RTWCC" + $ObjectID 9 + Version "1.6.0" + Array { + Type "Cell" + Dimension 1 + Cell "IncludeHyperlinkInReport" + PropName "DisabledProps" + } + SystemTargetFile "grt.tlc" + GenCodeOnly off + MakeCommand "make_rtw" + GenerateMakefile on + TemplateMakefile "grt_default_tmf" + GenerateReport off + SaveLog off + RTWVerbose on + RetainRTWFile off + ProfileTLC off + TLCDebug off + TLCCoverage off + TLCAssert off + ProcessScriptMode "Default" + ConfigurationMode "Optimized" + ConfigAtBuild off + RTWUseLocalCustomCode off + RTWUseSimCustomCode off + IncludeHyperlinkInReport off + LaunchReport off + TargetLang "C" + IncludeBusHierarchyInRTWFileBlockHierarchyMap off + IncludeERTFirstTime off + GenerateTraceInfo off + GenerateTraceReport off + GenerateTraceReportSl off + GenerateTraceReportSf off + GenerateTraceReportEml off + GenerateCodeInfo off + RTWCompilerOptimization "Off" + CheckMdlBeforeBuild "Off" + Array { + Type "Handle" + Dimension 2 + Simulink.CodeAppCC { + $ObjectID 10 + Version "1.6.0" + Array { + Type "Cell" + Dimension 16 + Cell "IgnoreCustomStorageClasses" + Cell "InsertBlockDesc" + Cell "SFDataObjDesc" + Cell "SimulinkDataObjDesc" + Cell "DefineNamingRule" + Cell "SignalNamingRule" + Cell "ParamNamingRule" + Cell "InlinedPrmAccess" + Cell "CustomSymbolStr" + Cell "CustomSymbolStrGlobalVar" + Cell "CustomSymbolStrType" + Cell "CustomSymbolStrField" + Cell "CustomSymbolStrFcn" + Cell "CustomSymbolStrBlkIO" + Cell "CustomSymbolStrTmpVar" + Cell "CustomSymbolStrMacro" + PropName "DisabledProps" + } + ForceParamTrailComments off + GenerateComments on + IgnoreCustomStorageClasses on + IgnoreTestpoints off + IncHierarchyInIds off + MaxIdLength 31 + PreserveName off + PreserveNameWithParent off + ShowEliminatedStatement off + IncAutoGenComments off + SimulinkDataObjDesc off + SFDataObjDesc off + IncDataTypeInIds off + MangleLength 1 + CustomSymbolStrGlobalVar "$R$N$M" + CustomSymbolStrType "$N$R$M" + CustomSymbolStrField "$N$M" + CustomSymbolStrFcn "$R$N$M$F" + CustomSymbolStrFcnArg "rt$I$N$M" + CustomSymbolStrBlkIO "rtb_$N$M" + CustomSymbolStrTmpVar "$N$M" + CustomSymbolStrMacro "$R$N$M" + DefineNamingRule "None" + ParamNamingRule "None" + SignalNamingRule "None" + InsertBlockDesc off + SimulinkBlockComments on + EnableCustomComments off + InlinedPrmAccess "Literals" + ReqsInCode off + UseSimReservedNames off + } + Simulink.GRTTargetCC { + $BackupClass "Simulink.TargetCC" + $ObjectID 11 + Version "1.6.0" + Array { + Type "Cell" + Dimension 13 + Cell "IncludeMdlTerminateFcn" + Cell "CombineOutputUpdateFcns" + Cell "SuppressErrorStatus" + Cell "ERTCustomFileBanners" + Cell "GenerateSampleERTMain" + Cell "GenerateTestInterfaces" + Cell "MultiInstanceERTCode" + Cell "PurelyIntegerCode" + Cell "SupportNonFinite" + Cell "SupportComplex" + Cell "SupportAbsoluteTime" + Cell "SupportContinuousTime" + Cell "SupportNonInlinedSFcns" + PropName "DisabledProps" + } + TargetFcnLib "ansi_tfl_tmw.mat" + TargetLibSuffix "" + TargetPreCompLibLocation "" + TargetFunctionLibrary "ANSI_C" + UtilityFuncGeneration "Auto" + ERTMultiwordTypeDef "System defined" + ERTMultiwordLength 256 + MultiwordLength 2048 + GenerateFullHeader on + GenerateSampleERTMain off + GenerateTestInterfaces off + IsPILTarget off + ModelReferenceCompliant on + ParMdlRefBuildCompliant on + CompOptLevelCompliant on + IncludeMdlTerminateFcn on + GeneratePreprocessorConditionals "Disable all" + CombineOutputUpdateFcns off + SuppressErrorStatus off + ERTFirstTimeCompliant off + IncludeFileDelimiter "Auto" + ERTCustomFileBanners off + SupportAbsoluteTime on + LogVarNameModifier "rt_" + MatFileLogging on + MultiInstanceERTCode off + SupportNonFinite on + SupportComplex on + PurelyIntegerCode off + SupportContinuousTime on + SupportNonInlinedSFcns on + SupportVariableSizeSignals off + EnableShiftOperators on + ParenthesesLevel "Nominal" + PortableWordSizes off + ModelStepFunctionPrototypeControlCompliant off + CPPClassGenCompliant off + AutosarCompliant off + UseMalloc off + ExtMode off + ExtModeStaticAlloc off + ExtModeTesting off + ExtModeStaticAllocSize 1000000 + ExtModeTransport 0 + ExtModeMexFile "ext_comm" + ExtModeIntrfLevel "Level1" + RTWCAPISignals off + RTWCAPIParams off + RTWCAPIStates off + GenerateASAP2 off + } + PropName "Components" + } + } + PropName "Components" + } + Name "Configuration" + CurrentDlgPage "Solver" + ConfigPrmDlgPosition " [ 200, 197, 1080, 827 ] " + } + PropName "ConfigurationSets" + } + Simulink.ConfigSet { + $PropName "ActiveConfigurationSet" + $ObjectID 1 + } + BlockDefaults { + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + NamePlacement "normal" + FontName "Courier" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + ShowName on + BlockRotation 0 + BlockMirror off + } + AnnotationDefaults { + HorizontalAlignment "center" + VerticalAlignment "middle" + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + FontName "Courier" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + UseDisplayTextAsClickCallback off + } + LineDefaults { + FontName "Courier" + FontSize 9 + FontWeight "normal" + FontAngle "normal" + } + BlockParameterDefaults { + Block { + BlockType FromWorkspace + VariableName "simulink_input" + SampleTime "-1" + Interpolate on + ZeroCross off + OutputAfterFinalValue "Extrapolation" + } + Block { + BlockType "S-Function" + FunctionName "system" + SFunctionModules "''" + PortCounts "[]" + SFunctionDeploymentMode off + } + Block { + BlockType Scope + ModelBased off + TickLabels "OneTimeTick" + ZoomMode "on" + Grid "on" + TimeRange "auto" + YMin "-5" + YMax "5" + SaveToWorkspace off + SaveName "ScopeData" + LimitDataPoints on + MaxDataPoints "5000" + Decimation "1" + SampleInput off + SampleTime "-1" + } + } + System { + Name "example_QProblem" + Location [2, 74, 1918, 1139] + Open on + ModelBrowserVisibility off + ModelBrowserWidth 200 + ScreenColor "white" + PaperOrientation "landscape" + PaperPositionMode "auto" + PaperType "usletter" + PaperUnits "inches" + TiledPaperMargins [0.500000, 0.500000, 0.500000, 0.500000] + TiledPageScale 1 + ShowPageBoundaries off + ZoomFactor "125" + ReportName "simulink-default.rpt" + SIDHighWatermark 9 + Block { + BlockType FromWorkspace + Name "g" + SID 2 + Position [200, 158, 265, 182] + VariableName "g" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "lb" + SID 4 + Position [200, 203, 265, 227] + VariableName "lb" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "lbA" + SID 6 + Position [200, 293, 265, 317] + VariableName "lbA" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType "S-Function" + Name "qpOASES" + SID 9 + Ports [5, 4] + Position [595, 222, 795, 298] + BackgroundColor "[1.000000, 0.915850, 0.439000]" + FunctionName "qpOASES_QProblem" + Parameters "H,A" + EnableBusSupport off + } + Block { + BlockType FromWorkspace + Name "ub" + SID 5 + Position [200, 248, 265, 272] + VariableName "ub" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "ubA" + SID 7 + Position [200, 338, 265, 362] + VariableName "ubA" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType Scope + Name "x,\nfval,\nexitflag,\niter" + SID 8 + Ports [4] + Position [945, 222, 1000, 298] + Floating off + Location [6, 78, 1276, 993] + Open off + NumInputPorts "4" + List { + ListType AxesTitles + axes1 "%" + axes2 "%" + axes3 "%" + axes4 "%" + } + YMin "-5~-5~-5~-5" + YMax "5~5~5~5" + SaveName "ScopeData1" + DataFormat "StructureWithTime" + SampleTime "0" + } + Line { + SrcBlock "qpOASES" + SrcPort 1 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 1 + } + Line { + SrcBlock "qpOASES" + SrcPort 2 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 2 + } + Line { + SrcBlock "qpOASES" + SrcPort 3 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 3 + } + Line { + SrcBlock "qpOASES" + SrcPort 4 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 4 + } + Line { + SrcBlock "ub" + SrcPort 1 + DstBlock "qpOASES" + DstPort 3 + } + Line { + SrcBlock "lb" + SrcPort 1 + Points [55, 0; 0, 30] + DstBlock "qpOASES" + DstPort 2 + } + Line { + SrcBlock "g" + SrcPort 1 + Points [80, 0; 0, 60] + DstBlock "qpOASES" + DstPort 1 + } + Line { + SrcBlock "lbA" + SrcPort 1 + Points [55, 0; 0, -30] + DstBlock "qpOASES" + DstPort 4 + } + Line { + SrcBlock "ubA" + SrcPort 1 + Points [80, 0; 0, -60] + DstBlock "qpOASES" + DstPort 5 + } + Annotation { + Position [335, 96] + } + Annotation { + Name "This file is part of qpOASES.\n\nqpOASES -- An Implementation of the Online Active Set Strategy.\nC" + "opyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, Christian Kirches et al.\nAll rights reserved." + Position [693, 128] + } + } +} diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/example_QProblemB.mdl b/locomotion/src/third_party/qpOASES/interfaces/simulink/example_QProblemB.mdl new file mode 100644 index 0000000..42b1df6 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/example_QProblemB.mdl @@ -0,0 +1,728 @@ +Model { + Name "example_QProblemB" + Version 7.4 + MdlSubVersion 0 + GraphicalInterface { + NumRootInports 0 + NumRootOutports 0 + ParameterArgumentNames "" + ComputedModelVersion "1.67" + NumModelReferences 0 + NumTestPointedSignals 0 + } + SavedCharacterEncoding "UTF-8" + SaveDefaultBlockParams on + ScopeRefreshTime 0.035000 + OverrideScopeRefreshTime on + DisableAllScopes off + DataTypeOverride "UseLocalSettings" + MinMaxOverflowLogging "UseLocalSettings" + MinMaxOverflowArchiveMode "Overwrite" + MaxMDLFileLineLength 120 + Created "Fri Apr 13 11:08:51 2007" + Creator "jferreau" + UpdateHistory "UpdateHistoryNever" + ModifiedByFormat "%" + LastModifiedBy "chjofer2" + ModifiedDateFormat "%" + LastModifiedDate "Tue Jan 06 16:15:23 2015" + RTWModifiedTimeStamp 342461721 + ModelVersionFormat "1.%" + ConfigurationManager "None" + SampleTimeColors off + SampleTimeAnnotations off + LibraryLinkDisplay "none" + WideLines off + ShowLineDimensions off + ShowPortDataTypes off + ShowLoopsOnError on + IgnoreBidirectionalLines off + ShowStorageClass off + ShowTestPointIcons on + ShowSignalResolutionIcons on + ShowViewerIcons on + SortedOrder off + ExecutionContextIcon off + ShowLinearizationAnnotations on + BlockNameDataTip off + BlockParametersDataTip off + BlockDescriptionStringDataTip off + ToolBar on + StatusBar on + BrowserShowLibraryLinks off + BrowserLookUnderMasks off + SimulationMode "normal" + LinearizationMsg "none" + Profile off + ParamWorkspaceSource "MATLABWorkspace" + AccelSystemTargetFile "accel.tlc" + AccelTemplateMakefile "accel_default_tmf" + AccelMakeCommand "make_rtw" + TryForcingSFcnDF off + RecordCoverage off + CovPath "/" + CovSaveName "covdata" + CovMetricSettings "dw" + CovNameIncrementing off + CovHtmlReporting on + CovForceBlockReductionOff on + covSaveCumulativeToWorkspaceVar on + CovSaveSingleToWorkspaceVar on + CovCumulativeVarName "covCumulativeData" + CovCumulativeReport off + CovReportOnPause on + CovModelRefEnable "Off" + CovExternalEMLEnable off + ExtModeBatchMode off + ExtModeEnableFloating on + ExtModeTrigType "manual" + ExtModeTrigMode "normal" + ExtModeTrigPort "1" + ExtModeTrigElement "any" + ExtModeTrigDuration 1000 + ExtModeTrigDurationFloating "auto" + ExtModeTrigHoldOff 0 + ExtModeTrigDelay 0 + ExtModeTrigDirection "rising" + ExtModeTrigLevel 0 + ExtModeArchiveMode "off" + ExtModeAutoIncOneShot off + ExtModeIncDirWhenArm off + ExtModeAddSuffixToVar off + ExtModeWriteAllDataToWs off + ExtModeArmWhenConnect on + ExtModeSkipDownloadWhenConnect off + ExtModeLogAll on + ExtModeAutoUpdateStatusClock off + BufferReuse on + ShowModelReferenceBlockVersion off + ShowModelReferenceBlockIO off + Array { + Type "Handle" + Dimension 1 + Simulink.ConfigSet { + $ObjectID 1 + Version "1.6.0" + Array { + Type "Handle" + Dimension 8 + Simulink.SolverCC { + $ObjectID 2 + Version "1.6.0" + StartTime "0.0" + StopTime "0.5" + AbsTol "auto" + FixedStep "auto" + InitialStep "auto" + MaxNumMinSteps "-1" + MaxOrder 5 + ZcThreshold "auto" + ConsecutiveZCsStepRelTol "10*128*eps" + MaxConsecutiveZCs "1000" + ExtrapolationOrder 4 + NumberNewtonIterations 1 + MaxStep "auto" + MinStep "auto" + MaxConsecutiveMinStep "1" + RelTol "1e-3" + SolverMode "Auto" + Solver "VariableStepDiscrete" + SolverName "VariableStepDiscrete" + ShapePreserveControl "DisableAll" + ZeroCrossControl "UseLocalSettings" + ZeroCrossAlgorithm "Nonadaptive" + AlgebraicLoopSolver "TrustRegion" + SolverResetMethod "Fast" + PositivePriorityOrder off + AutoInsertRateTranBlk off + SampleTimeConstraint "Unconstrained" + InsertRTBMode "Whenever possible" + } + Simulink.DataIOCC { + $ObjectID 3 + Version "1.6.0" + Decimation "1" + ExternalInput "[t, u]" + FinalStateName "xFinal" + InitialState "xInitial" + LimitDataPoints on + MaxDataPoints "1000" + LoadExternalInput off + LoadInitialState off + SaveFinalState off + SaveCompleteFinalSimState off + SaveFormat "Array" + SaveOutput on + SaveState off + SignalLogging on + InspectSignalLogs off + SaveTime on + ReturnWorkspaceOutputs off + StateSaveName "xout" + TimeSaveName "tout" + OutputSaveName "yout" + SignalLoggingName "logsout" + OutputOption "RefineOutputTimes" + OutputTimes "[]" + ReturnWorkspaceOutputsName "out" + Refine "1" + } + Simulink.OptimizationCC { + $ObjectID 4 + Version "1.6.0" + Array { + Type "Cell" + Dimension 4 + Cell "ZeroExternalMemoryAtStartup" + Cell "ZeroInternalMemoryAtStartup" + Cell "NoFixptDivByZeroProtection" + Cell "OptimizeModelRefInitCode" + PropName "DisabledProps" + } + BlockReduction on + BooleanDataType on + ConditionallyExecuteInputs on + InlineParams off + UseIntDivNetSlope off + InlineInvariantSignals off + OptimizeBlockIOStorage on + BufferReuse on + EnhancedBackFolding off + StrengthReduction off + EnforceIntegerDowncast on + ExpressionFolding on + BooleansAsBitfields off + EnableMemcpy on + MemcpyThreshold 64 + PassReuseOutputArgsAs "Structure reference" + ExpressionDepthLimit 2147483647 + FoldNonRolledExpr on + LocalBlockOutputs on + RollThreshold 5 + SystemCodeInlineAuto off + StateBitsets off + DataBitsets off + UseTempVars off + ZeroExternalMemoryAtStartup on + ZeroInternalMemoryAtStartup on + InitFltsAndDblsToZero on + NoFixptDivByZeroProtection off + EfficientFloat2IntCast off + EfficientMapNaN2IntZero on + OptimizeModelRefInitCode off + LifeSpan "inf" + BufferReusableBoundary on + SimCompilerOptimization "Off" + AccelVerboseBuild off + } + Simulink.DebuggingCC { + $ObjectID 5 + Version "1.6.0" + RTPrefix "error" + ConsistencyChecking "none" + ArrayBoundsChecking "none" + SignalInfNanChecking "none" + SignalRangeChecking "none" + ReadBeforeWriteMsg "UseLocalSettings" + WriteAfterWriteMsg "UseLocalSettings" + WriteAfterReadMsg "UseLocalSettings" + AlgebraicLoopMsg "warning" + ArtificialAlgebraicLoopMsg "warning" + SaveWithDisabledLinksMsg "warning" + SaveWithParameterizedLinksMsg "none" + CheckSSInitialOutputMsg on + UnderspecifiedInitializationDetection "Classic" + MergeDetectMultiDrivingBlocksExec "none" + CheckExecutionContextPreStartOutputMsg off + CheckExecutionContextRuntimeOutputMsg off + SignalResolutionControl "TryResolveAllWithWarning" + BlockPriorityViolationMsg "warning" + MinStepSizeMsg "warning" + TimeAdjustmentMsg "none" + MaxConsecutiveZCsMsg "error" + SolverPrmCheckMsg "warning" + InheritedTsInSrcMsg "warning" + DiscreteInheritContinuousMsg "warning" + MultiTaskDSMMsg "error" + MultiTaskCondExecSysMsg "error" + MultiTaskRateTransMsg "error" + SingleTaskRateTransMsg "none" + TasksWithSamePriorityMsg "warning" + SigSpecEnsureSampleTimeMsg "warning" + CheckMatrixSingularityMsg "none" + IntegerOverflowMsg "warning" + Int32ToFloatConvMsg "warning" + ParameterDowncastMsg "error" + ParameterOverflowMsg "error" + ParameterUnderflowMsg "none" + ParameterPrecisionLossMsg "warning" + ParameterTunabilityLossMsg "warning" + FixptConstUnderflowMsg "none" + FixptConstOverflowMsg "none" + FixptConstPrecisionLossMsg "none" + UnderSpecifiedDataTypeMsg "none" + UnnecessaryDatatypeConvMsg "none" + VectorMatrixConversionMsg "none" + InvalidFcnCallConnMsg "error" + FcnCallInpInsideContextMsg "Use local settings" + SignalLabelMismatchMsg "none" + UnconnectedInputMsg "warning" + UnconnectedOutputMsg "warning" + UnconnectedLineMsg "warning" + SFcnCompatibilityMsg "none" + UniqueDataStoreMsg "none" + BusObjectLabelMismatch "warning" + RootOutportRequireBusObject "warning" + AssertControl "UseLocalSettings" + EnableOverflowDetection off + ModelReferenceIOMsg "none" + ModelReferenceVersionMismatchMessage "none" + ModelReferenceIOMismatchMessage "none" + ModelReferenceCSMismatchMessage "none" + UnknownTsInhSupMsg "warning" + ModelReferenceDataLoggingMessage "warning" + ModelReferenceSymbolNameMessage "warning" + ModelReferenceExtraNoncontSigs "error" + StateNameClashWarn "warning" + SimStateInterfaceChecksumMismatchMsg "warning" + StrictBusMsg "Warning" + LoggingUnavailableSignals "error" + BlockIODiagnostic "none" + } + Simulink.HardwareCC { + $ObjectID 6 + Version "1.6.0" + ProdBitPerChar 8 + ProdBitPerShort 16 + ProdBitPerInt 32 + ProdBitPerLong 32 + ProdIntDivRoundTo "Undefined" + ProdEndianess "Unspecified" + ProdWordSize 32 + ProdShiftRightIntArith on + ProdHWDeviceType "32-bit Generic" + TargetBitPerChar 8 + TargetBitPerShort 16 + TargetBitPerInt 32 + TargetBitPerLong 32 + TargetShiftRightIntArith on + TargetIntDivRoundTo "Undefined" + TargetEndianess "Unspecified" + TargetWordSize 32 + TargetTypeEmulationWarnSuppressLevel 0 + TargetPreprocMaxBitsSint 32 + TargetPreprocMaxBitsUint 32 + TargetHWDeviceType "Specified" + TargetUnknown off + ProdEqTarget on + } + Simulink.ModelReferenceCC { + $ObjectID 7 + Version "1.6.0" + UpdateModelReferenceTargets "IfOutOfDateOrStructuralChange" + CheckModelReferenceTargetMessage "error" + ModelReferenceNumInstancesAllowed "Multi" + ModelReferencePassRootInputsByReference on + ModelReferenceMinAlgLoopOccurrences off + } + Simulink.SFSimCC { + $ObjectID 8 + Version "1.6.0" + SFSimEnableDebug on + SFSimOverflowDetection on + SFSimEcho on + SimBlas on + SimCtrlC on + SimExtrinsic on + SimIntegrity on + SimUseLocalCustomCode off + SimBuildMode "sf_incremental_build" + } + Simulink.RTWCC { + $BackupClass "Simulink.RTWCC" + $ObjectID 9 + Version "1.6.0" + Array { + Type "Cell" + Dimension 1 + Cell "IncludeHyperlinkInReport" + PropName "DisabledProps" + } + SystemTargetFile "grt.tlc" + GenCodeOnly off + MakeCommand "make_rtw" + GenerateMakefile on + TemplateMakefile "grt_default_tmf" + GenerateReport off + SaveLog off + RTWVerbose on + RetainRTWFile off + ProfileTLC off + TLCDebug off + TLCCoverage off + TLCAssert off + ProcessScriptMode "Default" + ConfigurationMode "Optimized" + ConfigAtBuild off + RTWUseLocalCustomCode off + RTWUseSimCustomCode off + IncludeHyperlinkInReport off + LaunchReport off + TargetLang "C" + IncludeBusHierarchyInRTWFileBlockHierarchyMap off + IncludeERTFirstTime off + GenerateTraceInfo off + GenerateTraceReport off + GenerateTraceReportSl off + GenerateTraceReportSf off + GenerateTraceReportEml off + GenerateCodeInfo off + RTWCompilerOptimization "Off" + CheckMdlBeforeBuild "Off" + Array { + Type "Handle" + Dimension 2 + Simulink.CodeAppCC { + $ObjectID 10 + Version "1.6.0" + Array { + Type "Cell" + Dimension 16 + Cell "IgnoreCustomStorageClasses" + Cell "InsertBlockDesc" + Cell "SFDataObjDesc" + Cell "SimulinkDataObjDesc" + Cell "DefineNamingRule" + Cell "SignalNamingRule" + Cell "ParamNamingRule" + Cell "InlinedPrmAccess" + Cell "CustomSymbolStr" + Cell "CustomSymbolStrGlobalVar" + Cell "CustomSymbolStrType" + Cell "CustomSymbolStrField" + Cell "CustomSymbolStrFcn" + Cell "CustomSymbolStrBlkIO" + Cell "CustomSymbolStrTmpVar" + Cell "CustomSymbolStrMacro" + PropName "DisabledProps" + } + ForceParamTrailComments off + GenerateComments on + IgnoreCustomStorageClasses on + IgnoreTestpoints off + IncHierarchyInIds off + MaxIdLength 31 + PreserveName off + PreserveNameWithParent off + ShowEliminatedStatement off + IncAutoGenComments off + SimulinkDataObjDesc off + SFDataObjDesc off + IncDataTypeInIds off + MangleLength 1 + CustomSymbolStrGlobalVar "$R$N$M" + CustomSymbolStrType "$N$R$M" + CustomSymbolStrField "$N$M" + CustomSymbolStrFcn "$R$N$M$F" + CustomSymbolStrFcnArg "rt$I$N$M" + CustomSymbolStrBlkIO "rtb_$N$M" + CustomSymbolStrTmpVar "$N$M" + CustomSymbolStrMacro "$R$N$M" + DefineNamingRule "None" + ParamNamingRule "None" + SignalNamingRule "None" + InsertBlockDesc off + SimulinkBlockComments on + EnableCustomComments off + InlinedPrmAccess "Literals" + ReqsInCode off + UseSimReservedNames off + } + Simulink.GRTTargetCC { + $BackupClass "Simulink.TargetCC" + $ObjectID 11 + Version "1.6.0" + Array { + Type "Cell" + Dimension 13 + Cell "IncludeMdlTerminateFcn" + Cell "CombineOutputUpdateFcns" + Cell "SuppressErrorStatus" + Cell "ERTCustomFileBanners" + Cell "GenerateSampleERTMain" + Cell "GenerateTestInterfaces" + Cell "MultiInstanceERTCode" + Cell "PurelyIntegerCode" + Cell "SupportNonFinite" + Cell "SupportComplex" + Cell "SupportAbsoluteTime" + Cell "SupportContinuousTime" + Cell "SupportNonInlinedSFcns" + PropName "DisabledProps" + } + TargetFcnLib "ansi_tfl_tmw.mat" + TargetLibSuffix "" + TargetPreCompLibLocation "" + TargetFunctionLibrary "ANSI_C" + UtilityFuncGeneration "Auto" + ERTMultiwordTypeDef "System defined" + ERTMultiwordLength 256 + MultiwordLength 2048 + GenerateFullHeader on + GenerateSampleERTMain off + GenerateTestInterfaces off + IsPILTarget off + ModelReferenceCompliant on + ParMdlRefBuildCompliant on + CompOptLevelCompliant on + IncludeMdlTerminateFcn on + GeneratePreprocessorConditionals "Disable all" + CombineOutputUpdateFcns off + SuppressErrorStatus off + ERTFirstTimeCompliant off + IncludeFileDelimiter "Auto" + ERTCustomFileBanners off + SupportAbsoluteTime on + LogVarNameModifier "rt_" + MatFileLogging on + MultiInstanceERTCode off + SupportNonFinite on + SupportComplex on + PurelyIntegerCode off + SupportContinuousTime on + SupportNonInlinedSFcns on + SupportVariableSizeSignals off + EnableShiftOperators on + ParenthesesLevel "Nominal" + PortableWordSizes off + ModelStepFunctionPrototypeControlCompliant off + CPPClassGenCompliant off + AutosarCompliant off + UseMalloc off + ExtMode off + ExtModeStaticAlloc off + ExtModeTesting off + ExtModeStaticAllocSize 1000000 + ExtModeTransport 0 + ExtModeMexFile "ext_comm" + ExtModeIntrfLevel "Level1" + RTWCAPISignals off + RTWCAPIParams off + RTWCAPIStates off + GenerateASAP2 off + } + PropName "Components" + } + } + PropName "Components" + } + Name "Configuration" + CurrentDlgPage "Solver" + ConfigPrmDlgPosition " [ 200, 197, 1080, 827 ] " + } + PropName "ConfigurationSets" + } + Simulink.ConfigSet { + $PropName "ActiveConfigurationSet" + $ObjectID 1 + } + BlockDefaults { + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + NamePlacement "normal" + FontName "Courier" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + ShowName on + BlockRotation 0 + BlockMirror off + } + AnnotationDefaults { + HorizontalAlignment "center" + VerticalAlignment "middle" + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + FontName "Courier" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + UseDisplayTextAsClickCallback off + } + LineDefaults { + FontName "Courier" + FontSize 9 + FontWeight "normal" + FontAngle "normal" + } + BlockParameterDefaults { + Block { + BlockType FromWorkspace + VariableName "simulink_input" + SampleTime "-1" + Interpolate on + ZeroCross off + OutputAfterFinalValue "Extrapolation" + } + Block { + BlockType "S-Function" + FunctionName "system" + SFunctionModules "''" + PortCounts "[]" + SFunctionDeploymentMode off + } + Block { + BlockType Scope + ModelBased off + TickLabels "OneTimeTick" + ZoomMode "on" + Grid "on" + TimeRange "auto" + YMin "-5" + YMax "5" + SaveToWorkspace off + SaveName "ScopeData" + LimitDataPoints on + MaxDataPoints "5000" + Decimation "1" + SampleInput off + SampleTime "-1" + } + } + System { + Name "example_QProblemB" + Location [1922, 224, 3598, 1179] + Open on + ModelBrowserVisibility off + ModelBrowserWidth 200 + ScreenColor "white" + PaperOrientation "landscape" + PaperPositionMode "auto" + PaperType "usletter" + PaperUnits "inches" + TiledPaperMargins [0.500000, 0.500000, 0.500000, 0.500000] + TiledPageScale 1 + ShowPageBoundaries off + ZoomFactor "125" + ReportName "simulink-default.rpt" + SIDHighWatermark 6 + Block { + BlockType FromWorkspace + Name "g" + SID 2 + Position [170, 153, 235, 177] + VariableName "g" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "lb" + SID 3 + Position [170, 203, 235, 227] + VariableName "lb" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType "S-Function" + Name "qpOASES" + SID 6 + Ports [3, 4] + Position [505, 180, 700, 245] + BackgroundColor "yellow" + FunctionName "qpOASES_QProblemB" + Parameters "H" + EnableBusSupport off + } + Block { + BlockType FromWorkspace + Name "ub" + SID 4 + Position [170, 253, 235, 277] + VariableName "ub" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType Scope + Name "x,\nfval,\nexitflag,\niter" + SID 5 + Ports [4] + Position [855, 185, 905, 240] + Floating off + Location [6, 78, 1276, 993] + Open off + NumInputPorts "4" + List { + ListType AxesTitles + axes1 "%" + axes2 "%" + axes3 "%" + axes4 "%" + } + YMin "-5~-5~-5~-5" + YMax "5~5~5~5" + SaveName "ScopeData1" + DataFormat "StructureWithTime" + SampleTime "0" + } + Line { + SrcBlock "qpOASES" + SrcPort 1 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 1 + } + Line { + SrcBlock "qpOASES" + SrcPort 2 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 2 + } + Line { + SrcBlock "qpOASES" + SrcPort 3 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 3 + } + Line { + SrcBlock "qpOASES" + SrcPort 4 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 4 + } + Line { + SrcBlock "g" + SrcPort 1 + Points [50, 0; 0, 30] + DstBlock "qpOASES" + DstPort 1 + } + Line { + SrcBlock "lb" + SrcPort 1 + DstBlock "qpOASES" + DstPort 2 + } + Line { + SrcBlock "ub" + SrcPort 1 + Points [50, 0; 0, -30] + DstBlock "qpOASES" + DstPort 3 + } + Annotation { + Position [335, 96] + } + Annotation { + Name "This file is part of qpOASES.\n\nqpOASES -- An Implementation of the Online Active Set Strategy.\nC" + "opyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, Christian Kirches et al.\nAll rights reserved." + Position [608, 108] + } + } +} diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/example_SQProblem.mdl b/locomotion/src/third_party/qpOASES/interfaces/simulink/example_SQProblem.mdl new file mode 100644 index 0000000..94ed087 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/example_SQProblem.mdl @@ -0,0 +1,797 @@ +Model { + Name "example_SQProblem" + Version 7.4 + MdlSubVersion 0 + GraphicalInterface { + NumRootInports 0 + NumRootOutports 0 + ParameterArgumentNames "" + ComputedModelVersion "1.67" + NumModelReferences 0 + NumTestPointedSignals 0 + } + SavedCharacterEncoding "UTF-8" + SaveDefaultBlockParams on + ScopeRefreshTime 0.035000 + OverrideScopeRefreshTime on + DisableAllScopes off + DataTypeOverride "UseLocalSettings" + MinMaxOverflowLogging "UseLocalSettings" + MinMaxOverflowArchiveMode "Overwrite" + MaxMDLFileLineLength 120 + Created "Fri Apr 13 11:08:51 2007" + Creator "jferreau" + UpdateHistory "UpdateHistoryNever" + ModifiedByFormat "%" + LastModifiedBy "chjofer2" + ModifiedDateFormat "%" + LastModifiedDate "Wed Jan 07 09:31:42 2015" + RTWModifiedTimeStamp 342523898 + ModelVersionFormat "1.%" + ConfigurationManager "None" + SampleTimeColors off + SampleTimeAnnotations off + LibraryLinkDisplay "none" + WideLines off + ShowLineDimensions off + ShowPortDataTypes off + ShowLoopsOnError on + IgnoreBidirectionalLines off + ShowStorageClass off + ShowTestPointIcons on + ShowSignalResolutionIcons on + ShowViewerIcons on + SortedOrder off + ExecutionContextIcon off + ShowLinearizationAnnotations on + BlockNameDataTip off + BlockParametersDataTip off + BlockDescriptionStringDataTip off + ToolBar on + StatusBar on + BrowserShowLibraryLinks off + BrowserLookUnderMasks off + SimulationMode "normal" + LinearizationMsg "none" + Profile off + ParamWorkspaceSource "MATLABWorkspace" + AccelSystemTargetFile "accel.tlc" + AccelTemplateMakefile "accel_default_tmf" + AccelMakeCommand "make_rtw" + TryForcingSFcnDF off + RecordCoverage off + CovPath "/" + CovSaveName "covdata" + CovMetricSettings "dw" + CovNameIncrementing off + CovHtmlReporting on + CovForceBlockReductionOff on + covSaveCumulativeToWorkspaceVar on + CovSaveSingleToWorkspaceVar on + CovCumulativeVarName "covCumulativeData" + CovCumulativeReport off + CovReportOnPause on + CovModelRefEnable "Off" + CovExternalEMLEnable off + ExtModeBatchMode off + ExtModeEnableFloating on + ExtModeTrigType "manual" + ExtModeTrigMode "normal" + ExtModeTrigPort "1" + ExtModeTrigElement "any" + ExtModeTrigDuration 1000 + ExtModeTrigDurationFloating "auto" + ExtModeTrigHoldOff 0 + ExtModeTrigDelay 0 + ExtModeTrigDirection "rising" + ExtModeTrigLevel 0 + ExtModeArchiveMode "off" + ExtModeAutoIncOneShot off + ExtModeIncDirWhenArm off + ExtModeAddSuffixToVar off + ExtModeWriteAllDataToWs off + ExtModeArmWhenConnect on + ExtModeSkipDownloadWhenConnect off + ExtModeLogAll on + ExtModeAutoUpdateStatusClock off + BufferReuse on + ShowModelReferenceBlockVersion off + ShowModelReferenceBlockIO off + Array { + Type "Handle" + Dimension 1 + Simulink.ConfigSet { + $ObjectID 1 + Version "1.6.0" + Array { + Type "Handle" + Dimension 8 + Simulink.SolverCC { + $ObjectID 2 + Version "1.6.0" + StartTime "0.0" + StopTime "0.5" + AbsTol "auto" + FixedStep "auto" + InitialStep "auto" + MaxNumMinSteps "-1" + MaxOrder 5 + ZcThreshold "auto" + ConsecutiveZCsStepRelTol "10*128*eps" + MaxConsecutiveZCs "1000" + ExtrapolationOrder 4 + NumberNewtonIterations 1 + MaxStep "auto" + MinStep "auto" + MaxConsecutiveMinStep "1" + RelTol "1e-3" + SolverMode "Auto" + Solver "VariableStepDiscrete" + SolverName "VariableStepDiscrete" + ShapePreserveControl "DisableAll" + ZeroCrossControl "UseLocalSettings" + ZeroCrossAlgorithm "Nonadaptive" + AlgebraicLoopSolver "TrustRegion" + SolverResetMethod "Fast" + PositivePriorityOrder off + AutoInsertRateTranBlk off + SampleTimeConstraint "Unconstrained" + InsertRTBMode "Whenever possible" + } + Simulink.DataIOCC { + $ObjectID 3 + Version "1.6.0" + Decimation "1" + ExternalInput "[t, u]" + FinalStateName "xFinal" + InitialState "xInitial" + LimitDataPoints on + MaxDataPoints "1000" + LoadExternalInput off + LoadInitialState off + SaveFinalState off + SaveCompleteFinalSimState off + SaveFormat "Array" + SaveOutput on + SaveState off + SignalLogging on + InspectSignalLogs off + SaveTime on + ReturnWorkspaceOutputs off + StateSaveName "xout" + TimeSaveName "tout" + OutputSaveName "yout" + SignalLoggingName "logsout" + OutputOption "RefineOutputTimes" + OutputTimes "[]" + ReturnWorkspaceOutputsName "out" + Refine "1" + } + Simulink.OptimizationCC { + $ObjectID 4 + Version "1.6.0" + Array { + Type "Cell" + Dimension 4 + Cell "ZeroExternalMemoryAtStartup" + Cell "ZeroInternalMemoryAtStartup" + Cell "NoFixptDivByZeroProtection" + Cell "OptimizeModelRefInitCode" + PropName "DisabledProps" + } + BlockReduction on + BooleanDataType on + ConditionallyExecuteInputs on + InlineParams off + UseIntDivNetSlope off + InlineInvariantSignals off + OptimizeBlockIOStorage on + BufferReuse on + EnhancedBackFolding off + StrengthReduction off + EnforceIntegerDowncast on + ExpressionFolding on + BooleansAsBitfields off + EnableMemcpy on + MemcpyThreshold 64 + PassReuseOutputArgsAs "Structure reference" + ExpressionDepthLimit 2147483647 + FoldNonRolledExpr on + LocalBlockOutputs on + RollThreshold 5 + SystemCodeInlineAuto off + StateBitsets off + DataBitsets off + UseTempVars off + ZeroExternalMemoryAtStartup on + ZeroInternalMemoryAtStartup on + InitFltsAndDblsToZero on + NoFixptDivByZeroProtection off + EfficientFloat2IntCast off + EfficientMapNaN2IntZero on + OptimizeModelRefInitCode off + LifeSpan "inf" + BufferReusableBoundary on + SimCompilerOptimization "Off" + AccelVerboseBuild off + } + Simulink.DebuggingCC { + $ObjectID 5 + Version "1.6.0" + RTPrefix "error" + ConsistencyChecking "none" + ArrayBoundsChecking "none" + SignalInfNanChecking "none" + SignalRangeChecking "none" + ReadBeforeWriteMsg "UseLocalSettings" + WriteAfterWriteMsg "UseLocalSettings" + WriteAfterReadMsg "UseLocalSettings" + AlgebraicLoopMsg "warning" + ArtificialAlgebraicLoopMsg "warning" + SaveWithDisabledLinksMsg "warning" + SaveWithParameterizedLinksMsg "none" + CheckSSInitialOutputMsg on + UnderspecifiedInitializationDetection "Classic" + MergeDetectMultiDrivingBlocksExec "none" + CheckExecutionContextPreStartOutputMsg off + CheckExecutionContextRuntimeOutputMsg off + SignalResolutionControl "TryResolveAllWithWarning" + BlockPriorityViolationMsg "warning" + MinStepSizeMsg "warning" + TimeAdjustmentMsg "none" + MaxConsecutiveZCsMsg "error" + SolverPrmCheckMsg "warning" + InheritedTsInSrcMsg "warning" + DiscreteInheritContinuousMsg "warning" + MultiTaskDSMMsg "error" + MultiTaskCondExecSysMsg "error" + MultiTaskRateTransMsg "error" + SingleTaskRateTransMsg "none" + TasksWithSamePriorityMsg "warning" + SigSpecEnsureSampleTimeMsg "warning" + CheckMatrixSingularityMsg "none" + IntegerOverflowMsg "warning" + Int32ToFloatConvMsg "warning" + ParameterDowncastMsg "error" + ParameterOverflowMsg "error" + ParameterUnderflowMsg "none" + ParameterPrecisionLossMsg "warning" + ParameterTunabilityLossMsg "warning" + FixptConstUnderflowMsg "none" + FixptConstOverflowMsg "none" + FixptConstPrecisionLossMsg "none" + UnderSpecifiedDataTypeMsg "none" + UnnecessaryDatatypeConvMsg "none" + VectorMatrixConversionMsg "none" + InvalidFcnCallConnMsg "error" + FcnCallInpInsideContextMsg "Use local settings" + SignalLabelMismatchMsg "none" + UnconnectedInputMsg "warning" + UnconnectedOutputMsg "warning" + UnconnectedLineMsg "warning" + SFcnCompatibilityMsg "none" + UniqueDataStoreMsg "none" + BusObjectLabelMismatch "warning" + RootOutportRequireBusObject "warning" + AssertControl "UseLocalSettings" + EnableOverflowDetection off + ModelReferenceIOMsg "none" + ModelReferenceVersionMismatchMessage "none" + ModelReferenceIOMismatchMessage "none" + ModelReferenceCSMismatchMessage "none" + UnknownTsInhSupMsg "warning" + ModelReferenceDataLoggingMessage "warning" + ModelReferenceSymbolNameMessage "warning" + ModelReferenceExtraNoncontSigs "error" + StateNameClashWarn "warning" + SimStateInterfaceChecksumMismatchMsg "warning" + StrictBusMsg "Warning" + LoggingUnavailableSignals "error" + BlockIODiagnostic "none" + } + Simulink.HardwareCC { + $ObjectID 6 + Version "1.6.0" + ProdBitPerChar 8 + ProdBitPerShort 16 + ProdBitPerInt 32 + ProdBitPerLong 32 + ProdIntDivRoundTo "Undefined" + ProdEndianess "Unspecified" + ProdWordSize 32 + ProdShiftRightIntArith on + ProdHWDeviceType "32-bit Generic" + TargetBitPerChar 8 + TargetBitPerShort 16 + TargetBitPerInt 32 + TargetBitPerLong 32 + TargetShiftRightIntArith on + TargetIntDivRoundTo "Undefined" + TargetEndianess "Unspecified" + TargetWordSize 32 + TargetTypeEmulationWarnSuppressLevel 0 + TargetPreprocMaxBitsSint 32 + TargetPreprocMaxBitsUint 32 + TargetHWDeviceType "Specified" + TargetUnknown off + ProdEqTarget on + } + Simulink.ModelReferenceCC { + $ObjectID 7 + Version "1.6.0" + UpdateModelReferenceTargets "IfOutOfDateOrStructuralChange" + CheckModelReferenceTargetMessage "error" + ModelReferenceNumInstancesAllowed "Multi" + ModelReferencePassRootInputsByReference on + ModelReferenceMinAlgLoopOccurrences off + } + Simulink.SFSimCC { + $ObjectID 8 + Version "1.6.0" + SFSimEnableDebug on + SFSimOverflowDetection on + SFSimEcho on + SimBlas on + SimCtrlC on + SimExtrinsic on + SimIntegrity on + SimUseLocalCustomCode off + SimBuildMode "sf_incremental_build" + } + Simulink.RTWCC { + $BackupClass "Simulink.RTWCC" + $ObjectID 9 + Version "1.6.0" + Array { + Type "Cell" + Dimension 1 + Cell "IncludeHyperlinkInReport" + PropName "DisabledProps" + } + SystemTargetFile "grt.tlc" + GenCodeOnly off + MakeCommand "make_rtw" + GenerateMakefile on + TemplateMakefile "grt_default_tmf" + GenerateReport off + SaveLog off + RTWVerbose on + RetainRTWFile off + ProfileTLC off + TLCDebug off + TLCCoverage off + TLCAssert off + ProcessScriptMode "Default" + ConfigurationMode "Optimized" + ConfigAtBuild off + RTWUseLocalCustomCode off + RTWUseSimCustomCode off + IncludeHyperlinkInReport off + LaunchReport off + TargetLang "C" + IncludeBusHierarchyInRTWFileBlockHierarchyMap off + IncludeERTFirstTime off + GenerateTraceInfo off + GenerateTraceReport off + GenerateTraceReportSl off + GenerateTraceReportSf off + GenerateTraceReportEml off + GenerateCodeInfo off + RTWCompilerOptimization "Off" + CheckMdlBeforeBuild "Off" + Array { + Type "Handle" + Dimension 2 + Simulink.CodeAppCC { + $ObjectID 10 + Version "1.6.0" + Array { + Type "Cell" + Dimension 16 + Cell "IgnoreCustomStorageClasses" + Cell "InsertBlockDesc" + Cell "SFDataObjDesc" + Cell "SimulinkDataObjDesc" + Cell "DefineNamingRule" + Cell "SignalNamingRule" + Cell "ParamNamingRule" + Cell "InlinedPrmAccess" + Cell "CustomSymbolStr" + Cell "CustomSymbolStrGlobalVar" + Cell "CustomSymbolStrType" + Cell "CustomSymbolStrField" + Cell "CustomSymbolStrFcn" + Cell "CustomSymbolStrBlkIO" + Cell "CustomSymbolStrTmpVar" + Cell "CustomSymbolStrMacro" + PropName "DisabledProps" + } + ForceParamTrailComments off + GenerateComments on + IgnoreCustomStorageClasses on + IgnoreTestpoints off + IncHierarchyInIds off + MaxIdLength 31 + PreserveName off + PreserveNameWithParent off + ShowEliminatedStatement off + IncAutoGenComments off + SimulinkDataObjDesc off + SFDataObjDesc off + IncDataTypeInIds off + MangleLength 1 + CustomSymbolStrGlobalVar "$R$N$M" + CustomSymbolStrType "$N$R$M" + CustomSymbolStrField "$N$M" + CustomSymbolStrFcn "$R$N$M$F" + CustomSymbolStrFcnArg "rt$I$N$M" + CustomSymbolStrBlkIO "rtb_$N$M" + CustomSymbolStrTmpVar "$N$M" + CustomSymbolStrMacro "$R$N$M" + DefineNamingRule "None" + ParamNamingRule "None" + SignalNamingRule "None" + InsertBlockDesc off + SimulinkBlockComments on + EnableCustomComments off + InlinedPrmAccess "Literals" + ReqsInCode off + UseSimReservedNames off + } + Simulink.GRTTargetCC { + $BackupClass "Simulink.TargetCC" + $ObjectID 11 + Version "1.6.0" + Array { + Type "Cell" + Dimension 13 + Cell "IncludeMdlTerminateFcn" + Cell "CombineOutputUpdateFcns" + Cell "SuppressErrorStatus" + Cell "ERTCustomFileBanners" + Cell "GenerateSampleERTMain" + Cell "GenerateTestInterfaces" + Cell "MultiInstanceERTCode" + Cell "PurelyIntegerCode" + Cell "SupportNonFinite" + Cell "SupportComplex" + Cell "SupportAbsoluteTime" + Cell "SupportContinuousTime" + Cell "SupportNonInlinedSFcns" + PropName "DisabledProps" + } + TargetFcnLib "ansi_tfl_tmw.mat" + TargetLibSuffix "" + TargetPreCompLibLocation "" + TargetFunctionLibrary "ANSI_C" + UtilityFuncGeneration "Auto" + ERTMultiwordTypeDef "System defined" + ERTMultiwordLength 256 + MultiwordLength 2048 + GenerateFullHeader on + GenerateSampleERTMain off + GenerateTestInterfaces off + IsPILTarget off + ModelReferenceCompliant on + ParMdlRefBuildCompliant on + CompOptLevelCompliant on + IncludeMdlTerminateFcn on + GeneratePreprocessorConditionals "Disable all" + CombineOutputUpdateFcns off + SuppressErrorStatus off + ERTFirstTimeCompliant off + IncludeFileDelimiter "Auto" + ERTCustomFileBanners off + SupportAbsoluteTime on + LogVarNameModifier "rt_" + MatFileLogging on + MultiInstanceERTCode off + SupportNonFinite on + SupportComplex on + PurelyIntegerCode off + SupportContinuousTime on + SupportNonInlinedSFcns on + SupportVariableSizeSignals off + EnableShiftOperators on + ParenthesesLevel "Nominal" + PortableWordSizes off + ModelStepFunctionPrototypeControlCompliant off + CPPClassGenCompliant off + AutosarCompliant off + UseMalloc off + ExtMode off + ExtModeStaticAlloc off + ExtModeTesting off + ExtModeStaticAllocSize 1000000 + ExtModeTransport 0 + ExtModeMexFile "ext_comm" + ExtModeIntrfLevel "Level1" + RTWCAPISignals off + RTWCAPIParams off + RTWCAPIStates off + GenerateASAP2 off + } + PropName "Components" + } + } + PropName "Components" + } + Name "Configuration" + CurrentDlgPage "Solver" + ConfigPrmDlgPosition " [ 200, 197, 1080, 827 ] " + } + PropName "ConfigurationSets" + } + Simulink.ConfigSet { + $PropName "ActiveConfigurationSet" + $ObjectID 1 + } + BlockDefaults { + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + NamePlacement "normal" + FontName "Courier" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + ShowName on + BlockRotation 0 + BlockMirror off + } + AnnotationDefaults { + HorizontalAlignment "center" + VerticalAlignment "middle" + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + FontName "Courier" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + UseDisplayTextAsClickCallback off + } + LineDefaults { + FontName "Courier" + FontSize 9 + FontWeight "normal" + FontAngle "normal" + } + BlockParameterDefaults { + Block { + BlockType FromWorkspace + VariableName "simulink_input" + SampleTime "-1" + Interpolate on + ZeroCross off + OutputAfterFinalValue "Extrapolation" + } + Block { + BlockType "S-Function" + FunctionName "system" + SFunctionModules "''" + PortCounts "[]" + SFunctionDeploymentMode off + } + Block { + BlockType Scope + ModelBased off + TickLabels "OneTimeTick" + ZoomMode "on" + Grid "on" + TimeRange "auto" + YMin "-5" + YMax "5" + SaveToWorkspace off + SaveName "ScopeData" + LimitDataPoints on + MaxDataPoints "5000" + Decimation "1" + SampleInput off + SampleTime "-1" + } + } + System { + Name "example_SQProblem" + Location [122, 122, 1798, 1077] + Open on + ModelBrowserVisibility off + ModelBrowserWidth 200 + ScreenColor "white" + PaperOrientation "landscape" + PaperPositionMode "auto" + PaperType "usletter" + PaperUnits "inches" + TiledPaperMargins [0.500000, 0.500000, 0.500000, 0.500000] + TiledPageScale 1 + ShowPageBoundaries off + ZoomFactor "125" + ReportName "simulink-default.rpt" + SIDHighWatermark 14 + Block { + BlockType FromWorkspace + Name "A" + SID 3 + Position [100, 198, 165, 222] + VariableName "A" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "H" + SID 1 + Position [100, 98, 165, 122] + VariableName "H" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "g" + SID 2 + Position [100, 148, 165, 172] + VariableName "g" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "lb" + SID 4 + Position [100, 248, 165, 272] + VariableName "lb" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "lbA" + SID 6 + Position [100, 348, 165, 372] + VariableName "lbA" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType "S-Function" + Name "qpOASES" + SID 9 + Ports [7, 4] + Position [590, 224, 790, 296] + BackgroundColor "yellow" + FunctionName "qpOASES_SQProblem" + EnableBusSupport off + } + Block { + BlockType FromWorkspace + Name "ub" + SID 5 + Position [100, 298, 165, 322] + VariableName "ub" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType FromWorkspace + Name "ubA" + SID 7 + Position [100, 398, 165, 422] + VariableName "ubA" + SampleTime "0.1" + ZeroCross on + OutputAfterFinalValue "Holding final value" + } + Block { + BlockType Scope + Name "x,\nfval,\nexitflag,\niter" + SID 8 + Ports [4] + Position [950, 223, 1005, 297] + Floating off + Location [6, 78, 1276, 993] + Open off + NumInputPorts "4" + List { + ListType AxesTitles + axes1 "%" + axes2 "%" + axes3 "%" + axes4 "%" + } + YMin "-5~-5~-5~-5" + YMax "5~5~5~5" + SaveName "ScopeData1" + DataFormat "StructureWithTime" + SampleTime "0" + } + Line { + SrcBlock "H" + SrcPort 1 + Points [155, 0; 0, 120] + DstBlock "qpOASES" + DstPort 1 + } + Line { + SrcBlock "g" + SrcPort 1 + Points [115, 0; 0, 80] + DstBlock "qpOASES" + DstPort 2 + } + Line { + Labels [3, 0] + SrcBlock "ubA" + SrcPort 1 + Points [160, 0; 0, -120] + DstBlock "qpOASES" + DstPort 7 + } + Line { + SrcBlock "ub" + SrcPort 1 + Points [80, 0; 0, -40] + DstBlock "qpOASES" + DstPort 5 + } + Line { + SrcBlock "lb" + SrcPort 1 + DstBlock "qpOASES" + DstPort 4 + } + Line { + SrcBlock "A" + SrcPort 1 + Points [80, 0; 0, 40] + DstBlock "qpOASES" + DstPort 3 + } + Line { + Labels [3, 0] + SrcBlock "lbA" + SrcPort 1 + Points [115, 0; 0, -80] + DstBlock "qpOASES" + DstPort 6 + } + Line { + SrcBlock "qpOASES" + SrcPort 1 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 1 + } + Line { + SrcBlock "qpOASES" + SrcPort 2 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 2 + } + Line { + SrcBlock "qpOASES" + SrcPort 3 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 3 + } + Line { + SrcBlock "qpOASES" + SrcPort 4 + DstBlock "x,\nfval,\nexitflag,\niter" + DstPort 4 + } + Annotation { + Position [350, 96] + } + Annotation { + Name "This file is part of qpOASES.\n\nqpOASES -- An Implementation of the Online Active Set Strategy.\nC" + "opyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, Christian Kirches et al.\nAll rights reserved." + Position [683, 128] + } + } +} diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_QProblem.m b/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_QProblem.m new file mode 100644 index 0000000..464d89b --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_QProblem.m @@ -0,0 +1,86 @@ +%% +%% This file is part of qpOASES. +%% +%% qpOASES -- An Implementation of the Online Active Set Strategy. +%% Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%% Christian Kirches et al. All rights reserved. +%% +%% qpOASES is free software; you can redistribute it and/or +%% modify it under the terms of the GNU Lesser General Public +%% License as published by the Free Software Foundation; either +%% version 2.1 of the License, or (at your option) any later version. +%% +%% qpOASES is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%% See the GNU Lesser General Public License for more details. +%% +%% You should have received a copy of the GNU Lesser General Public +%% License along with qpOASES; if not, write to the Free Software +%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +%% + + + +%% +%% Filename: interfaces/simulink/load_example_QProblem.m +%% Author: Hans Joachim Ferreau (thanks to Aude Perrin) +%% Version: 3.2 +%% Date: 2007-2017 +%% + + + +clear all; + + +%% setup QP data +simulationTime = [0;0.1]; + +H = [ 1.0,0.0; ... + 0.0,0.5 ]; + +A = [ 1.0,1.0 ]; + +g.time = simulationTime; +data1 = [ 1.5,1.0 ]; +data2 = [ 1.0,1.5 ]; +g.signals.values = [data1; data2]; +g.signals.dimensions = numel(data1); + +lb.time = simulationTime; +data1 = [ 0.5,-2.0 ]; +data2 = [ 0.0,-1.0 ]; +lb.signals.values = [data1; data2]; +lb.signals.dimensions = numel(data1); + +ub.time = simulationTime; +data1 = [ 5.0,2.0 ]; +data2 = [ 5.0,-0.5 ]; +ub.signals.values = [data1; data2]; +ub.signals.dimensions = numel(data1); + +lbA.time = simulationTime; +data1 = [ -1.0 ]; +data2 = [ -2.0 ]; +lbA.signals.values = [data1; data2]; +lbA.signals.dimensions = numel(data1); + +ubA.time = simulationTime; +data1 = [ 2.0 ]; +data2 = [ 1.0 ]; +ubA.signals.values = [data1; data2]; +ubA.signals.dimensions = numel(data1); + + +clear simulationTime data1 data2 + + +%% open corresponding simulink example +open( 'example_QProblem.mdl' ); + + + +%% +%% end of file +%% diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_QProblemB.m b/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_QProblemB.m new file mode 100644 index 0000000..bc06729 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_QProblemB.m @@ -0,0 +1,72 @@ +%% +%% This file is part of qpOASES. +%% +%% qpOASES -- An Implementation of the Online Active Set Strategy. +%% Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%% Christian Kirches et al. All rights reserved. +%% +%% qpOASES is free software; you can redistribute it and/or +%% modify it under the terms of the GNU Lesser General Public +%% License as published by the Free Software Foundation; either +%% version 2.1 of the License, or (at your option) any later version. +%% +%% qpOASES is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%% See the GNU Lesser General Public License for more details. +%% +%% You should have received a copy of the GNU Lesser General Public +%% License along with qpOASES; if not, write to the Free Software +%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +%% + + + +%% +%% Filename: interfaces/simulink/load_example_QProblemB.m +%% Author: Hans Joachim Ferreau (thanks to Aude Perrin) +%% Version: 3.2 +%% Date: 2007-2017 +%% + + + +clear all; + + +%% setup QP data +simulationTime = [0;0.1]; + +H = [ 1.0,0.0; ... + 0.0,0.5 ]; + +g.time = simulationTime; +data1 = [ 1.5,1.0 ]; +data2 = [ 1.0,1.5 ]; +g.signals.values = [data1; data2]; +g.signals.dimensions = numel(data1); + +lb.time = simulationTime; +data1 = [ 0.5,-2.0 ]; +data2 = [ 0.0,-1.0 ]; +lb.signals.values = [data1; data2]; +lb.signals.dimensions = numel(data1); + +ub.time = simulationTime; +data1 = [ 5.0,2.0 ]; +data2 = [ 5.0,-0.5 ]; +ub.signals.values = [data1; data2]; +ub.signals.dimensions = numel(data1); + + +clear simulationTime data1 data2 + + +%% open corresponding simulink example +open( 'example_QProblemB.mdl' ); + + + +%% +%% end of file +%% diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_SQProblem.m b/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_SQProblem.m new file mode 100644 index 0000000..8835b72 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/load_example_SQProblem.m @@ -0,0 +1,95 @@ +%% +%% This file is part of qpOASES. +%% +%% qpOASES -- An Implementation of the Online Active Set Strategy. +%% Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%% Christian Kirches et al. All rights reserved. +%% +%% qpOASES is free software; you can redistribute it and/or +%% modify it under the terms of the GNU Lesser General Public +%% License as published by the Free Software Foundation; either +%% version 2.1 of the License, or (at your option) any later version. +%% +%% qpOASES is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%% See the GNU Lesser General Public License for more details. +%% +%% You should have received a copy of the GNU Lesser General Public +%% License along with qpOASES; if not, write to the Free Software +%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +%% + + + +%% +%% Filename: interfaces/simulink/load_example_SQProblem.m +%% Author: Hans Joachim Ferreau (thanks to Aude Perrin) +%% Version: 3.2 +%% Date: 2007-2017 +%% + + + +clear all; + + +%% setup QP data +simulationTime = [0;0.1]; + +H.time = simulationTime; +data1 = [ 1.0,0.0; ... + 0.0,0.5 ]; +data2 = [ 1.0,0.5; ... + 0.5,0.5 ]; +H.signals.values = [ data1(:)'; data2(:)' ]; +H.signals.dimensions = numel(data1); + +g.time = simulationTime; +data1 = [ 1.5,1.0 ]; +data2 = [ 1.0,1.5 ]; +g.signals.values = [data1; data2]; +g.signals.dimensions = numel(data1); + +A.time = simulationTime; +data1 = [ 1.0,1.0 ]; +data2 = [ 1.0,5.0 ]; +A.signals.values = [ data1(:)'; data2(:)' ]; +A.signals.dimensions = numel(data1); + +lb.time = simulationTime; +data1 = [ 0.5,-2.0 ]; +data2 = [ 0.0,-1.0 ]; +lb.signals.values = [data1; data2]; +lb.signals.dimensions = numel(data1); + +ub.time = simulationTime; +data1 = [ 5.0,2.0 ]; +data2 = [ 5.0,-0.5 ]; +ub.signals.values = [data1; data2]; +ub.signals.dimensions = numel(data1); + +lbA.time = simulationTime; +data1 = [ -1.0 ]; +data2 = [ -2.0 ]; +lbA.signals.values = [data1; data2]; +lbA.signals.dimensions = numel(data1); + +ubA.time = simulationTime; +data1 = [ 2.0 ]; +data2 = [ 1.0 ]; +ubA.signals.values = [data1; data2]; +ubA.signals.dimensions = numel(data1); + + +clear simulationTime data1 data2 + + +%% open corresponding simulink example +open( 'example_SQProblem.mdl' ); + + + +%% +%% end of file +%% diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/make.m b/locomotion/src/third_party/qpOASES/interfaces/simulink/make.m new file mode 100644 index 0000000..be4314b --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/make.m @@ -0,0 +1,239 @@ +function [] = make( varargin ) +%MAKE Compiles the Simulink interface of qpOASES. +% +%Type make to compile all interfaces that +% have been modified, +%type make clean to delete all compiled interfaces, +%type make clean all to first delete and then compile +% all interfaces, +%type make 'name' to compile only the interface with +% the given name (if it has been modified), +%type make 'opt' to compile all interfaces using the +% given compiler options. +% +%Copyright (C) 2013-2017 by Hans Joachim Ferreau, Andreas Potschka, +%Christian Kirches et al. All rights reserved. + +%% +%% This file is part of qpOASES. +%% +%% qpOASES -- An Implementation of the Online Active Set Strategy. +%% Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +%% Christian Kirches et al. All rights reserved. +%% +%% qpOASES is free software; you can redistribute it and/or +%% modify it under the terms of the GNU Lesser General Public +%% License as published by the Free Software Foundation; either +%% version 2.1 of the License, or (at your option) any later version. +%% +%% qpOASES is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%% See the GNU Lesser General Public License for more details. +%% +%% You should have received a copy of the GNU Lesser General Public +%% License along with qpOASES; if not, write to the Free Software +%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +%% + +%% +%% Filename: interfaces/simulink/make.m +%% Author: Hans Joachim Ferreau, Andreas Potschka, Christian Kirches +%% Version: 3.2 +%% Date: 2007-2017 +%% + + + %% consistency check + if ( exist( [pwd, '/make.m'],'file' ) == 0 ) + error( ['ERROR (',mfilename '.m): Run this make script directly within the directory ', ... + '/interfaces/simulink, please.'] ); + end + + + if ( nargin > 2 ) + error( ['ERROR (',mfilename '.m): At most two make arguments supported!'] ); + else + [ doClean,fcnNames,userFlags ] = analyseMakeArguments( nargin,varargin ); + end + + + %% define compiler settings + QPOASESPATH = '../../'; + + DEBUGFLAGS = ' '; + %DEBUGFLAGS = ' -g CXXDEBUGFLAGS=''$CXXDEBUGFLAGS -Wall -pedantic -Wshadow'' '; + + IFLAGS = [ '-I. -I',QPOASESPATH,'include',' -I',QPOASESPATH,'src',' ' ]; + CPPFLAGS = [ IFLAGS, DEBUGFLAGS, '-largeArrayDims -D__cpluplus -D__MATLAB__ -D__SINGLE_OBJECT__',' ' ]; + defaultFlags = '-O '; %% -D__NO_COPYRIGHT__ -D__SUPPRESSANYOUTPUT__ + + if ( ispc == 0 ) + CPPFLAGS = [ CPPFLAGS, '-DLINUX ',' ' ]; + else + CPPFLAGS = [ CPPFLAGS, '-DWIN32 ',' ' ]; + end + + if ( isempty(userFlags) > 0 ) + CPPFLAGS = [ CPPFLAGS, defaultFlags,' ' ]; + else + CPPFLAGS = [ CPPFLAGS, userFlags,' ' ]; + end + + mexExt = eval('mexext'); + + + %% ensure copyright notice is displayed + if ~isempty( strfind( CPPFLAGS,'-D__NO_COPYRIGHT__' ) ) + printCopyrightNotice( ); + end + + + %% clean if desired + if ( doClean > 0 ) + + eval( 'delete *.o;' ); + eval( ['delete *.',mexExt,'*;'] ); + disp( [ 'INFO (',mfilename '.m): Cleaned all compiled files.'] ); + pause( 0.2 ); + + end + + + if ( ~isempty(userFlags) ) + disp( [ 'INFO (',mfilename '.m): Compiling all files with user-defined compiler flags (''',userFlags,''')...'] ); + end + + + %% call mex compiler + for ii=1:length(fcnNames) + + cmd = [ 'mex -output ', fcnNames{ii}, ' ', CPPFLAGS, [fcnNames{ii},'.cpp'] ]; + + if ( exist( [fcnNames{ii},'.',mexExt],'file' ) == 0 ) + + eval( cmd ); + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' successfully created.'] ); + + else + + % check modification time of source/Make files and compiled mex file + cppFile = dir( [pwd,'/',fcnNames{ii},'.cpp'] ); + cppFileTimestamp = getTimestamp( cppFile ); + + makeFile = dir( [pwd,'/make.m'] ); + makeFileTimestamp = getTimestamp( makeFile ); + + mexFile = dir( [pwd,'/',fcnNames{ii},'.',mexExt] ); + if ( isempty(mexFile) == 0 ) + mexFileTimestamp = getTimestamp( mexFile ); + else + mexFileTimestamp = 0; + end + + if ( ( cppFileTimestamp >= mexFileTimestamp ) || ... + ( makeFileTimestamp >= mexFileTimestamp ) ) + eval( cmd ); + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' successfully created.'] ); + else + disp( [ 'INFO (',mfilename '.m): ', fcnNames{ii},'.',mexExt, ' already exists.'] ); + end + + end + + end + + %% add qpOASES directory to path + path( path,pwd ); + +end + + +function [ doClean,fcnNames,userIFlags ] = analyseMakeArguments( nArgs,args ) + + doClean = 0; + fcnNames = []; + userIFlags = []; + + switch ( nArgs ) + + case 1 + if ( strcmp( args{1},'all' ) > 0 ) + fcnNames = { 'qpOASES_QProblemB','qpOASES_QProblem','qpOASES_SQProblem' }; + elseif ( strcmp( args{1},'qpOASES_QProblemB' ) > 0 ) + fcnNames = { 'qpOASES_QProblemB' }; + elseif ( strcmp( args{1},'qpOASES_QProblem' ) > 0 ) + fcnNames = { 'qpOASES_QProblem' }; + elseif ( strcmp( args{1},'qpOASES_SQProblem' ) > 0 ) + fcnNames = { 'qpOASES_SQProblem' }; + elseif ( strcmp( args{1},'clean' ) > 0 ) + doClean = 1; + elseif ( strcmp( args{1}(1),'-' ) > 0 ) + % make clean all with user-specified compiler flags + userIFlags = args{1}; + doClean = 1; + fcnNames = { 'qpOASES_QProblemB','qpOASES_QProblem','qpOASES_SQProblem' }; + else + error( ['ERROR (',mfilename '.m): Invalid first argument (''',args{1},''')!'] ); + end + + case 2 + if ( strcmp( args{1},'clean' ) > 0 ) + doClean = 1; + else + error( ['ERROR (',mfilename '.m): First argument must be ''clean'' if two arguments are provided!'] ); + end + + if ( strcmp( args{2},'all' ) > 0 ) + fcnNames = { 'qpOASES_QProblemB','qpOASES_QProblem','qpOASES_SQProblem' }; + elseif ( strcmp( args{2},'qpOASES_QProblemB' ) > 0 ) + fcnNames = { 'qpOASES_QProblemB' }; + elseif ( strcmp( args{2},'qpOASES_QProblem' ) > 0 ) + fcnNames = { 'qpOASES_QProblem' }; + elseif ( strcmp( args{2},'qpOASES_SQProblem' ) > 0 ) + fcnNames = { 'qpOASES_SQProblem' }; + else + error( ['ERROR (',mfilename '.m): Invalid second argument (''',args{2},''')!'] ); + end + + otherwise + doClean = 0; + fcnNames = { 'qpOASES_QProblemB','qpOASES_QProblem','qpOASES_SQProblem' }; + userIFlags = []; + end + +end + + +function [ timestamp ] = getTimestamp( dateString ) + + try + timestamp = dateString.datenum; + catch + timestamp = Inf; + end + +end + + +function [ ] = printCopyrightNotice( ) + + disp( ' ' ); + disp( 'qpOASES -- An Implementation of the Online Active Set Strategy.' ); + disp( 'Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka,' ); + disp( 'Christian Kirches et al. All rights reserved.' ); + disp( ' ' ); + disp( 'qpOASES is distributed under the terms of the' ); + disp( 'GNU Lesser General Public License 2.1 in the hope that it will be' ); + disp( 'useful, but WITHOUT ANY WARRANTY; without even the implied warranty' ); + disp( 'of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.' ); + disp( 'See the GNU Lesser General Public License for more details.' ); + disp( ' ' ); + disp( ' ' ); + +end + + +%% +%% end of file +%% diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_QProblem.cpp b/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_QProblem.cpp new file mode 100644 index 0000000..1defe13 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_QProblem.cpp @@ -0,0 +1,507 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/simulink/qpOASES_QProblem.cpp + * \author Hans Joachim Ferreau (thanks to Aude Perrin) + * \version 3.2 + * \date 2007-2017 + * + * Interface for Simulink(R) that enables to call qpOASES as a S function + * (variant for QPs with fixed matrices). + * + */ + + +#include + +#include +#include "qpOASES_simulink_utils.cpp" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define S_FUNCTION_NAME qpOASES_QProblem /**< Name of the S function. */ +#define S_FUNCTION_LEVEL 2 /**< S function level. */ + +#define MDL_START /**< Activate call to mdlStart. */ + +#include "simstruc.h" + + +/* SETTINGS: */ +#define SAMPLINGTIME -1 /**< Sampling time. */ +#define NCONTROLINPUTS 2 /**< Number of control inputs. */ +#define MAXITER 100 /**< Maximum number of iterations. */ +#define HESSIANTYPE HST_UNKNOWN /**< Hessian type, see documentation of QProblem class constructor. */ + + +static void mdlInitializeSizes (SimStruct *S) /* Init sizes array */ +{ + int ii; + int nU = NCONTROLINPUTS; + + /* Specify the number of continuous and discrete states */ + ssSetNumContStates(S, 0); + ssSetNumDiscStates(S, 0); + + /* Specify the number of parameters */ + ssSetNumSFcnParams(S, 2); /* H, A */ + if ( ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S) ) + return; + + /* Specify the number of intput ports */ + if ( !ssSetNumInputPorts(S, 5) ) + return; + + /* Specify the number of output ports */ + if ( !ssSetNumOutputPorts(S, 4) ) + return; + + /* Specify dimension information for the input ports */ + ssSetInputPortVectorDimension(S, 0, DYNAMICALLY_SIZED); /* g */ + ssSetInputPortVectorDimension(S, 1, DYNAMICALLY_SIZED); /* lb */ + ssSetInputPortVectorDimension(S, 2, DYNAMICALLY_SIZED); /* ub */ + ssSetInputPortVectorDimension(S, 3, DYNAMICALLY_SIZED); /* lbA */ + ssSetInputPortVectorDimension(S, 4, DYNAMICALLY_SIZED); /* ubA */ + + /* Specify dimension information for the output ports */ + ssSetOutputPortVectorDimension(S, 0, nU ); /* uOpt */ + ssSetOutputPortVectorDimension(S, 1, 1 ); /* fval */ + ssSetOutputPortVectorDimension(S, 2, 1 ); /* exitflag */ + ssSetOutputPortVectorDimension(S, 3, 1 ); /* iter */ + + /* Specify the direct feedthrough status */ + for( ii=0; ii<5; ++ii ) + { + ssSetInputPortDirectFeedThrough(S, ii, 1); + //ssSetInputPortRequiredContiguous(S, ii, 1); + } + + /* One sample time */ + ssSetNumSampleTimes(S, 1); + + /* global variables: + * 0: problem + * 1: H + * 2: g + * 3: A + * 4: lb + * 5: ub + * 6: lbA + * 7: ubA + */ + + /* Specify the size of the block's pointer work vector */ + ssSetNumPWork(S, 8); +} + + +#if defined(MATLAB_MEX_FILE) + +#define MDL_SET_INPUT_PORT_DIMENSION_INFO +#define MDL_SET_OUTPUT_PORT_DIMENSION_INFO + +static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo) +{ + if ( !ssSetInputPortDimensionInfo(S, port, dimsInfo) ) + return; +} + +static void mdlSetOutputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo) +{ + if ( !ssSetOutputPortDimensionInfo(S, port, dimsInfo) ) + return; +} + +#endif + + +static void mdlInitializeSampleTimes(SimStruct *S) +{ + ssSetSampleTime(S, 0, SAMPLINGTIME); + ssSetOffsetTime(S, 0, 0.0); +} + + +static void mdlStart(SimStruct *S) +{ + USING_NAMESPACE_QPOASES + + int nU = NCONTROLINPUTS; + int size_g, size_lb, size_ub, size_lbA, size_ubA; + int size_H, nRows_H, nCols_H, size_A, nRows_A, nCols_A; + int nV, nC; + + QProblem* problem; + + + /* get block inputs dimensions */ + const mxArray* in_H = ssGetSFcnParam(S, 0); + const mxArray* in_A = ssGetSFcnParam(S, 1); + + if ( mxIsEmpty(in_H) == 1 ) + { + if ( ( HESSIANTYPE != HST_ZERO ) && ( HESSIANTYPE != HST_IDENTITY ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Hessian can only be empty if type is set to HST_ZERO or HST_IDENTITY!" ); + #endif + return; + } + + nRows_H = 0; + nCols_H = 0; + size_H = 0; + } + else + { + nRows_H = (int)mxGetM(in_H); + nCols_H = (int)mxGetN(in_H); + size_H = nRows_H * nCols_H; + } + + if ( mxIsEmpty(in_A) == 1 ) + { + nRows_A = 0; + nCols_A = 0; + size_A = 0; + } + else + { + nRows_A = (int)mxGetM(in_A); + nCols_A = (int)mxGetN(in_A); + size_A = nRows_A * nCols_A; + } + + size_g = ssGetInputPortWidth(S, 0); + size_lb = ssGetInputPortWidth(S, 1); + size_ub = ssGetInputPortWidth(S, 2); + size_lbA = ssGetInputPortWidth(S, 3); + size_ubA = ssGetInputPortWidth(S, 4); + + + /* dimension checks */ + nV = size_g; + nC = nRows_A; + + + if ( MAXITER < 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Maximum number of iterations must not be negative!" ); + #endif + return; + } + + if ( nV <= 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" ); + #endif + return; + } + + if ( ( size_H != nV*nV ) && ( size_H != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in H!" ); + #endif + return; + } + + if ( nRows_H != nCols_H ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Hessian matrix must be square matrix!" ); + #endif + return; + } + + if ( ( nU < 1 ) || ( nU > nV ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Invalid number of control inputs!" ); + #endif + return; + } + + if ( ( size_lb != nV ) && ( size_lb != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in lb!" ); + #endif + return; + } + + if ( ( size_ub != nV ) && ( size_lb != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in ub!" ); + #endif + return; + } + + if ( ( size_lbA != nC ) && ( size_lbA != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in lbA!" ); + #endif + return; + } + + if ( ( size_ubA != nC ) && ( size_ubA != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in ubA!" ); + #endif + return; + } + + + /* allocate QProblem object */ + problem = new QProblem( nV,nC,HESSIANTYPE ); + if ( problem == 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Unable to create QProblem object!" ); + #endif + return; + } + + Options problemOptions; + problemOptions.setToMPC(); + problem->setOptions( problemOptions ); + + #ifndef __DEBUG__ + problem->setPrintLevel( PL_LOW ); + #endif + #ifdef __SUPPRESSANYOUTPUT__ + problem->setPrintLevel( PL_NONE ); + #endif + + ssGetPWork(S)[0] = (void *) problem; + + /* allocate memory for QP data ... */ + if ( size_H > 0 ) + ssGetPWork(S)[1] = (void *) calloc( size_H, sizeof(real_t) ); /* H */ + else + ssGetPWork(S)[1] = 0; + + ssGetPWork(S)[2] = (void *) calloc( size_g, sizeof(real_t) ); /* g */ + ssGetPWork(S)[3] = (void *) calloc( size_A, sizeof(real_t) ); /* A */ + + if ( size_lb > 0 ) + ssGetPWork(S)[4] = (void *) calloc( size_lb, sizeof(real_t) ); /* lb */ + else + ssGetPWork(S)[4] = 0; + + if ( size_ub > 0 ) + ssGetPWork(S)[5] = (void *) calloc( size_ub, sizeof(real_t) ); /* ub */ + else + ssGetPWork(S)[5] = 0; + + if ( size_lbA > 0 ) + ssGetPWork(S)[6] = (void *) calloc( size_lbA, sizeof(real_t) ); /* lbA */ + else + ssGetPWork(S)[6] = 0; + + if ( size_ubA > 0 ) + ssGetPWork(S)[7] = (void *) calloc( size_ubA, sizeof(real_t) ); /* ubA */ + else + ssGetPWork(S)[7] = 0; +} + + +static void mdlOutputs(SimStruct *S, int_T tid) +{ + USING_NAMESPACE_QPOASES + + int ii; + int nV, nC; + returnValue status; + + int_t nWSR = MAXITER; + int nU = NCONTROLINPUTS; + + InputRealPtrsType in_g, in_lb, in_ub, in_lbA, in_ubA; + + QProblem* problem; + real_t *H, *g, *A, *lb, *ub, *lbA, *ubA; + + real_t *xOpt; + + real_T *out_uOpt, *out_objVal, *out_status, *out_nWSR; + + + /* get pointers to block inputs ... */ + const mxArray* in_H = ssGetSFcnParam(S, 0); + const mxArray* in_A = ssGetSFcnParam(S, 1); + in_g = ssGetInputPortRealSignalPtrs(S, 0); + in_lb = ssGetInputPortRealSignalPtrs(S, 1); + in_ub = ssGetInputPortRealSignalPtrs(S, 2); + in_lbA = ssGetInputPortRealSignalPtrs(S, 3); + in_ubA = ssGetInputPortRealSignalPtrs(S, 4); + + + /* ... and to the QP data */ + problem = (QProblem*)(ssGetPWork(S)[0]); + + H = (real_t *) ssGetPWork(S)[1]; + g = (real_t *) ssGetPWork(S)[2]; + A = (real_t *) ssGetPWork(S)[3]; + lb = (real_t *) ssGetPWork(S)[4]; + ub = (real_t *) ssGetPWork(S)[5]; + lbA = (real_t *) ssGetPWork(S)[6]; + ubA = (real_t *) ssGetPWork(S)[7]; + + + /* setup QP data */ + nV = ssGetInputPortWidth(S, 0); /* nV = size_g */ + nC = (int)mxGetM(in_A); /* nC = nRows_A*/ + + if ( H != 0 ) + { + /* no conversion from FORTRAN to C as Hessian is symmetric! */ + for ( ii=0; iigetCount() == 0 ) + { + /* initialise and solve first QP */ + status = problem->init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + problem->getPrimalSolution( xOpt ); + } + else + { + /* solve neighbouring QP using hotstart technique */ + status = problem->hotstart( g,lb,ub,lbA,ubA, nWSR,0 ); + if ( ( status != SUCCESSFUL_RETURN ) && ( status != RET_MAX_NWSR_REACHED ) ) + { + /* if an error occurs, reset problem data structures ... */ + problem->reset( ); + + /* ... and initialise/solve again with remaining number of iterations. */ + int_t nWSR_retry = MAXITER - nWSR; + status = problem->init( H,g,A,lb,ub,lbA,ubA, nWSR_retry,0 ); + nWSR += nWSR_retry; + + } + + /* obtain optimal solution */ + problem->getPrimalSolution( xOpt ); + } + + /* generate block output: status information ... */ + out_uOpt = ssGetOutputPortRealSignal(S, 0); + out_objVal = ssGetOutputPortRealSignal(S, 1); + out_status = ssGetOutputPortRealSignal(S, 2); + out_nWSR = ssGetOutputPortRealSignal(S, 3); + + for ( ii=0; iigetObjVal()); + out_status[0] = (real_t)(getSimpleStatus( status )); + out_nWSR[0] = (real_T)(nWSR); + + removeNaNs( out_uOpt,nU ); + removeInfs( out_uOpt,nU ); + removeNaNs( out_objVal,1 ); + removeInfs( out_objVal,1 ); + + delete[] xOpt; +} + + +static void mdlTerminate(SimStruct *S) +{ + USING_NAMESPACE_QPOASES + + int ii; + + /* reset global message handler */ + getGlobalMessageHandler( )->reset( ); + + if ( ssGetPWork(S)[0] != 0 ) + delete ((QProblem*)(ssGetPWork(S)[0])); + + for ( ii=1; ii<8; ++ii ) + { + if ( ssGetPWork(S)[ii] != 0 ) + free( ssGetPWork(S)[ii] ); + } +} + + +#ifdef MATLAB_MEX_FILE +#include "simulink.c" +#else +#include "cg_sfun.h" +#endif + + +#ifdef __cplusplus +} +#endif + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_QProblemB.cpp b/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_QProblemB.cpp new file mode 100644 index 0000000..8a0c401 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_QProblemB.cpp @@ -0,0 +1,434 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/simulink/qpOASES_QProblemB.cpp + * \author Hans Joachim Ferreau (thanks to Aude Perrin) + * \version 3.2 + * \date 2007-2017 + * + * Interface for Simulink(R) that enables to call qpOASES as a S function + * (variant for simply bounded QPs with fixed matrices). + * + */ + + +#include + +#include +#include "qpOASES_simulink_utils.cpp" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define S_FUNCTION_NAME qpOASES_QProblemB /**< Name of the S function. */ +#define S_FUNCTION_LEVEL 2 /**< S function level. */ + +#define MDL_START /**< Activate call to mdlStart. */ + +#include "simstruc.h" + + +/* SETTINGS */ +#define SAMPLINGTIME -1 /**< Sampling time. */ +#define NCONTROLINPUTS 2 /**< Number of control inputs. */ +#define MAXITER 100 /**< Maximum number of iteration. */ +#define HESSIANTYPE HST_UNKNOWN /**< Hessian type, see documentation of QProblemB class constructor. */ + + +static void mdlInitializeSizes (SimStruct *S) /* Init sizes array */ +{ + int ii; + int nU = NCONTROLINPUTS; + + /* Specify the number of continuous and discrete states */ + ssSetNumContStates(S, 0); + ssSetNumDiscStates(S, 0); + + /* Specify the number of parameters */ + ssSetNumSFcnParams(S, 1); /* H */ + if ( ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S) ) + return; + + /* Specify the number of intput ports */ + if ( !ssSetNumInputPorts(S, 3) ) + return; + + /* Specify the number of output ports */ + if ( !ssSetNumOutputPorts(S, 4) ) + return; + + /* Specify dimension information for the input ports */ + ssSetInputPortVectorDimension(S, 0, DYNAMICALLY_SIZED); /* g */ + ssSetInputPortVectorDimension(S, 1, DYNAMICALLY_SIZED); /* lb */ + ssSetInputPortVectorDimension(S, 2, DYNAMICALLY_SIZED); /* ub */ + + /* Specify dimension information for the output ports */ + ssSetOutputPortVectorDimension(S, 0, nU ); /* uOpt */ + ssSetOutputPortVectorDimension(S, 1, 1 ); /* fval */ + ssSetOutputPortVectorDimension(S, 2, 1 ); /* exitflag */ + ssSetOutputPortVectorDimension(S, 3, 1 ); /* iter */ + + /* Specify the direct feedthrough status */ + for( ii=0; ii<3; ++ii ) + { + ssSetInputPortDirectFeedThrough(S, ii, 1); + //ssSetInputPortRequiredContiguous(S, ii, 1); + } + + /* One sample time */ + ssSetNumSampleTimes(S, 1); + + /* global variables: + * 0: problem + * 1: H + * 2: g + * 3: lb + * 4: ub + */ + + /* Specify the size of the block's pointer work vector */ + ssSetNumPWork(S, 5); +} + + +#if defined(MATLAB_MEX_FILE) + +#define MDL_SET_INPUT_PORT_DIMENSION_INFO +#define MDL_SET_OUTPUT_PORT_DIMENSION_INFO + +static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo) +{ + if ( !ssSetInputPortDimensionInfo(S, port, dimsInfo) ) + return; +} + +static void mdlSetOutputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo) +{ + if ( !ssSetOutputPortDimensionInfo(S, port, dimsInfo) ) + return; +} + +#endif + + +static void mdlInitializeSampleTimes(SimStruct *S) +{ + ssSetSampleTime(S, 0, SAMPLINGTIME); + ssSetOffsetTime(S, 0, 0.0); +} + + +static void mdlStart(SimStruct *S) +{ + USING_NAMESPACE_QPOASES + + int nU = NCONTROLINPUTS; + int size_g, size_lb, size_ub; + int size_H, nRows_H, nCols_H; + int nV; + + QProblemB* problem; + + + /* get block inputs dimensions */ + const mxArray* in_H = ssGetSFcnParam(S, 0); + + if ( mxIsEmpty(in_H) == 1 ) + { + if ( ( HESSIANTYPE != HST_ZERO ) && ( HESSIANTYPE != HST_IDENTITY ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Hessian can only be empty if type is set to HST_ZERO or HST_IDENTITY!" ); + #endif + return; + } + + nRows_H = 0; + nCols_H = 0; + size_H = 0; + } + else + { + nRows_H = (int)mxGetM(in_H); + nCols_H = (int)mxGetN(in_H); + size_H = nRows_H * nCols_H; + } + + size_g = ssGetInputPortWidth(S, 0); + size_lb = ssGetInputPortWidth(S, 1); + size_ub = ssGetInputPortWidth(S, 2); + + + /* dimension checks */ + nV = size_g; + + if ( MAXITER < 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Maximum number of iterations must not be negative!" ); + #endif + return; + } + + if ( nV <= 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" ); + #endif + return; + } + + if ( ( size_H != nV*nV ) && ( size_H != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in H!" ); + #endif + return; + } + + if ( nRows_H != nCols_H ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Hessian matrix must be square matrix!" ); + #endif + return; + } + + if ( ( nU < 1 ) || ( nU > nV ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Invalid number of control inputs!" ); + #endif + return; + } + + if ( ( size_lb != nV ) && ( size_lb != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in lb!" ); + #endif + return; + } + + if ( ( size_ub != nV ) && ( size_ub != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in ub!" ); + #endif + return; + } + + + /* allocate QProblemB object */ + problem = new QProblemB( nV,HESSIANTYPE ); + if ( problem == 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Unable to create QProblemB object!" ); + #endif + return; + } + + Options problemOptions; + problemOptions.setToMPC(); + problem->setOptions( problemOptions ); + + #ifndef __DEBUG__ + problem->setPrintLevel( PL_LOW ); + #endif + #ifdef __SUPPRESSANYOUTPUT__ + problem->setPrintLevel( PL_NONE ); + #endif + + ssGetPWork(S)[0] = (void *) problem; + + /* allocate memory for QP data ... */ + if ( size_H > 0 ) + ssGetPWork(S)[1] = (void *) calloc( size_H, sizeof(real_t) ); /* H */ + else + ssGetPWork(S)[1] = 0; + + ssGetPWork(S)[2] = (void *) calloc( size_g, sizeof(real_t) ); /* g */ + + if ( size_lb > 0 ) + ssGetPWork(S)[3] = (void *) calloc( size_lb, sizeof(real_t) ); /* lb */ + else + ssGetPWork(S)[3] = 0; + + if ( size_ub > 0 ) + ssGetPWork(S)[4] = (void *) calloc( size_ub, sizeof(real_t) ); /* ub */ + else + ssGetPWork(S)[4] = 0; +} + + +static void mdlOutputs(SimStruct *S, int_T tid) +{ + USING_NAMESPACE_QPOASES + + int ii; + int nV; + returnValue status; + + int_t nWSR = MAXITER; + int nU = NCONTROLINPUTS; + + InputRealPtrsType in_g, in_lb, in_ub; + + QProblemB* problem; + real_t *H, *g, *lb, *ub; + + real_t *xOpt; + + real_T *out_uOpt, *out_objVal, *out_status, *out_nWSR; + + + /* get pointers to block inputs ... */ + const mxArray* in_H = ssGetSFcnParam(S, 0); + in_g = ssGetInputPortRealSignalPtrs(S, 0); + in_lb = ssGetInputPortRealSignalPtrs(S, 1); + in_ub = ssGetInputPortRealSignalPtrs(S, 2); + + /* ... and to the QP data */ + problem = (QProblemB*) ssGetPWork(S)[0]; + + H = (real_t *) ssGetPWork(S)[1]; + g = (real_t *) ssGetPWork(S)[2]; + lb = (real_t *) ssGetPWork(S)[3]; + ub = (real_t *) ssGetPWork(S)[4]; + + + /* setup QP data */ + nV = ssGetInputPortWidth(S, 1); /* nV = size_g */ + + if ( H != 0 ) + { + /* no conversion from FORTRAN to C as Hessian is symmetric! */ + for ( ii=0; iigetCount() == 0 ) + { + /* initialise and solve first QP */ + status = problem->init( H,g,lb,ub, nWSR,0 ); + problem->getPrimalSolution( xOpt ); + } + else + { + /* solve neighbouring QP using hotstart technique */ + status = problem->hotstart( g,lb,ub, nWSR,0 ); + if ( ( status != SUCCESSFUL_RETURN ) && ( status != RET_MAX_NWSR_REACHED ) ) + { + /* if an error occurs, reset problem data structures ... */ + problem->reset( ); + + /* ... and initialise/solve again with remaining number of iterations. */ + int_t nWSR_retry = MAXITER - nWSR; + status = problem->init( H,g,lb,ub, nWSR_retry,0 ); + nWSR += nWSR_retry; + } + + /* obtain optimal solution */ + problem->getPrimalSolution( xOpt ); + } + + /* generate block output: status information ... */ + out_uOpt = ssGetOutputPortRealSignal(S, 0); + out_objVal = ssGetOutputPortRealSignal(S, 1); + out_status = ssGetOutputPortRealSignal(S, 2); + out_nWSR = ssGetOutputPortRealSignal(S, 3); + + for ( ii=0; iigetObjVal()); + out_status[0] = (real_t)(getSimpleStatus( status )); + out_nWSR[0] = (real_T)(nWSR); + + removeNaNs( out_uOpt,nU ); + removeInfs( out_uOpt,nU ); + removeNaNs( out_objVal,1 ); + removeInfs( out_objVal,1 ); + + delete[] xOpt; +} + + +static void mdlTerminate(SimStruct *S) +{ + USING_NAMESPACE_QPOASES + + int ii; + + /* reset global message handler */ + getGlobalMessageHandler( )->reset( ); + + if ( ssGetPWork(S)[0] != 0 ) + delete ((QProblemB*)(ssGetPWork(S)[0])); + + for ( ii=1; ii<5; ++ii ) + { + if ( ssGetPWork(S)[ii] != 0 ) + free( ssGetPWork(S)[ii] ); + } +} + + +#ifdef MATLAB_MEX_FILE +#include "simulink.c" +#else +#include "cg_sfun.h" +#endif + + +#ifdef __cplusplus +} +#endif + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_SQProblem.cpp b/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_SQProblem.cpp new file mode 100644 index 0000000..8f1fd95 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_SQProblem.cpp @@ -0,0 +1,474 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/simulink/qpOASES_SQProblem.cpp + * \author Hans Joachim Ferreau (thanks to Aude Perrin) + * \version 3.2 + * \date 2007-2017 + * + * Interface for Simulink(R) that enables to call qpOASES as a S function + * (variant for QPs with varying matrices). + * + */ + + +#include + +#include +#include "qpOASES_simulink_utils.cpp" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define S_FUNCTION_NAME qpOASES_SQProblem /**< Name of the S function. */ +#define S_FUNCTION_LEVEL 2 /**< S function level. */ + +#define MDL_START /**< Activate call to mdlStart. */ + +#include "simstruc.h" + + +/* SETTINGS */ +#define SAMPLINGTIME -1 /**< Sampling time. */ +#define NCONTROLINPUTS 2 /**< Number of control inputs. */ +#define MAXITER 100 /**< Maximum number of iterations. */ +#define HESSIANTYPE HST_UNKNOWN /**< Hessian type, see documentation of SQProblem class constructor. */ + + +static void mdlInitializeSizes (SimStruct *S) /* Init sizes array */ +{ + int ii; + int nU = NCONTROLINPUTS; + + /* Specify the number of continuous and discrete states */ + ssSetNumContStates(S, 0); + ssSetNumDiscStates(S, 0); + + /* Specify the number of parameters */ + ssSetNumSFcnParams(S, 0); + if ( ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S) ) + return; + + /* Specify the number of intput ports */ + if ( !ssSetNumInputPorts(S, 7) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Invalid number of input ports!" ); + #endif + return; + } + + /* Specify the number of output ports */ + if ( !ssSetNumOutputPorts(S, 4) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Invalid number of output ports!" ); + #endif + return; + } + + /* Specify dimension information for the input ports */ + ssSetInputPortVectorDimension(S, 0, DYNAMICALLY_SIZED); /* H */ + ssSetInputPortVectorDimension(S, 1, DYNAMICALLY_SIZED); /* g */ + ssSetInputPortVectorDimension(S, 2, DYNAMICALLY_SIZED); /* A */ + ssSetInputPortVectorDimension(S, 3, DYNAMICALLY_SIZED); /* lb */ + ssSetInputPortVectorDimension(S, 4, DYNAMICALLY_SIZED); /* ub */ + ssSetInputPortVectorDimension(S, 5, DYNAMICALLY_SIZED); /* lbA */ + ssSetInputPortVectorDimension(S, 6, DYNAMICALLY_SIZED); /* ubA */ + + /* Specify dimension information for the output ports */ + ssSetOutputPortVectorDimension(S, 0, nU ); /* uOpt */ + ssSetOutputPortVectorDimension(S, 1, 1 ); /* fval */ + ssSetOutputPortVectorDimension(S, 2, 1 ); /* exitflag */ + ssSetOutputPortVectorDimension(S, 3, 1 ); /* iter */ + + /* Specify the direct feedthrough status */ + for( ii=0; ii<7; ++ii ) + { + ssSetInputPortDirectFeedThrough(S, ii, 1); + //ssSetInputPortRequiredContiguous(S, ii, 1); + } + + /* One sample time */ + ssSetNumSampleTimes(S, 1); + + /* global variables: + * 0: problem + * 1: H + * 2: g + * 3: A + * 4: lb + * 5: ub + * 6: lbA + * 7: ubA + */ + + /* Specify the size of the block's pointer work vector */ + ssSetNumPWork(S, 8); +} + + +#if defined(MATLAB_MEX_FILE) + +#define MDL_SET_INPUT_PORT_DIMENSION_INFO +#define MDL_SET_OUTPUT_PORT_DIMENSION_INFO + +static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo) +{ + if ( !ssSetInputPortDimensionInfo(S, port, dimsInfo) ) + return; +} + +static void mdlSetOutputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo) +{ + if ( !ssSetOutputPortDimensionInfo(S, port, dimsInfo) ) + return; +} + +#endif + + +static void mdlInitializeSampleTimes(SimStruct *S) +{ + ssSetSampleTime(S, 0, SAMPLINGTIME); + ssSetOffsetTime(S, 0, 0.0); +} + + +static void mdlStart(SimStruct *S) +{ + USING_NAMESPACE_QPOASES + + int nU = NCONTROLINPUTS; + int size_H, size_g, size_A, size_lb, size_ub, size_lbA, size_ubA; + int nV, nC; + + SQProblem* problem; + + + /* get block inputs dimensions */ + size_H = ssGetInputPortWidth(S, 0); + size_g = ssGetInputPortWidth(S, 1); + size_A = ssGetInputPortWidth(S, 2); + size_lb = ssGetInputPortWidth(S, 3); + size_ub = ssGetInputPortWidth(S, 4); + size_lbA = ssGetInputPortWidth(S, 5); + size_ubA = ssGetInputPortWidth(S, 6); + + + /* dimension checks */ + nV = size_g; + nC = (int) ( ((real_t) size_A) / ((real_t) nV) ); + + if ( MAXITER < 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Maximum number of iterations must not be negative!" ); + #endif + return; + } + + if ( nV <= 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" ); + #endif + return; + } + + if ( ( size_H != nV*nV ) && ( size_H != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in H!" ); + #endif + return; + } + + if ( ( nU < 1 ) || ( nU > nV ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Invalid number of control inputs!" ); + #endif + return; + } + + if ( ( size_lb != nV ) && ( size_lb != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in lb!" ); + #endif + return; + } + + if ( ( size_ub != nV ) && ( size_ub != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in ub!" ); + #endif + return; + } + + if ( ( size_lbA != nC ) && ( size_lbA != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in lbA!" ); + #endif + return; + } + + if ( ( size_ubA != nC ) && ( size_ubA != 0 ) ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in ubA!" ); + #endif + return; + } + + + /* allocate QProblem object */ + problem = new SQProblem( nV,nC,HESSIANTYPE ); + if ( problem == 0 ) + { + #ifndef __SUPPRESSANYOUTPUT__ + mexErrMsgTxt( "ERROR (qpOASES): Unable to create SQProblem object!" ); + #endif + return; + } + + Options problemOptions; + problemOptions.setToMPC(); + problem->setOptions( problemOptions ); + + #ifndef __DEBUG__ + problem->setPrintLevel( PL_LOW ); + #endif + #ifdef __SUPPRESSANYOUTPUT__ + problem->setPrintLevel( PL_NONE ); + #endif + + ssGetPWork(S)[0] = (void *) problem; + + /* allocate memory for QP data ... */ + if ( size_H > 0 ) + ssGetPWork(S)[1] = (void *) calloc( size_H, sizeof(real_t) ); /* H */ + else + ssGetPWork(S)[1] = 0; + + ssGetPWork(S)[2] = (void *) calloc( size_g, sizeof(real_t) ); /* g */ + ssGetPWork(S)[3] = (void *) calloc( size_A, sizeof(real_t) ); /* A */ + + if ( size_lb > 0 ) + ssGetPWork(S)[4] = (void *) calloc( size_lb, sizeof(real_t) ); /* lb */ + else + ssGetPWork(S)[4] = 0; + + if ( size_ub > 0 ) + ssGetPWork(S)[5] = (void *) calloc( size_ub, sizeof(real_t) ); /* ub */ + else + ssGetPWork(S)[5] = 0; + + if ( size_lbA > 0 ) + ssGetPWork(S)[6] = (void *) calloc( size_lbA, sizeof(real_t) ); /* lbA */ + else + ssGetPWork(S)[6] = 0; + + if ( size_ubA > 0 ) + ssGetPWork(S)[7] = (void *) calloc( size_ubA, sizeof(real_t) ); /* ubA */ + else + ssGetPWork(S)[7] = 0; +} + + + +static void mdlOutputs(SimStruct *S, int_T tid) +{ + USING_NAMESPACE_QPOASES + + int ii; + int nV, nC; + returnValue status; + + int_t nWSR = MAXITER; + int nU = NCONTROLINPUTS; + + InputRealPtrsType in_H, in_g, in_A, in_lb, in_ub, in_lbA, in_ubA; + + SQProblem* problem; + real_t *H, *g, *A, *lb, *ub, *lbA, *ubA; + + real_t *xOpt; + + real_T *out_uOpt, *out_objVal, *out_status, *out_nWSR; + + + /* get pointers to block inputs ... */ + in_H = ssGetInputPortRealSignalPtrs(S, 0); + in_g = ssGetInputPortRealSignalPtrs(S, 1); + in_A = ssGetInputPortRealSignalPtrs(S, 2); + in_lb = ssGetInputPortRealSignalPtrs(S, 3); + in_ub = ssGetInputPortRealSignalPtrs(S, 4); + in_lbA = ssGetInputPortRealSignalPtrs(S, 5); + in_ubA = ssGetInputPortRealSignalPtrs(S, 6); + + + /* ... and to the QP data */ + problem = (SQProblem*) ssGetPWork(S)[0]; + + H = (real_t *) ssGetPWork(S)[1]; + g = (real_t *) ssGetPWork(S)[2]; + A = (real_t *) ssGetPWork(S)[3]; + lb = (real_t *) ssGetPWork(S)[4]; + ub = (real_t *) ssGetPWork(S)[5]; + lbA = (real_t *) ssGetPWork(S)[6]; + ubA = (real_t *) ssGetPWork(S)[7]; + + + /* setup QP data */ + nV = ssGetInputPortWidth(S, 1); /* nV = size_g */ + nC = (int) ( ((real_t) ssGetInputPortWidth(S, 2)) / ((real_t) nV) ); /* nC = size_A / size_g */ + + if ( H != 0 ) + { + /* no conversion from FORTRAN to C as Hessian is symmetric! */ + for ( ii=0; iigetCount() == 0 ) + { + /* initialise and solve first QP */ + status = problem->init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + problem->getPrimalSolution( xOpt ); + } + else + { + /* solve neighbouring QP using hotstart technique */ + status = problem->hotstart( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + if ( ( status != SUCCESSFUL_RETURN ) && ( status != RET_MAX_NWSR_REACHED ) ) + { + /* if an error occurs, reset problem data structures ... */ + problem->reset( ); + + /* ... and initialise/solve again with remaining number of iterations. */ + int_t nWSR_retry = MAXITER - nWSR; + status = problem->init( H,g,A,lb,ub,lbA,ubA, nWSR_retry,0 ); + nWSR += nWSR_retry; + } + + /* obtain optimal solution */ + problem->getPrimalSolution( xOpt ); + } + + /* generate block output: status information ... */ + out_uOpt = ssGetOutputPortRealSignal(S, 0); + out_objVal = ssGetOutputPortRealSignal(S, 1); + out_status = ssGetOutputPortRealSignal(S, 2); + out_nWSR = ssGetOutputPortRealSignal(S, 3); + + for ( ii=0; iigetObjVal( )); + out_status[0] = (real_t)(getSimpleStatus( status )); + out_nWSR[0] = (real_T)(nWSR); + + removeNaNs( out_uOpt,nU ); + removeInfs( out_uOpt,nU ); + removeNaNs( out_objVal,1 ); + removeInfs( out_objVal,1 ); + + delete[] xOpt; +} + + +static void mdlTerminate(SimStruct *S) +{ + USING_NAMESPACE_QPOASES + + int ii; + + /* reset global message handler */ + getGlobalMessageHandler( )->reset( ); + + if ( ssGetPWork(S)[0] != 0 ) + delete ((SQProblem*)(ssGetPWork(S)[0])); + + for ( ii=1; ii<8; ++ii ) + { + if ( ssGetPWork(S)[ii] != 0 ) + free( ssGetPWork(S)[ii] ); + } +} + + +#ifdef MATLAB_MEX_FILE +#include "simulink.c" +#else +#include "cg_sfun.h" +#endif + + +#ifdef __cplusplus +} +#endif + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_simulink_utils.cpp b/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_simulink_utils.cpp new file mode 100644 index 0000000..72afc76 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/interfaces/simulink/qpOASES_simulink_utils.cpp @@ -0,0 +1,121 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file interfaces/simulink/qpOASES_simulink_utils.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Collects utility functions for Interface to Simulink(R) that + * enables to call qpOASES as a C S function. + * + */ + +#ifndef __SINGLE_OBJECT__ +#include +#endif + + +USING_NAMESPACE_QPOASES + + +/* + * i s N a N + */ +BooleanType isNaN( real_t val ) +{ + if ( (( val <= 0.0 ) || ( val >= 0.0 )) == 0 ) + return BT_TRUE; + else + return BT_FALSE; +} + + +/* + * r e m o v e N a N s + */ +returnValue removeNaNs( real_t* const data, unsigned int dim ) +{ + unsigned int i; + + if ( data == 0 ) + return RET_INVALID_ARGUMENTS; + + for ( i=0; i INFTY ) + data[i] = INFTY; + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * c o n v e r t F o r t r a n T o C + */ +returnValue convertFortranToC( const real_t* const M_for, int nV, int nC, real_t* const M ) +{ + int i,j; + + if ( ( M_for == 0 ) || ( M == 0 ) ) + return RET_INVALID_ARGUMENTS; + + if ( ( nV < 0 ) || ( nC < 0 ) ) + return RET_INVALID_ARGUMENTS; + + for ( i=0; i. + + + +@PACKAGE_INIT@ + +set(qpOASES_VERSION @PACKAGE_VERSION@) + + +set_and_check(qpOASES_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") + + +set(qpOASES_INCLUDE_DIR "${qpOASES_INCLUDE_DIR}" CACHE STRING "Include path for qpOASES and its dependencies") +set_and_check(qpOASES_LIBRARY_DIR @PACKAGE_LIB_INSTALL_DIR@) +set(qpOASES_LIBRARY_DIR "${qpOASES_LIBRARY_DIR}" CACHE STRING "Library path for qpOASES and its dependencies") + +find_library(qpOASES_LIBRARY NAMES qpOASES + PATHS ${qpOASES_LIBRARY_DIR} NO_DEFAULT_PATH) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(qpOASES DEFAULT_MSG qpOASES_INCLUDE_DIR qpOASES_LIBRARY_DIR qpOASES_LIBRARY qpOASES_VERSION) \ No newline at end of file diff --git a/locomotion/src/third_party/qpOASES/src/BLASReplacement.cpp b/locomotion/src/third_party/qpOASES/src/BLASReplacement.cpp new file mode 100644 index 0000000..b32ee98 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/BLASReplacement.cpp @@ -0,0 +1,152 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/BLASReplacement.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * BLAS Level 3 replacement routines. + */ + + +#include +#include + + +extern "C" void DGEMM( const char* TRANSA, const char* TRANSB, + const la_uint_t* M, const la_uint_t* N, const la_uint_t* K, + const double* ALPHA, const double* A, const la_uint_t* LDA, const double* B, const la_uint_t* LDB, + const double* BETA, double* C, const la_uint_t* LDC + ) +{ + la_uint_t i, j, k; + + if ( REFER_NAMESPACE_QPOASES isZero(*BETA) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + C[j+(*LDC)*k] = 0.0; + else if ( REFER_NAMESPACE_QPOASES isEqual(*BETA,-1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + C[j+(*LDC)*k] = -C[j+(*LDC)*k]; + else if ( REFER_NAMESPACE_QPOASES isEqual(*BETA,1.0) == REFER_NAMESPACE_QPOASES BT_FALSE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + C[j+(*LDC)*k] *= *BETA; + + if (TRANSA[0] == 'N') + if ( REFER_NAMESPACE_QPOASES isEqual(*ALPHA,1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] += A[j+(*LDA)*i] * B[i+(*LDB)*k]; + else if ( REFER_NAMESPACE_QPOASES isEqual(*ALPHA,-1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] -= A[j+(*LDA)*i] * B[i+(*LDB)*k]; + else + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] += *ALPHA * A[j+(*LDA)*i] * B[i+(*LDB)*k]; + else + if ( REFER_NAMESPACE_QPOASES isEqual(*ALPHA,1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] += A[i+(*LDA)*j] * B[i+(*LDB)*k]; + else if ( REFER_NAMESPACE_QPOASES isEqual(*ALPHA,-1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] -= A[i+(*LDA)*j] * B[i+(*LDB)*k]; + else + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] += *ALPHA * A[i+(*LDA)*j] * B[i+(*LDB)*k]; +} + +extern "C" void SGEMM( const char* TRANSA, const char* TRANSB, + const la_uint_t* M, const la_uint_t* N, const la_uint_t* K, + const float* ALPHA, const float* A, const la_uint_t* LDA, const float* B, const la_uint_t* LDB, + const float* BETA, float* C, const la_uint_t* LDC + ) +{ + la_uint_t i, j, k; + + if ( REFER_NAMESPACE_QPOASES isZero(*BETA) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + C[j+(*LDC)*k] = 0.0; + else if ( REFER_NAMESPACE_QPOASES isEqual(*BETA,-1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + C[j+(*LDC)*k] = -C[j+(*LDC)*k]; + else if ( REFER_NAMESPACE_QPOASES isEqual(*BETA,1.0) == REFER_NAMESPACE_QPOASES BT_FALSE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + C[j+(*LDC)*k] *= *BETA; + + if (TRANSA[0] == 'N') + if ( REFER_NAMESPACE_QPOASES isEqual(*ALPHA,1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] += A[j+(*LDA)*i] * B[i+(*LDB)*k]; + else if ( REFER_NAMESPACE_QPOASES isEqual(*ALPHA,-1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] -= A[j+(*LDA)*i] * B[i+(*LDB)*k]; + else + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] += *ALPHA * A[j+(*LDA)*i] * B[i+(*LDB)*k]; + else + if ( REFER_NAMESPACE_QPOASES isEqual(*ALPHA,1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] += A[i+(*LDA)*j] * B[i+(*LDB)*k]; + else if ( REFER_NAMESPACE_QPOASES isEqual(*ALPHA,-1.0) == REFER_NAMESPACE_QPOASES BT_TRUE ) + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] -= A[i+(*LDA)*j] * B[i+(*LDB)*k]; + else + for (k = 0; k < *N; k++) + for (j = 0; j < *M; j++) + for (i = 0; i < *K; i++) + C[j+(*LDC)*k] += *ALPHA * A[i+(*LDA)*j] * B[i+(*LDB)*k]; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/Bounds.cpp b/locomotion/src/third_party/qpOASES/src/Bounds.cpp new file mode 100644 index 0000000..e10faed --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/Bounds.cpp @@ -0,0 +1,514 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/Bounds.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the Bounds class designed to manage working sets of + * bounds within a QProblem. + */ + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * B o u n d s + */ +Bounds::Bounds( ) : SubjectTo( ) +{ +} + + +/* + * B o u n d s + */ +Bounds::Bounds( int_t _n ) : SubjectTo( _n ) +{ + init( _n ); +} + + +/* + * B o u n d s + */ +Bounds::Bounds( const Bounds& rhs ) : SubjectTo( rhs ) +{ + copy( rhs ); +} + + +/* + * ~ B o u n d s + */ +Bounds::~Bounds( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +Bounds& Bounds::operator=( const Bounds& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + SubjectTo::operator=( rhs ); + copy( rhs ); + } + + return *this; +} + + + +/* + * i n i t + */ +returnValue Bounds::init( int_t _n + ) +{ + if ( _n < 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + clear( ); + + if ( _n >= 0 ) + { + freee.init( _n ); + fixed.init( _n ); + } + + return SubjectTo::init( _n ); +} + + + +/* + * s e t u p B o u n d + */ +returnValue Bounds::setupBound( int_t number, SubjectToStatus _status + ) +{ + /* consistency check */ + if ( ( number < 0 ) || ( number >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + /* Add bound index to respective index list. */ + switch ( _status ) + { + case ST_INACTIVE: + if ( this->addIndex( this->getFree( ),number,_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_BOUND_FAILED ); + break; + + case ST_LOWER: + if ( this->addIndex( this->getFixed( ),number,_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_BOUND_FAILED ); + break; + + case ST_UPPER: + if ( this->addIndex( this->getFixed( ),number,_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_BOUND_FAILED ); + break; + + default: + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p A l l F r e e + */ +returnValue Bounds::setupAllFree( ) +{ + return setupAll( ST_INACTIVE ); +} + + +/* + * s e t u p A l l L o w e r + */ +returnValue Bounds::setupAllLower( ) +{ + return setupAll( ST_LOWER ); +} + + +/* + * s e t u p A l l U p p e r + */ +returnValue Bounds::setupAllUpper( ) +{ + return setupAll( ST_UPPER ); +} + + +/* + * m o v e F i x e d T o F r e e + */ +returnValue Bounds::moveFixedToFree( int_t number ) +{ + /* consistency check */ + if ( ( number < 0 ) || ( number >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + /* Move index from indexlist of fixed variables to that of free ones. */ + if ( this->removeIndex( this->getFixed( ),number ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_MOVING_BOUND_FAILED ); + + if ( this->addIndex( this->getFree( ),number,ST_INACTIVE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_MOVING_BOUND_FAILED ); + + return SUCCESSFUL_RETURN; +} + + +/* + * m o v e F r e e T o F i x e d + */ +returnValue Bounds::moveFreeToFixed( int_t number, SubjectToStatus _status + ) +{ + /* consistency check */ + if ( ( number < 0 ) || ( number >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + /* Move index from indexlist of free variables to that of fixed ones. */ + if ( this->removeIndex( this->getFree( ),number ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_MOVING_BOUND_FAILED ); + + if ( this->addIndex( this->getFixed( ),number,_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_MOVING_BOUND_FAILED ); + + return SUCCESSFUL_RETURN; +} + + +/* + * f l i p F i x e d + */ +returnValue Bounds::flipFixed( int_t number ) +{ + /* consistency check */ + if ( ( number < 0 ) || ( number >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + if ( status != 0 ) + switch (status[number]) + { + case ST_LOWER: status[number] = ST_UPPER; break; + case ST_UPPER: status[number] = ST_LOWER; break; + default: return THROWERROR( RET_MOVING_BOUND_FAILED ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s w a p F r e e + */ +returnValue Bounds::swapFree( int_t number1, int_t number2 + ) +{ + /* consistency check */ + if ( ( number1 < 0 ) || ( number1 >= n ) || ( number2 < 0 ) || ( number2 >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + /* Swap index within indexlist of free variables. */ + return this->swapIndex( this->getFree( ),number1,number2 ); +} + + +/* + * s h i f t + */ +returnValue Bounds::shift( int_t offset ) +{ + int_t i; + + /* consistency check */ + if ( ( offset == 0 ) || ( n <= 1 ) ) + return SUCCESSFUL_RETURN; + + if ( ( offset < 0 ) || ( offset > n/2 ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + if ( ( n % offset ) != 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + + /* 1) Shift types and status. */ + for( i=0; i n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + + /* 1) Rotate types and status. */ + SubjectToType* typeTmp = new SubjectToType[offset]; + SubjectToStatus* statusTmp = new SubjectToStatus[offset]; + + for( i=0; igetNumberArray( &FR_idx ); + + int_t* FX_idx; + getFixed( )->getNumberArray( &FX_idx ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"Bounds object comprising %d variables (%d free, %d fixed):\n",(int)n,(int)nFR,(int)nFX ); + myPrintf( myPrintfString ); + + REFER_NAMESPACE_QPOASES print( FR_idx,nFR,"free " ); + REFER_NAMESPACE_QPOASES print( FX_idx,nFX,"fixed" ); + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * c l e a r + */ +returnValue Bounds::clear( ) +{ + return SUCCESSFUL_RETURN; +} + + +/* + * c o p y + */ +returnValue Bounds::copy( const Bounds& rhs + ) +{ + freee = rhs.freee; + fixed = rhs.fixed; + + return SUCCESSFUL_RETURN; +} + + + +/* + * s e t u p A l l + */ +returnValue Bounds::setupAll( SubjectToStatus _status ) +{ + int_t i; + + /* 1) Place unbounded variables at the beginning of the index list of free variables. */ + for( i=0; i + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * C o n s t r a i n t s + */ +Constraints::Constraints( ) : SubjectTo( ) +{ +} + + +/* + * C o n s t r a i n t s + */ +Constraints::Constraints( int_t _n ) : SubjectTo( _n ) +{ + init( _n ); +} + + +/* + * C o n s t r a i n t s + */ +Constraints::Constraints( const Constraints& rhs ) : SubjectTo( rhs ) +{ + copy( rhs ); +} + + +/* + * ~ C o n s t r a i n t s + */ +Constraints::~Constraints( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +Constraints& Constraints::operator=( const Constraints& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + SubjectTo::operator=( rhs ); + copy( rhs ); + } + + return *this; +} + + +/* + * i n i t + */ +returnValue Constraints::init( int_t _n + ) +{ + if ( _n < 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + clear( ); + + if ( _n >= 0 ) + { + active.init( _n ); + inactive.init( _n ); + } + + return SubjectTo::init( _n ); +} + + + +/* + * s e t u p C o n s t r a i n t + */ +returnValue Constraints::setupConstraint( int_t number, SubjectToStatus _status + ) +{ + /* consistency check */ + if ( ( number < 0 ) || ( number >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + /* Add constraint index to respective index list. */ + switch ( _status ) + { + case ST_INACTIVE: + if ( this->addIndex( this->getInactive( ),number,_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_CONSTRAINT_FAILED ); + break; + + case ST_LOWER: + if ( this->addIndex( this->getActive( ),number,_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_CONSTRAINT_FAILED ); + break; + + case ST_UPPER: + if ( this->addIndex( this->getActive( ),number,_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_CONSTRAINT_FAILED ); + break; + + default: + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p A l l I n a c t i v e + */ +returnValue Constraints::setupAllInactive( ) +{ + return setupAll( ST_INACTIVE ); +} + + +/* + * s e t u p A l l L o w e r + */ +returnValue Constraints::setupAllLower( ) +{ + return setupAll( ST_LOWER ); +} + + +/* + * s e t u p A l l U p p e r + */ +returnValue Constraints::setupAllUpper( ) +{ + return setupAll( ST_UPPER ); +} + + +/* + * m o v e A c t i v e T o I n a c t i v e + */ +returnValue Constraints::moveActiveToInactive( int_t number ) +{ + /* consistency check */ + if ( ( number < 0 ) || ( number >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + /* Move index from indexlist of active constraints to that of inactive ones. */ + if ( this->removeIndex( this->getActive( ),number ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_MOVING_BOUND_FAILED ); + + if ( this->addIndex( this->getInactive( ),number,ST_INACTIVE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_MOVING_BOUND_FAILED ); + + return SUCCESSFUL_RETURN; +} + + +/* + * m o v e I n a c t i v e T o A c t i v e + */ +returnValue Constraints::moveInactiveToActive( int_t number, SubjectToStatus _status + ) +{ + /* consistency check */ + if ( ( number < 0 ) || ( number >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + /* Move index from indexlist of inactive constraints to that of active ones. */ + if ( this->removeIndex( this->getInactive( ),number ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_MOVING_BOUND_FAILED ); + + if ( this->addIndex( this->getActive( ),number,_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_MOVING_BOUND_FAILED ); + + return SUCCESSFUL_RETURN; +} + + +/* + * f l i p F i x e d + */ +returnValue Constraints::flipFixed( int_t number ) +{ + /* consistency check */ + if ( ( number < 0 ) || ( number >= n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + if ( status != 0 ) + switch (status[number]) + { + case ST_LOWER: status[number] = ST_UPPER; break; + case ST_UPPER: status[number] = ST_LOWER; break; + default: return THROWERROR( RET_MOVING_CONSTRAINT_FAILED ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s h i f t + */ +returnValue Constraints::shift( int_t offset ) +{ + int_t i; + + /* consistency check */ + if ( ( offset == 0 ) || ( n <= 1 ) ) + return SUCCESSFUL_RETURN; + + if ( ( offset < 0 ) || ( offset > n/2 ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + if ( ( n % offset ) != 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + + /* 1) Shift types and status. */ + for( i=0; i n ) ) + return THROWERROR( RET_INDEX_OUT_OF_BOUNDS ); + + + /* 1) Rotate types and status. */ + SubjectToType* typeTmp = new SubjectToType[offset]; + SubjectToStatus* statusTmp = new SubjectToStatus[offset]; + + for( i=0; igetNumberArray( &IAC_idx ); + + int_t* AC_idx; + getActive( )->getNumberArray( &AC_idx ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"Constraints object comprising %d constraints (%d inactive, %d active):\n",(int)n,(int)nIAC,(int)nAC ); + myPrintf( myPrintfString ); + + REFER_NAMESPACE_QPOASES print( IAC_idx,nIAC,"inactive" ); + REFER_NAMESPACE_QPOASES print( AC_idx, nAC, "active " ); + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * c l e a r + */ +returnValue Constraints::clear( ) +{ + return SUCCESSFUL_RETURN; +} + + +/* + * c o p y + */ +returnValue Constraints::copy( const Constraints& rhs + ) +{ + active = rhs.active; + inactive = rhs.inactive; + + return SUCCESSFUL_RETURN; +} + + + +/* + * s e t u p A l l + */ +returnValue Constraints::setupAll( SubjectToStatus _status ) +{ + int_t i; + + /* 1) Place unbounded constraints at the beginning of the index list of inactive constraints. */ + for( i=0; i + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * F l i p p e r + */ +Flipper::Flipper( ) +{ + R = 0; + Q = 0; + T = 0; + + init( ); +} + + +/* + * F l i p p e r + */ +Flipper::Flipper( uint_t _nV, + uint_t _nC + ) +{ + R = 0; + Q = 0; + T = 0; + + init( _nV,_nC ); +} + + +/* + * F l i p p e r + */ +Flipper::Flipper( const Flipper& rhs ) +{ + R = 0; + Q = 0; + T = 0; + + copy( rhs ); +} + + +/* + * ~ F l i p p e r + */ +Flipper::~Flipper( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +Flipper& Flipper::operator=( const Flipper& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + copy( rhs ); + } + + return *this; +} + + + +/* + * i n i t + */ +returnValue Flipper::init( uint_t _nV, + uint_t _nC + ) +{ + clear( ); + + nV = _nV; + nC = _nC; + + return SUCCESSFUL_RETURN; +} + + + +/* + * g e t + */ +returnValue Flipper::get( Bounds* const _bounds, + real_t* const _R, + Constraints* const _constraints, + real_t* const _Q, + real_t* const _T + ) const +{ + if ( _bounds != 0 ) + *_bounds = bounds; + + if ( _constraints != 0 ) + *_constraints = constraints; + + if ( ( _R != 0 ) && ( R != 0 ) ) + memcpy( _R,R, nV*nV*sizeof(real_t) ); + + if ( ( _Q != 0 ) && ( Q != 0 ) ) + memcpy( _Q,Q, nV*nV*sizeof(real_t) ); + + if ( ( _T != 0 ) && ( T != 0 ) ) + memcpy( _T,T, getDimT()*sizeof(real_t) ); + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t + */ +returnValue Flipper::set( const Bounds* const _bounds, + const real_t* const _R, + const Constraints* const _constraints, + const real_t* const _Q, + const real_t* const _T + ) +{ + if ( _bounds != 0 ) + bounds = *_bounds; + + if ( _constraints != 0 ) + constraints = *_constraints; + + if ( _R != 0 ) + { + if ( R == 0 ) + R = new real_t[nV*nV]; + + memcpy( R,_R, nV*nV*sizeof(real_t) ); + } + + if ( _Q != 0 ) + { + if ( Q == 0 ) + Q = new real_t[nV*nV]; + + memcpy( Q,_Q, nV*nV*sizeof(real_t) ); + } + + if ( _T != 0 ) + { + if ( T == 0 ) + T = new real_t[getDimT()]; + + memcpy( T,_T, getDimT()*sizeof(real_t) ); + } + + return SUCCESSFUL_RETURN; +} + + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * c l e a r + */ +returnValue Flipper::clear( ) +{ + if ( R != 0 ) + { + delete[] R; + R = 0; + } + + if ( Q != 0 ) + { + delete[] Q; + Q = 0; + } + + if ( T != 0 ) + { + delete[] T; + T = 0; + } + + return SUCCESSFUL_RETURN; +} + + +/* + * c o p y + */ +returnValue Flipper::copy( const Flipper& rhs + ) +{ + return set( &(rhs.bounds),rhs.R, &(rhs.constraints),rhs.Q,rhs.T ); +} + + +uint_t Flipper::getDimT( ) const +{ + if ( nV > nC ) + return nC*nC; + else + return nV*nV; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/Indexlist.cpp b/locomotion/src/third_party/qpOASES/src/Indexlist.cpp new file mode 100644 index 0000000..d6fb383 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/Indexlist.cpp @@ -0,0 +1,319 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/Indexlist.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the Indexlist class designed to manage index lists of + * constraints and bounds within a QProblem_SubjectTo. + */ + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * I n d e x l i s t + */ +Indexlist::Indexlist( ) +{ + number = 0; + iSort = 0; + + init( ); +} + + +/* + * I n d e x l i s t + */ +Indexlist::Indexlist( int_t n ) +{ + number = 0; + iSort = 0; + + init( n ); +} + + +/* + * I n d e x l i s t + */ +Indexlist::Indexlist( const Indexlist& rhs ) +{ + copy( rhs ); +} + + +/* + * ~ I n d e x l i s t + */ +Indexlist::~Indexlist( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +Indexlist& Indexlist::operator=( const Indexlist& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + copy( rhs ); + } + + return *this; +} + + + +/* + * i n i t + */ +returnValue Indexlist::init( int_t n + ) +{ + if ( n < 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + clear( ); + + length = 0; + physicallength = n; + + if ( n > 0 ) + { + number = new int_t[n]; + iSort = new int_t[n]; + } + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t N u m b e r A r r a y + */ +returnValue Indexlist::getNumberArray( int_t** const numberarray ) const +{ + if (numberarray == 0) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + *numberarray = number; + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t I S o r t A r r a y + */ +returnValue Indexlist::getISortArray( int_t** const iSortArray ) const +{ + *iSortArray = iSort; + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t I n d e x + */ +int_t Indexlist::getIndex( int_t givennumber ) const +{ + int_t index = findInsert(givennumber); + return number[iSort[index]] == givennumber ? iSort[index] : -1; +} + + +/* + * a d d N u m b e r + */ +returnValue Indexlist::addNumber( int_t addnumber ) +{ + if ( length >= physicallength ) + return THROWERROR( RET_INDEXLIST_EXCEEDS_MAX_LENGTH ); + + int_t i, j; + number[length] = addnumber; + j = findInsert(addnumber); + for (i = length; i > j+1; i--) + iSort[i] = iSort[i-1]; + iSort[j+1] = length; + ++length; + + return SUCCESSFUL_RETURN; +} + + +/* + * r e m o v e N u m b e r + */ +returnValue Indexlist::removeNumber( int_t removenumber ) +{ + int_t i; + int_t idx = findInsert( removenumber ); + int_t iSidx = iSort[idx]; + + /* nothing to be done if number is not contained in index set */ + if ( number[iSidx] != removenumber ) + return SUCCESSFUL_RETURN; + + /* update sorted indices iSort first */ + for (i = 0; i < length; i++) + if (iSort[i] > iSidx) iSort[i]--; + for (i = idx+1; i < length; i++) + iSort[i-1] = iSort[i]; + + /* remove from numbers list */ + for( i=iSidx; i= number[iSort[length-1]]) return length-1; + + /* otherwise, perform bisection search */ + int_t fst = 0, lst = length-1, mid; + + while (fst < lst - 1) + { + mid = (fst + lst) / 2; + if (i >= number[iSort[mid]]) fst = mid; + else lst = mid; + } + + return fst; +} + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/LAPACKReplacement.cpp b/locomotion/src/third_party/qpOASES/src/LAPACKReplacement.cpp new file mode 100644 index 0000000..16f474e --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/LAPACKReplacement.cpp @@ -0,0 +1,159 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/LAPACKReplacement.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * LAPACK replacement routines. + */ + + +#include +#include + + +extern "C" void DPOTRF( const char* uplo, const la_uint_t* _n, double* a, + const la_uint_t* _lda, la_int_t* info + ) +{ + double sum; + la_int_t i, j, k; + la_int_t n = (la_int_t)(*_n); + la_int_t lda = (la_int_t)(*_lda); + + for( i=0; i=0; --k ) + sum -= a[k+lda*i] * a[k+lda*i]; + + if ( sum > 0.0 ) + a[i+lda*i] = REFER_NAMESPACE_QPOASES getSqrt( sum ); + else + { + a[0] = sum; /* tunnel negative diagonal element to caller */ + if (info != 0) + *info = (la_int_t)i+1; + return; + } + + for( j=(i+1); j=0; --k ) + sum -= a[k+lda*i] * a[k+lda*j]; + + a[i+lda*j] = sum / a[i+lda*i]; + } + } + if (info != 0) + *info = 0; +} + + +extern "C" void SPOTRF( const char* uplo, const la_uint_t* _n, float* a, + const la_uint_t* _lda, la_int_t* info + ) +{ + float sum; + la_int_t i, j, k; + la_int_t n = (la_int_t)(*_n); + la_int_t lda = (la_int_t)(*_lda); + + for( i=0; i=0; --k ) + sum -= a[k+lda*i] * a[k+lda*i]; + + if ( sum > 0.0 ) + a[i+lda*i] = (float)(REFER_NAMESPACE_QPOASES getSqrt( sum )); + else + { + a[0] = sum; /* tunnel negative diagonal element to caller */ + if (info != 0) + *info = (la_int_t)i+1; + return; + } + + for( j=(i+1); j=0; --k ) + sum -= a[k+lda*i] * a[k+lda*j]; + + a[i+lda*j] = sum / a[i+lda*i]; + } + } + if (info != 0) + *info = 0; +} + + +extern "C" void DTRTRS( const char* UPLO, const char* TRANS, const char* DIAG, + const la_uint_t* N, const la_uint_t* NRHS, + double* A, const la_uint_t* LDA, double* B, const la_uint_t* LDB, la_int_t* INFO + ) +{ + INFO[0] = ((la_int_t)0xDEADBEEF); /* Dummy. If SQProblemSchur is to be used, system LAPACK must be used */ +} + +extern "C" void STRTRS( const char* UPLO, const char* TRANS, const char* DIAG, + const la_uint_t* N, const la_uint_t* NRHS, + float* A, const la_uint_t* LDA, float* B, const la_uint_t* LDB, la_int_t* INFO + ) +{ + INFO[0] = ((la_int_t)0xDEADBEEF); /* Dummy. If SQProblemSchur is to be used, system LAPACK must be used */ +} + + +extern "C" void DTRCON( const char* NORM, const char* UPLO, const char* DIAG, + const la_uint_t* N, double* A, const la_uint_t*LDA, + double* RCOND, double* WORK, const la_uint_t* IWORK, la_int_t* INFO + ) +{ + INFO[0] = ((la_int_t)0xDEADBEEF); /* Dummy. If SQProblemSchur is to be used, system LAPACK must be used */ +} + +extern "C" void STRCON( const char* NORM, const char* UPLO, const char* DIAG, + const la_uint_t* N, float* A, const la_uint_t* LDA, + float* RCOND, float* WORK, const la_uint_t* IWORK, la_int_t* INFO + ) +{ + INFO[0] = ((la_int_t)0xDEADBEEF); /* Dummy. If SQProblemSchur is to be used, system LAPACK must be used */ +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/Makefile b/locomotion/src/third_party/qpOASES/src/Makefile new file mode 100644 index 0000000..69b9503 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/Makefile @@ -0,0 +1,111 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: src/Makefile +## Author: Hans Joachim Ferreau, Andreas Potschka, Christian Kirches +## Version: 3.2 +## Date: 2007-2017 +## + +include ../make.mk + +## +## flags +## + +IFLAGS = -I. \ + -I${IDIR} + +QPOASES_OBJECTS = \ + SQProblem.${OBJEXT} \ + QProblem.${OBJEXT} \ + QProblemB.${OBJEXT} \ + SQProblemSchur.${OBJEXT} \ + Bounds.${OBJEXT} \ + Constraints.${OBJEXT} \ + SubjectTo.${OBJEXT} \ + Indexlist.${OBJEXT} \ + Flipper.${OBJEXT} \ + Utils.${OBJEXT} \ + Options.${OBJEXT} \ + Matrices.${OBJEXT} \ + MessageHandling.${OBJEXT} \ + SparseSolver.${OBJEXT} + + +QPOASES_EXTRAS_OBJECTS = \ + SolutionAnalysis.${OBJEXT} \ + OQPinterface.${OBJEXT} + +QPOASES_DEPENDS = \ + ${IDIR}/qpOASES.hpp \ + ${IDIR}/qpOASES/LapackBlasReplacement.hpp \ + ${IDIR}/qpOASES/SQProblem.hpp \ + ${IDIR}/qpOASES/QProblem.hpp \ + ${IDIR}/qpOASES/Flipper.hpp \ + ${IDIR}/qpOASES/QProblemB.hpp \ + ${IDIR}/qpOASES/Bounds.hpp \ + ${IDIR}/qpOASES/Constraints.hpp \ + ${IDIR}/qpOASES/SubjectTo.hpp \ + ${IDIR}/qpOASES/Indexlist.hpp \ + ${IDIR}/qpOASES/Utils.hpp \ + ${IDIR}/qpOASES/Constants.hpp \ + ${IDIR}/qpOASES/Types.hpp \ + ${IDIR}/qpOASES/Options.hpp \ + ${IDIR}/qpOASES/Matrices.hpp \ + ${IDIR}/qpOASES/MessageHandling.hpp \ + ${IDIR}/qpOASES/UnitTesting.hpp + + +## +## targets +## + +all: ${LINK_DEPENDS} + + +${BINDIR}/libqpOASES.${LIBEXT}: ${QPOASES_OBJECTS} ${QPOASES_EXTRAS_OBJECTS} + @${ECHO} "Creating static lib" $@ + @${AR} r $@ $^ + +${BINDIR}/libqpOASES.${DLLEXT}: ${QPOASES_OBJECTS} ${QPOASES_EXTRAS_OBJECTS} + @${ECHO} "Creating shared lib" $@ + @${CPP} ${DEF_TARGET} ${SHARED} $^ ${LINK_LIBRARIES} + +clean: + @${ECHO} "Cleaning up (src)" + @${RM} -f *.${OBJEXT} *.${LIBEXT} *.${DLLEXT} + +clobber: clean + + +%.${OBJEXT}: %.cpp ${QPOASES_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} -c ${IFLAGS} ${CPPFLAGS} $< + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/src/Matrices.cpp b/locomotion/src/third_party/qpOASES/src/Matrices.cpp new file mode 100644 index 0000000..d16e2a1 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/Matrices.cpp @@ -0,0 +1,2200 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/Matrices.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the matrix classes. + */ + + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + +returnValue Matrix::getSparseSubmatrix( + const Indexlist* const irows, + const Indexlist* const icols, + int_t rowoffset, + int_t coloffset, + int_t& numNonzeros, + int_t* irn, + int_t* jcn, + real_t* avals, + BooleanType only_lower_triangular) const +{ + int_t* rowsNumbers; + irows->getNumberArray( &rowsNumbers ); + int_t* colsNumbers; + icols->getNumberArray( &colsNumbers ); + + return getSparseSubmatrix(irows->getLength(), rowsNumbers, icols->getLength(), colsNumbers, rowoffset, coloffset, numNonzeros, irn, jcn, avals, only_lower_triangular); +} + +returnValue Matrix::getSparseSubmatrix( + const Indexlist* const irows, + int_t idx_icol, + int_t rowoffset, + int_t coloffset, + int_t& numNonzeros, + int_t* irn, + int_t* jcn, + real_t* avals, + BooleanType only_lower_triangular) const +{ + int_t* rowsNumbers; + irows->getNumberArray( &rowsNumbers ); + + return getSparseSubmatrix(irows->getLength(), rowsNumbers, 1, &idx_icol, rowoffset, coloffset, numNonzeros, irn, jcn, avals, only_lower_triangular); +} + +returnValue Matrix::getSparseSubmatrix( + int_t idx_row, + const Indexlist* const icols, + int_t rowoffset, + int_t coloffset, + int_t& numNonzeros, + int_t* irn, + int_t* jcn, + real_t* avals, + BooleanType only_lower_triangular) const +{ + int_t* colsNumbers; + icols->getNumberArray( &colsNumbers ); + + return getSparseSubmatrix(1, &idx_row, icols->getLength(), colsNumbers, rowoffset, coloffset, numNonzeros, irn, jcn, avals, only_lower_triangular); +} + + +DenseMatrix::~DenseMatrix() +{ + if ( needToFreeMemory( ) == BT_TRUE ) + free( ); +} + +void DenseMatrix::free( ) +{ + if (val != 0) + delete[] val; + val = 0; +} + +Matrix *DenseMatrix::duplicate( ) const +{ + DenseMatrix *dupl = 0; + + if ( needToFreeMemory( ) == BT_TRUE ) + { + real_t* val_new = new real_t[nRows*nCols]; + memcpy( val_new,val, ((uint_t)(nRows*nCols))*sizeof(real_t) ); + dupl = new DenseMatrix(nRows, nCols, nCols, val_new); + dupl->doFreeMemory( ); + } + else + { + dupl = new DenseMatrix(nRows, nCols, nCols, val); + } + + return dupl; +} + +real_t DenseMatrix::diag( int_t i + ) const +{ + return val[i*(leaDim+1)]; +} + +BooleanType DenseMatrix::isDiag( ) const +{ + int_t i, j; + + if (nRows != nCols) + return BT_FALSE; + + for ( i=0; i EPS ) || ( getAbs( val[j*leaDim+i] ) > EPS ) ) + return BT_FALSE; + + return BT_TRUE; +} + + +real_t DenseMatrix::getNorm( int_t type + ) const +{ + return REFER_NAMESPACE_QPOASES getNorm( val,nCols*nRows,type ); +} + + +real_t DenseMatrix::getRowNorm( int_t rNum, int_t type ) const +{ + return REFER_NAMESPACE_QPOASES getNorm( &(val[rNum*leaDim]),nCols,type ); +} + +returnValue DenseMatrix::getRowNorm( real_t* norm, int_t type ) const +{ + int_t i; + for (i = 0; i < nRows; ++i) + { + norm[i] = REFER_NAMESPACE_QPOASES getNorm( &(val[i*leaDim]),nCols,type ); + } + return SUCCESSFUL_RETURN; +} + +returnValue DenseMatrix::getRow(int_t rNum, const Indexlist* const icols, real_t alpha, real_t* row) const +{ + int_t i; + if (icols != 0) + { + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (i = 0; i < icols->length; i++) + row[i] = val[rNum*leaDim+icols->number[i]]; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (i = 0; i < icols->length; i++) + row[i] = -val[rNum*leaDim+icols->number[i]]; + else + for (i = 0; i < icols->length; i++) + row[i] = alpha*val[rNum*leaDim+icols->number[i]]; + } + else + { + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (i = 0; i < nCols; i++) + row[i] = val[rNum*leaDim+i]; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (i = 0; i < nCols; i++) + row[i] = -val[rNum*leaDim+i]; + else + for (i = 0; i < nCols; i++) + row[i] = alpha*val[rNum*leaDim+i]; + } + return SUCCESSFUL_RETURN; +} + + +returnValue DenseMatrix::getCol(int_t cNum, const Indexlist* const irows, real_t alpha, real_t* col) const +{ + int_t i; + + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (i = 0; i < irows->length; i++) + col[i] = val[irows->number[i]*leaDim+cNum]; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (i = 0; i < irows->length; i++) + col[i] = -val[irows->number[i]*leaDim+cNum]; + else + for (i = 0; i < irows->length; i++) + col[i] = alpha*val[irows->number[i]*leaDim+cNum]; + + return SUCCESSFUL_RETURN; +} + +returnValue DenseMatrix::getSparseSubmatrix (int_t irowsLength, const int_t* const irowsNumber, + int_t icolsLength, const int_t* const icolsNumber, + int_t rowoffset, int_t coloffset, int_t& numNonzeros, int_t* irn, + int_t* jcn, real_t* avals, + BooleanType only_lower_triangular /*= BT_FALSE */) const +{ + int_t i, j, irA; + real_t v; + numNonzeros = 0; + if ( only_lower_triangular == BT_FALSE ) + { + if (irn == 0) + { + if (jcn != 0 || avals != 0) + return THROWERROR( RET_INVALID_ARGUMENTS ); + for (j = 0; jlength; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] *= beta; + + if (icols == 0) + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + iy = row + k * yLD; + irA = irows->number[row] * leaDim; + for (i = 0; i < nCols; i++) + y[iy] += val[irA+i] * x[k*xLD+i]; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + iy = row + k * yLD; + irA = irows->number[row] * leaDim; + for (i = 0; i < nCols; i++) + y[iy] -= val[irA+i] * x[k*xLD+i]; + } + else + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + iy = row + k * yLD; + irA = irows->number[row] * leaDim; + for (i = 0; i < nCols; i++) + y[iy] += alpha * val[irA+i] * x[k*xLD+i]; + } + else /* icols != 0 */ + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + iy = row + k * yLD; + irA = irows->number[row] * leaDim; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[iy] += val[irA+icols->number[col]] * x[k*xLD+col]; + } + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + iy = row + k * yLD; + irA = irows->number[row] * leaDim; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[iy] -= val[irA+icols->number[col]] * x[k*xLD+col]; + } + } + else + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + iy = row + k * yLD; + irA = irows->number[row] * leaDim; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[iy] += alpha * val[irA+icols->number[col]] * x[k*xLD+col]; + } + } + } + else /* y not compressed */ + { + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] *= beta; + + if (icols == 0) + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->number[irows->iSort[j]]; + iy = row + k * yLD; + irA = row * leaDim; + for (i = 0; i < nCols; i++) + y[iy] += val[irA+i] * x[k*xLD+i]; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->number[irows->iSort[j]]; + iy = row + k * yLD; + irA = row * leaDim; + for (i = 0; i < nCols; i++) + y[iy] -= val[irA+i] * x[k*xLD+i]; + } + else + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->number[irows->iSort[j]]; + iy = row + k * yLD; + irA = row * leaDim; + for (i = 0; i < nCols; i++) + y[iy] += alpha * val[irA+i] * x[k*xLD+i]; + } + else /* icols != 0 */ + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->number[irows->iSort[j]]; + iy = row + k * yLD; + irA = row * leaDim; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[iy] += val[irA+icols->number[col]] * x[k*xLD+col]; + } + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->number[irows->iSort[j]]; + iy = row + k * yLD; + irA = row * leaDim; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[iy] -= val[irA+icols->number[col]] * x[k*xLD+col]; + } + } + else + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->number[irows->iSort[j]]; + iy = row + k * yLD; + irA = row * leaDim; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[iy] += alpha * val[irA+icols->number[col]] * x[k*xLD+col]; + } + } + } + + return SUCCESSFUL_RETURN; +} + +returnValue DenseMatrix::transTimes( const Indexlist* const irows, const Indexlist* const icols, + int_t xN, real_t alpha, const real_t* x, int_t xLD, real_t beta, real_t* y, int_t yLD ) const +{ + int_t i, j, k, row, col; + + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] *= beta; + + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[col+k*yLD] += val[irows->number[row]*leaDim+icols->number[col]] * x[row+k*xLD]; + } + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[col+k*yLD] -= val[irows->number[row]*leaDim+icols->number[col]] * x[row+k*xLD]; + } + } + else + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + { + row = irows->iSort[j]; + for (i = 0; i < icols->length; i++) + { + col = icols->iSort[i]; + y[col+k*yLD] += alpha * val[irows->number[row]*leaDim+icols->number[col]] * x[row+k*xLD]; + } + } + + return SUCCESSFUL_RETURN; +} + + +returnValue DenseMatrix::addToDiag( real_t alpha ) +{ + int_t i; + for (i = 0; i < nRows && i < nCols; i++) + val[i*(leaDim+1)] += alpha; + + return SUCCESSFUL_RETURN; +} + + +returnValue DenseMatrix::writeToFile( FILE* output_file, const char* prefix ) const +{ + return THROWERROR( RET_NOT_YET_IMPLEMENTED ); +} + + +real_t* DenseMatrix::full() const +{ + real_t* v = new real_t[nRows*nCols]; + memcpy( v,val, ((uint_t)(nRows*nCols))*sizeof(real_t) ); + return v; +} + + +returnValue DenseMatrix::print( const char* name ) const +{ + return REFER_NAMESPACE_QPOASES print( val,nRows,nCols,name ); +} + + + +Matrix *SymDenseMat::duplicate( ) const +{ + return duplicateSym(); +} + + +SymmetricMatrix *SymDenseMat::duplicateSym( ) const +{ + /* "same" as duplicate() in DenseMatrix */ + SymDenseMat *dupl = 0; + + if ( needToFreeMemory( ) == BT_TRUE ) + { + real_t* val_new = new real_t[nRows*nCols]; + memcpy( val_new,val, ((uint_t)(nRows*nCols))*sizeof(real_t) ); + dupl = new SymDenseMat(nRows, nCols, nCols, val_new); + dupl->doFreeMemory( ); + } + else + { + dupl = new SymDenseMat(nRows, nCols, nCols, val); + } + + return dupl; +} + + +returnValue SymDenseMat::bilinear( const Indexlist* const icols, + int_t xN, const real_t* x, int_t xLD, real_t* y, int_t yLD ) const +{ + int_t ii, jj, kk, col; + int_t i,j,k,irA; + + for (ii = 0; ii < xN; ii++) + for (jj = 0; jj < xN; jj++) + y[ii*yLD+jj] = 0.0; + + real_t* Ax = new real_t[icols->length * xN]; + + for (i=0;ilength * xN;++i) + Ax[i]=0.0; + + /* exploit symmetry of A ! */ + for (j = 0; j < icols->length; j++) { + irA = icols->number[j] * leaDim; + for (i = 0; i < icols->length; i++) + { + real_t h = val[irA+icols->number[i]]; + for (k = 0; k < xN; k++) + Ax[j + k * icols->length] += h * x[k*xLD+icols->number[i]]; + } + } + + for (ii = 0; ii < icols->length; ++ii) { + col = icols->number[ii]; + for (jj = 0; jj < xN; ++jj) { + for (kk = 0; kk < xN; ++kk) { + y[kk + jj*yLD] += x[col + jj*xLD] * Ax[ii + kk*icols->length]; + } + } + } + delete[] Ax; + + return SUCCESSFUL_RETURN; +} + + + +SparseMatrix::SparseMatrix() : nRows(0), nCols(0), ir(0), jc(0), jd(0), val(0) {} + +SparseMatrix::SparseMatrix( int_t nr, int_t nc, sparse_int_t* r, sparse_int_t* c, real_t* v ) + : nRows(nr), nCols(nc), ir(r), jc(c), jd(0), val(v) { doNotFreeMemory(); } + +SparseMatrix::SparseMatrix( int_t nr, int_t nc, int_t ld, const real_t* const v ) + : nRows(nr), nCols(nc), jd(0) +{ + int_t i, j, nnz; + + jc = new sparse_int_t[nc+1]; + ir = new sparse_int_t[nr*nc]; + val = new real_t[nr*nc]; + + nnz = 0; + for (j = 0; j < nCols; j++) + { + jc[j] = nnz; + for (i = 0; i < nRows; i++) + if ( ( isZero( v[i*ld+j],0.0 ) == BT_FALSE ) || ( i == j ) ) /* also include zero diagonal elements! */ + { + ir[nnz] = i; + val[nnz++] = v[i*ld+j]; + } + } + jc[nCols] = nnz; + + doFreeMemory( ); +} + + +SparseMatrix::~SparseMatrix() +{ + if (jd != 0) + { + delete[] jd; + jd = 0; + } + + if ( needToFreeMemory() == BT_TRUE ) + free( ); +} + + +void SparseMatrix::free( ) +{ + if (ir != 0) delete[] ir; + ir = 0; + if (jc != 0) delete[] jc; + jc = 0; + if (val != 0) delete[] val; + val = 0; + + doNotFreeMemory( ); +} + + +Matrix *SparseMatrix::duplicate( ) const +{ + long i, length = jc[nCols]; + SparseMatrix *dupl = new SparseMatrix; + + dupl->nRows = nRows; + dupl->nCols = nCols; + dupl->ir = new sparse_int_t[length]; + dupl->jc = new sparse_int_t[nCols+1]; + dupl->val = new real_t[length]; + + for (i = 0; i < length; i++) dupl->ir[i] = ir[i]; + for (i = 0; i <= nCols; i++) dupl->jc[i] = jc[i]; + for (i = 0; i < length; i++) dupl->val[i] = val[i]; + + if ( jd != 0 ) + { + dupl->jd = new sparse_int_t[nCols]; + for (i = 0; i < nCols; i++) dupl->jd[i] = jd[i]; + } + else + dupl->jd = 0; + + dupl->doFreeMemory( ); + + return dupl; +} + + +void SparseMatrix::setVal( const real_t* newVal ) +{ + long length = jc[nCols]; /* [nCols+1] ?? */ + for (long index = 0; index < length; ++index) + { + val[index] = newVal[index]; + } +} + + +real_t SparseMatrix::diag( int_t i ) const +{ + if ( jd == 0 ) + { + THROWERROR( RET_DIAGONAL_NOT_INITIALISED ); + return INFTY; + } + + int_t entry = jd[i]; + return (entry < jc[i+1] && ir[entry] == i) ? val[entry] : 0.0; +} + + +BooleanType SparseMatrix::isDiag( ) const +{ + int_t j; + + if ( nCols != nRows ) + return BT_FALSE; + + for (j = 0; j < nCols; ++j) + { + if ( jc[j+1] > jc[j]+1 ) + return BT_FALSE; + + if ( ( jc[j+1] == jc[j]+1 ) && ( ir[jc[j]] != j ) ) + return BT_FALSE; + } + + return BT_TRUE; +} + + + +real_t SparseMatrix::getNorm( int_t type + ) const +{ + int_t length = jc[nCols]; + return REFER_NAMESPACE_QPOASES getNorm( val,length,type ); +} + + +real_t SparseMatrix::getRowNorm( int_t rNum, int_t type ) const +{ + int_t i,j; + real_t norm = 0.0; + + switch( type ) + { + case 2: + for ( j=0; j < nCols; ++j ) { + for (i = jc[j]; i < jc[j+1] && ir[i] < rNum; i++) {}; + if (i < jc[j+1] && ir[i] == rNum) norm += val[i]*val[i]; + } + return getSqrt(norm); + + case 1: + for ( j=0; j < nCols; ++j ) { + for (i = jc[j]; i < jc[j+1] && ir[i] < rNum; i++) {}; + if (i < jc[j+1] && ir[i] == rNum) norm += getAbs( val[i] ); + } + return norm; + + default: + THROWERROR( RET_INVALID_ARGUMENTS ); + return -INFTY; + } +} + +returnValue SparseMatrix::getRowNorm( real_t* norm, int_t type ) const +{ + int_t i,j; + + for ( j=0; j < nRows; ++j ) norm[j] = 0.0; + + switch( type ) + { + case 2: + for ( j=0; j < nCols; ++j ) { + for (i = jc[j]; i < jc[j+1]; i++) + norm[ir[i]] += val[i]*val[i]; + } + for ( j=0; j < nRows; ++j ) norm[j] = getSqrt(norm[j]); + break; + case 1: + for ( j=0; j < nCols; ++j ) { + for (i = jc[j]; i < jc[j+1]; i++); + norm[ir[i]] += getAbs( val[i] ); + } + break; + default: + return RET_INVALID_ARGUMENTS; + } + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrix::getRow( int_t rNum, const Indexlist* const icols, real_t alpha, real_t* row ) const +{ + long i, j, k; + + if (icols != 0) + { + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < icols->length; k++) + { + j = icols->number[icols->iSort[k]]; + for (i = jc[j]; i < jc[j+1] && ir[i] < rNum; i++); + row[icols->iSort[k]] = (i < jc[j+1] && ir[i] == rNum) ? val[i] : 0.0; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < icols->length; k++) + { + j = icols->number[icols->iSort[k]]; + for (i = jc[j]; i < jc[j+1] && ir[i] < rNum; i++); + row[icols->iSort[k]] = (i < jc[j+1] && ir[i] == rNum) ? -val[i] : 0.0; + } + else + for (k = 0; k < icols->length; k++) + { + j = icols->number[icols->iSort[k]]; + for (i = jc[j]; i < jc[j+1] && ir[i] < rNum; i++); + row[icols->iSort[k]] = (i < jc[j+1] && ir[i] == rNum) ? alpha*val[i] : 0.0; + } + } + else + { + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (j = 0; j < nCols; j++) + { + for (i = jc[j]; i < jc[j+1] && ir[i] < rNum; i++); + row[j] = (i < jc[j+1] && ir[i] == rNum) ? val[i] : 0.0; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (j = 0; j < icols->length; j++) + { + for (i = jc[j]; i < jc[j+1] && ir[i] < rNum; i++); + row[j] = (i < jc[j+1] && ir[i] == rNum) ? -val[i] : 0.0; + } + else + for (j = 0; j < icols->length; j++) + { + for (i = jc[j]; i < jc[j+1] && ir[i] < rNum; i++); + row[j] = (i < jc[j+1] && ir[i] == rNum) ? alpha*val[i] : 0.0; + } + } + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrix::getCol( int_t cNum, const Indexlist* const irows, real_t alpha, real_t* col ) const +{ + long i, j; + + i = jc[cNum]; + j = 0; + if ( isEqual(alpha,1.0) == BT_TRUE ) + while (i < jc[cNum+1] && j < irows->length) + if (ir[i] == irows->number[irows->iSort[j]]) + col[irows->iSort[j++]] = val[i++]; + else if (ir[i] > irows->number[irows->iSort[j]]) + col[irows->iSort[j++]] = 0.0; + else + i++; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + while (i < jc[cNum+1] && j < irows->length) + if (ir[i] == irows->number[irows->iSort[j]]) + col[irows->iSort[j++]] = -val[i++]; + else if (ir[i] > irows->number[irows->iSort[j]]) + col[irows->iSort[j++]] = 0.0; + else + i++; + else + while (i < jc[cNum+1] && j < irows->length) + if (ir[i] == irows->number[irows->iSort[j]]) + col[irows->iSort[j++]] = alpha * val[i++]; + else if (ir[i] > irows->number[irows->iSort[j]]) + col[irows->iSort[j++]] = 0.0; + else + i++; + + /* fill in remaining zeros */ + while (j < irows->length) + col[irows->iSort[j++]] = 0.0; + + return SUCCESSFUL_RETURN; +} + +returnValue SparseMatrix::getSparseSubmatrix( int_t irowsLength, const int_t* const irowsNumber, + int_t icolsLength, const int_t* const icolsNumber, + int_t rowoffset, int_t coloffset, int_t& numNonzeros, int_t* irn, + int_t* jcn, real_t* avals, + BooleanType only_lower_triangular /*= BT_FALSE */ ) const +{ + int_t i, j, k, l; + + // Compute the "inverse" of the irows->number array + // TODO: Ideally this should be a part of Indexlist + int_t* rowNumberInv = new int_t[nRows]; + for (i=0; i= 0) + numNonzeros++; + } + } + } + else + { + for (k = 0; k < icolsLength; k++) + { + j = icolsNumber[k]; + for (i = jc[j]; i < jc[j+1]; i++) + { + l = rowNumberInv[ir[i]]; + if (l >= 0) + { + irn[numNonzeros] = l+rowoffset; + jcn[numNonzeros] = k+coloffset; + avals[numNonzeros] = val[i]; + numNonzeros++; + } + } + } + } + } + else + { + if (irn == 0) + { + if (jcn != 0 || avals != 0) + return THROWERROR( RET_INVALID_ARGUMENTS ); + for (k = 0; k < icolsLength; k++) + { + j = icolsNumber[k]; + for (i = jc[j]; i < jc[j+1]; i++) + { + l = rowNumberInv[ir[i]]; + if (l >= k) + numNonzeros++; + } + } + } + else + { + for (k = 0; k < icolsLength; k++) + { + j = icolsNumber[k]; + for (i = jc[j]; i < jc[j+1]; i++) + { + l = rowNumberInv[ir[i]]; + if (l >= k) + { + irn[numNonzeros] = l+rowoffset; + jcn[numNonzeros] = k+coloffset; + avals[numNonzeros] = val[i]; + numNonzeros++; + } + } + } + } + } + delete [] rowNumberInv; + + return SUCCESSFUL_RETURN; +} + +returnValue SparseMatrix::times( int_t xN, real_t alpha, const real_t* x, int_t xLD, + real_t beta, real_t* y, int_t yLD ) const +{ + long i, j, k; + + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + y[j+k*yLD] *= beta; + + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + for (i = jc[j]; i < jc[j+1]; i++) + y[ir[i]+k*yLD] += val[i] * x[j+k*xLD]; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + for (i = jc[j]; i < jc[j+1]; i++) + y[ir[i]+k*yLD] -= val[i] * x[j+k*xLD]; + else + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + for (i = jc[j]; i < jc[j+1]; i++) + y[ir[i]+k*yLD] += alpha * val[i] * x[j+k*xLD]; + + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrix::transTimes( int_t xN, real_t alpha, const real_t* x, int_t xLD, + real_t beta, real_t* y, int_t yLD ) const +{ + long i, j, k; + + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + y[j+k*yLD] *= beta; + + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + for (i = jc[j]; i < jc[j+1]; i++) + y[j+k*yLD] += val[i] * x[ir[i]+k*xLD]; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + for (i = jc[j]; i < jc[j+1]; i++) + y[j+k*yLD] -= val[i] * x[ir[i]+k*xLD]; + else + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + for (i = jc[j]; i < jc[j+1]; i++) + y[j+k*yLD] += alpha * val[i] * x[ir[i]+k*xLD]; + + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrix::times( const Indexlist* const irows, const Indexlist* const icols, + int_t xN, real_t alpha, const real_t* x, int_t xLD, real_t beta, real_t* y, int_t yLD, + BooleanType yCompr ) const +{ + long i, j, k, l, col; + real_t xcol; + + if ( isEqual(alpha,0.0) == BT_TRUE ) + { + if (yCompr == BT_TRUE) + { + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] *= beta; + } + else + { + if (isZero( beta ) == BT_TRUE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = 0.0; + else if (isEqual( beta, -1.0 ) == BT_TRUE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = -y[irows->number[j]+k*yLD]; + else if (isEqual( beta, 1.0 ) == BT_FALSE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] *= beta; + } + return SUCCESSFUL_RETURN; + } + + // First, work with full, unordered copy of y and store matrix times x in there + const int_t yfullLength = nRows; + real_t* ytmp = new real_t[xN*yfullLength]; + for (k = 0; k < xN*yfullLength; k++) + ytmp[k] = 0.0; + + if (icols!=0) + { + if (xN==1) + { + for (l = 0; l < icols->length; l++) + { + col = icols->iSort[l]; + xcol = x[col]; + if (isZero( xcol ) == BT_FALSE) + { + j = icols->number[col]; + for (i = jc[j]; i < jc[j+1]; i++) + ytmp[ir[i]] += val[i] * xcol; + } + } + } + else + { + // AW: I didn't test the case xN>1, but I hope it is working + real_t* xcols = new real_t[xN]; + for (l = 0; l < icols->length; l++) + { + col = icols->iSort[l]; + real_t xmax = 0.0; + for (k=0; knumber[col]; + for (i = jc[j]; i < jc[j+1]; i++) + for (k=0; k1, but I hope it is working + real_t* xcols = new real_t[xN]; + for (col = 0; col < nCols; col++) + { + real_t xmax = 0.0; + for (k=0; klength; j++) + y[j+k*yLD] = alpha*ytmp[irows->number[j]+k*yfullLength]; + else if (isEqual( beta, 1.0 ) == BT_TRUE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] += alpha*ytmp[irows->number[j]+k*yfullLength]; + else if (isEqual( beta, -1.0 ) == BT_TRUE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] = alpha*ytmp[irows->number[j]+k*yfullLength]-y[j+k*yLD]; + else if (isEqual( beta, 1.0 ) == BT_FALSE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] = alpha*ytmp[irows->number[j]+k*yfullLength]+beta*y[j+k*yLD]; + } + else + { + if (isZero( beta ) == BT_TRUE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = alpha*ytmp[irows->number[j]+k*yfullLength]; + else if (isEqual( beta, 1.0 ) == BT_TRUE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = alpha*ytmp[irows->number[j]+k*yfullLength]+y[j+k*yLD]; + else if (isEqual( beta, -1.0 ) == BT_TRUE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = alpha*ytmp[irows->number[j]+k*yfullLength]-y[j+k*yLD]; + else if (isEqual( beta, 1.0 ) == BT_FALSE) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = alpha*ytmp[irows->number[j]+k*yfullLength]+beta*y[j+k*yLD]; + } + + delete [] ytmp; + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrix::transTimes( const Indexlist* const irows, const Indexlist* const icols, + int_t xN, real_t alpha, const real_t* x, int_t xLD, real_t beta, real_t* y, int_t yLD ) const +{ + long i, j, k, l, col; + real_t yadd; + + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] *= beta; + if ( isEqual(alpha,0.0) == BT_TRUE ) + return SUCCESSFUL_RETURN; + + // work with full, unordered copy of x + const int_t xfullLength = nRows; + real_t* xtmp = new real_t[xfullLength]; + for (k = 0; k < xN; k++) + { + for (i = 0; i < xfullLength; i++) + xtmp[i] = 0.0; + for (i = 0; i < irows->length; i++) + xtmp[irows->number[i]] = x[k*xLD+i]; + for (l = 0; l < icols->length; l++) + { + col = icols->iSort[l]; + yadd = 0.0; + j = icols->number[col]; + for (i = jc[j]; i < jc[j+1]; i++) + yadd += val[i] * xtmp[ir[i]]; + y[col] += alpha*yadd; + } + y += yLD; // move on to next RHS + } + + delete [] xtmp; + + return SUCCESSFUL_RETURN; +} + + + +returnValue SparseMatrix::addToDiag( real_t alpha ) +{ + long i; + + if ( jd == 0 ) + return THROWERROR( RET_DIAGONAL_NOT_INITIALISED ); + + if ( isZero( alpha ) == BT_FALSE ) + { + for (i = 0; i < nRows && i < nCols; i++) + { + if (ir[jd[i]] == i) + val[jd[i]] += alpha; + else + return RET_NO_DIAGONAL_AVAILABLE; + } + } + + return SUCCESSFUL_RETURN; +} + + +sparse_int_t* SparseMatrix::createDiagInfo( ) +{ + sparse_int_t i, j; + + if (jd == 0) { + jd = new sparse_int_t[nCols]; + + for (j = 0; j < nCols; j++) + { + for (i = jc[j]; i < jc[j+1] && ir[i] < j; i++); + jd[j] = i; + } + } + + return jd; +} + + + +real_t* SparseMatrix::full( ) const +{ + sparse_int_t i, j; + real_t* v = new real_t[nRows*nCols]; + + for (i = 0; i < nCols*nRows; i++) + v[i] = 0.0; + + for (j = 0; j < nCols; j++) + for (i = jc[j]; i < jc[j+1]; i++) + v[ir[i] * nCols + j] = val[i]; + + return v; +} + + +returnValue SparseMatrix::print( const char* name ) const +{ + real_t* tmp = this->full(); + returnValue retVal = REFER_NAMESPACE_QPOASES print( tmp,nRows,nCols,name ); + delete[] tmp; + + return retVal; +} + +returnValue SparseMatrix::writeToFile( FILE* output_file, const char* prefix ) const +{ + for (int_t i=0; i<=nCols; i++) { + fprintf( output_file,"%sjc[%d] = %d\n",prefix,(int)i,(int)(jc[i]) ); + } + for (int_t i=0; inRows = nRows; + dupl->nCols = nCols; + dupl->jr = new sparse_int_t[nRows+1]; + dupl->ic = new sparse_int_t[length]; + dupl->val = new real_t[length]; + + for (i = 0; i < length; i++) dupl->jr[i] = jr[i]; + for (i = 0; i <= nCols; i++) dupl->ic[i] = ic[i]; + for (i = 0; i < length; i++) dupl->val[i] = val[i]; + + if ( jd != 0 ) + { + dupl->jd = new sparse_int_t[nRows]; + for (i = 0; i < nCols; i++) dupl->jd[i] = jd[i]; + } + else + dupl->jd = 0; + + dupl->doFreeMemory( ); + + return dupl; +} + + + +real_t SparseMatrixRow::diag( int_t i ) const +{ + if ( jd == 0 ) + { + THROWERROR( RET_DIAGONAL_NOT_INITIALISED ); + return INFTY; + } + + int_t entry = jd[i]; + return (entry < jr[i+1] && ic[entry] == i) ? val[entry] : 0.0; +} + + +BooleanType SparseMatrixRow::isDiag( ) const +{ + int_t i; + + if ( nCols != nRows ) + return BT_FALSE; + + for (i = 0; i < nRows; ++i) + { + if ( jr[i+1] > jr[i]+1 ) + return BT_FALSE; + + if ( ( jr[i+1] == jr[i]+1 ) && ( ic[jr[i]] != i ) ) + return BT_FALSE; + } + + return BT_TRUE; +} + + + +real_t SparseMatrixRow::getNorm( int_t type + ) const +{ + int_t length = jr[nRows]; + return REFER_NAMESPACE_QPOASES getNorm( val,length,type ); + +} + + +real_t SparseMatrixRow::getRowNorm( int_t rNum, int_t type ) const +{ + int_t length = jr[rNum+1] - jr[rNum]; + return REFER_NAMESPACE_QPOASES getNorm( &(val[jr[rNum]]),length,type ); +} + + +returnValue SparseMatrixRow::getRowNorm( real_t* norm, int_t type ) const +{ + int_t i; + for (i = 0; i < nRows; ++i) + { + int_t length = jr[i+1] - jr[i]; + norm[i] = REFER_NAMESPACE_QPOASES getNorm( &(val[jr[i]]),length,type ); + } + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrixRow::getRow( int_t rNum, const Indexlist* const icols, real_t alpha, real_t* row ) const +{ + long i, j; + + if (icols != 0) + { + j = jr[rNum]; + i = 0; + if ( isEqual(alpha,1.0) == BT_TRUE ) + while (j < jr[rNum+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + row[icols->iSort[i++]] = val[j++]; + else if (ic[j] > icols->number[icols->iSort[i]]) + row[icols->iSort[i++]] = 0.0; + else + j++; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + while (j < jr[rNum+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + row[icols->iSort[i++]] = -val[j++]; + else if (ic[j] > icols->number[icols->iSort[i]]) + row[icols->iSort[i++]] = 0.0; + else + j++; + else + while (j < jr[rNum+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + row[icols->iSort[i++]] = alpha * val[j++]; + else if (ic[j] > icols->number[icols->iSort[i]]) + row[icols->iSort[i++]] = 0.0; + else + j++; + + /* fill in remaining zeros */ + while (i < icols->length) + row[icols->iSort[i++]] = 0.0; + } + else + { + for (i = 0; i < nCols; i++) + row[i] = 0; + + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (j = jr[rNum]; j < jr[rNum+1]; j++) + row[ic[j]] = val[j]; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (j = jr[rNum]; j < jr[rNum+1]; j++) + row[ic[j]] = -val[j]; + else + for (j = jr[rNum]; j < jr[rNum+1]; j++) + row[ic[j]] = alpha * val[j]; + } + + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrixRow::getCol( int_t cNum, const Indexlist* const irows, real_t alpha, real_t* col ) const +{ + long i, j, k, srt; + + if (irows != 0) + { + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < irows->length; k++) + { + srt = irows->iSort[k]; + j = irows->number[srt]; + for (i = jr[j]; i < jr[j+1] && ic[i] < cNum; i++); + col[srt] = (i < jr[j+1] && ic[i] == cNum) ? val[i] : 0.0; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < irows->length; k++) + { + srt = irows->iSort[k]; + j = irows->number[srt]; + for (i = jr[j]; i < jr[j+1] && ic[i] < cNum; i++); + col[srt] = (i < jr[j+1] && ic[i] == cNum) ? -val[i] : 0.0; + } + else + for (k = 0; k < irows->length; k++) + { + srt = irows->iSort[k]; + j = irows->number[srt]; + for (i = jr[j]; i < jr[j+1] && ic[i] < cNum; i++); + col[srt] = (i < jr[j+1] && ic[i] == cNum) ? alpha*val[i] : 0.0; + } + } + else + { + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (j = 0; j < nCols; j++) + { + for (i = jr[j]; i < jr[j+1] && ic[i] < cNum; i++); + col[j] = (i < jr[j+1] && ic[i] == cNum) ? val[i] : 0.0; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (j = 0; j < irows->length; j++) + { + for (i = jr[j]; i < jr[j+1] && ic[i] < cNum; i++); + col[j] = (i < jr[j+1] && ic[i] == cNum) ? -val[i] : 0.0; + } + else + for (j = 0; j < irows->length; j++) + { + for (i = jr[j]; i < jr[j+1] && ic[i] < cNum; i++); + col[j] = (i < jr[j+1] && ic[i] == cNum) ? alpha*val[i] : 0.0; + } + } + return SUCCESSFUL_RETURN; +} + +returnValue SparseMatrixRow::getSparseSubmatrix ( + int_t irowsLength, const int_t* const irowsNumber, + int_t icolsLength, const int_t* const icolsNumber, + int_t rowoffset, int_t coloffset, int_t& numNonzeros, int_t* irn, + int_t* jcn, real_t* avals, BooleanType only_lower_triangular /*= BT_FALSE */) const +{ + fprintf(stderr, "SparseMatrixRow::getSparseSubmatrix not implemented!\n"); + + return THROWERROR(RET_NOT_YET_IMPLEMENTED); +} + +returnValue SparseMatrixRow::times( int_t xN, real_t alpha, const real_t* x, int_t xLD, + real_t beta, real_t* y, int_t yLD ) const +{ + long i, j, k; + + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + y[j+k*yLD] *= beta; + + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + for (i = jr[j]; i < jr[j+1]; i++) + y[j+k*yLD] += val[i] * x[ic[i]+k*xLD]; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + for (i = jr[j]; i < jr[j+1]; i++) + y[j+k*yLD] -= val[i] * x[ic[i]+k*xLD]; + else + for (k = 0; k < xN; k++) + for (j = 0; j < nRows; j++) + for (i = jr[j]; i < jr[j+1]; i++) + y[j+k*yLD] += alpha * val[i] * x[ic[i]+k*xLD]; + + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrixRow::transTimes( int_t xN, real_t alpha, const real_t* x, int_t xLD, + real_t beta, real_t* y, int_t yLD ) const +{ + long i, j, k; + + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < nCols; j++) + y[j+k*yLD] *= beta; + + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (i = 0; i < nRows; i++) + for (j = jr[i]; j < jr[i+1]; j++) + y[ic[j]+k*yLD] += val[j] * x[i+k*xLD]; + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (i = 0; i < nRows; i++) + for (j = jr[i]; j < jr[i+1]; j++) + y[ic[j]+k*yLD] -= val[j] * x[i+k*xLD]; + else + for (k = 0; k < xN; k++) + for (i = 0; i < nRows; i++) + for (j = jr[i]; j < jr[i+1]; j++) + y[ic[j]+k*yLD] += alpha * val[j] * x[i+k*xLD]; + + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrixRow::times( const Indexlist* const irows, const Indexlist* const icols, + int_t xN, real_t alpha, const real_t* x, int_t xLD, real_t beta, real_t* y, int_t yLD, + BooleanType yCompr ) const +{ + long i, j, k, l, srt, row; + + if (yCompr == BT_TRUE) + { + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[j+k*yLD] *= beta; + + if (icols == 0) + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + for (j = jr[row]; j < jr[row+1]; j++) + for (k = 0; k < xN; k++) + y[k*yLD+srt] += val[j] * x[k*xLD+ic[j]]; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + for (j = jr[row]; j < jr[row+1]; j++) + for (k = 0; k < xN; k++) + y[k*yLD+srt] -= val[j] * x[k*xLD+ic[j]]; + } + else + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + for (j = jr[row]; j < jr[row+1]; j++) + for (k = 0; k < xN; k++) + y[k*yLD+srt] += alpha * val[j] * x[k*xLD+ic[j]]; + } + else /* icols != 0 */ + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + j = jr[row]; + i = 0; + while (j < jr[row+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+srt] += val[j] * x[k*xLD+icols->iSort[i]]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + j = jr[row]; + i = 0; + while (j < jr[row+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+srt] -= val[j] * x[k*xLD+icols->iSort[i]]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + else + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + j = jr[row]; + i = 0; + while (j < jr[row+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+srt] += alpha * val[j] * x[k*xLD+icols->iSort[i]]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + } + else /* y not compressed */ + { + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < irows->length; j++) + y[irows->number[j]+k*yLD] *= beta; + + if (icols == 0) + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + row = irows->number[irows->iSort[l]]; + for (j = jr[row]; j < jr[row+1]; j++) + for (k = 0; k < xN; k++) + y[k*yLD+row] += val[j] * x[k*xLD+ic[j]]; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + row = irows->number[irows->iSort[l]]; + for (j = jr[row]; j < jr[row+1]; j++) + for (k = 0; k < xN; k++) + y[k*yLD+row] -= val[j] * x[k*xLD+ic[j]]; + } + else + for (l = 0; l < irows->length; l++) + { + row = irows->number[irows->iSort[l]]; + for (j = jr[row]; j < jr[row+1]; j++) + for (k = 0; k < xN; k++) + y[k*yLD+row] += alpha * val[j] * x[k*xLD+ic[j]]; + } + else /* icols != 0 */ + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + row = irows->iSort[l]; + j = jr[irows->number[row]]; + i = 0; + while (j < jr[irows->number[row]+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+row] += val[j] * x[k*xLD+icols->iSort[i]]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + row = irows->iSort[l]; + j = jr[irows->number[row]]; + i = 0; + while (j < jr[irows->number[row]+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+row] -= val[j] * x[k*xLD+icols->iSort[i]]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + else + for (l = 0; l < irows->length; l++) + { + row = irows->iSort[l]; + j = jr[irows->number[row]]; + i = 0; + while (j < jr[irows->number[row]+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+row] += alpha * val[j] * x[k*xLD+icols->iSort[i]]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + } + return SUCCESSFUL_RETURN; +} + + +returnValue SparseMatrixRow::transTimes( const Indexlist* const irows, const Indexlist* const icols, + int_t xN, real_t alpha, const real_t* x, int_t xLD, real_t beta, real_t* y, int_t yLD ) const +{ + long i, j, k, l, row, srt; + + if ( isZero(beta) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] = 0.0; + else if ( isEqual(beta,-1.0) == BT_TRUE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] = -y[j+k*yLD]; + else if ( isEqual(beta,1.0) == BT_FALSE ) + for (k = 0; k < xN; k++) + for (j = 0; j < icols->length; j++) + y[j+k*yLD] *= beta; + + if ( isEqual(alpha,1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + j = jr[row]; + i = 0; + while (j < jr[row+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+icols->iSort[i]] += val[j] * x[k*xLD+srt]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + else if ( isEqual(alpha,-1.0) == BT_TRUE ) + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + j = jr[row]; + i = 0; + while (j < jr[row+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+icols->iSort[i]] -= val[j] * x[k*xLD+srt]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + else + for (l = 0; l < irows->length; l++) + { + srt = irows->iSort[l]; + row = irows->number[srt]; + j = jr[row]; + i = 0; + while (j < jr[row+1] && i < icols->length) + if (ic[j] == icols->number[icols->iSort[i]]) + { + for (k = 0; k < xN; k++) + y[k*yLD+icols->iSort[i]] += alpha * val[j] * x[k*xLD+srt]; + j++, i++; + } + else if (ic[j] > icols->number[icols->iSort[i]]) i++; + else j++; + } + + return SUCCESSFUL_RETURN; +} + + + +returnValue SparseMatrixRow::addToDiag( real_t alpha ) +{ + long i; + + if ( jd == 0 ) + return THROWERROR( RET_DIAGONAL_NOT_INITIALISED ); + + if ( isZero(alpha) == BT_FALSE ) + { + for (i = 0; i < nRows && i < nCols; i++) + { + if (ic[jd[i]] == i) + val[jd[i]] += alpha; + else + return RET_NO_DIAGONAL_AVAILABLE; + } + } + + return SUCCESSFUL_RETURN; +} + + +sparse_int_t* SparseMatrixRow::createDiagInfo( ) +{ + sparse_int_t i, j; + + if (jd == 0) { + jd = new sparse_int_t[nRows]; + + for (i = 0; i < nRows; i++) + { + for (j = jr[i]; j < jr[i+1] && ic[j] < i; j++); + jd[i] = j; + } + } + + return jd; +} + + +real_t* SparseMatrixRow::full( ) const +{ + sparse_int_t i, j; + real_t* v = new real_t[nRows*nCols]; + + for (i = 0; i < nCols*nRows; i++) + v[i] = 0.0; + + for (i = 0; i < nRows; i++) + for (j = jr[i]; j < jr[i+1]; j++) + v[ic[j] + i * nCols] = val[j]; + + return v; +} + + +returnValue SparseMatrixRow::print( const char* name ) const +{ + real_t* tmp = this->full(); + returnValue retVal = REFER_NAMESPACE_QPOASES print( tmp,nRows,nCols,name ); + delete[] tmp; + + return retVal; +} + +returnValue SparseMatrixRow::writeToFile( FILE* output_file, const char* prefix ) const +{ + return THROWERROR( RET_NOT_YET_IMPLEMENTED ); +} + +Matrix *SymSparseMat::duplicate() const +{ + return duplicateSym(); +} + + +SymmetricMatrix *SymSparseMat::duplicateSym( ) const +{ + /* "same" as duplicate() in SparseMatrix */ + long i, length = jc[nCols]; + SymSparseMat *dupl = new SymSparseMat; + + dupl->nRows = nRows; + dupl->nCols = nCols; + dupl->ir = new sparse_int_t[length]; + dupl->jc = new sparse_int_t[nCols+1]; + dupl->val = new real_t[length]; + + for (i = 0; i < length; i++) dupl->ir[i] = ir[i]; + for (i = 0; i <= nCols; i++) dupl->jc[i] = jc[i]; + for (i = 0; i < length; i++) dupl->val[i] = val[i]; + + if ( jd != 0 ) + { + dupl->jd = new sparse_int_t[nCols]; + for (i = 0; i < nCols; i++) dupl->jd[i] = jd[i]; + } + else + dupl->jd = 0; + + dupl->doFreeMemory( ); + + return dupl; +} + + +returnValue SymSparseMat::bilinear( const Indexlist* const icols, + int_t xN, const real_t* x, int_t xLD, real_t* y, int_t yLD ) const +{ + int_t i, j, k, l, idx, row, col; + + if ( jd == 0 ) + return THROWERROR( RET_DIAGONAL_NOT_INITIALISED ); + + /* clear output */ + for (i = 0; i < xN*xN; i++) + y[i] = 0.0; + + /* compute lower triangle */ + for (l = 0; l < icols->length; l++) + { + col = icols->number[icols->iSort[l]]; + idx = jd[col]; + k = 0; + while (idx < jc[col+1] && k < icols->length) + { + row = icols->number[icols->iSort[k]]; + if (ir[idx] == row) + { + /* TODO: It is possible to formulate this as DSYR and DSYR2 + * operations. */ + if (row == col) /* diagonal element */ + for (i = 0; i < xN; i++) + for (j = i; j < xN; j++) + y[i*yLD+j] += val[idx] * x[i*xLD+col] * x[j*xLD+col]; + else /* subdiagonal elements */ + for (i = 0; i < xN; i++) + for (j = i; j < xN; j++) + y[i*yLD+j] += val[idx] * (x[i*xLD+col] * x[j*xLD+row] + x[i*xLD+row] * x[j*xLD+col]); + idx++, k++; + } + else if (ir[idx] > row) k++; + else idx++; + } + } + + /* fill upper triangle */ + for (i = 0; i < xN; i++) + for (j = i; j < xN; j++) + y[j*yLD+i] = y[i*yLD+j]; + + return SUCCESSFUL_RETURN; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/MessageHandling.cpp b/locomotion/src/third_party/qpOASES/src/MessageHandling.cpp new file mode 100644 index 0000000..3b21ebd --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/MessageHandling.cpp @@ -0,0 +1,632 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/MessageHandling.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the MessageHandling class including global return values. + * + */ + + +#include + +#ifdef __MATLAB__ + #include "mex.h" +#endif + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + +/** Default file to display messages. */ +FILE* stdFile = stdout; + + + +#ifndef __SUPPRESSANYOUTPUT__ + +/** Defines pairs of global return values and messages. */ +MessageHandling::ReturnValueList returnValueList[] = +{ +/* miscellaneous */ +{ SUCCESSFUL_RETURN, "Successful return", VS_VISIBLE }, +{ RET_DIV_BY_ZERO, "Division by zero", VS_VISIBLE }, +{ RET_INDEX_OUT_OF_BOUNDS, "Index out of bounds", VS_VISIBLE }, +{ RET_INVALID_ARGUMENTS, "At least one of the arguments is invalid", VS_VISIBLE }, +{ RET_ERROR_UNDEFINED, "Error number undefined", VS_VISIBLE }, +{ RET_WARNING_UNDEFINED, "Warning number undefined", VS_VISIBLE }, +{ RET_INFO_UNDEFINED, "Info number undefined", VS_VISIBLE }, +{ RET_EWI_UNDEFINED, "Error/warning/info number undefined", VS_VISIBLE }, +{ RET_AVAILABLE_WITH_LINUX_ONLY, "This function is available under Linux only", VS_HIDDEN }, +{ RET_UNKNOWN_BUG, "The error occurred is not yet known", VS_VISIBLE }, +{ RET_PRINTLEVEL_CHANGED, "Print level changed", VS_VISIBLE }, +{ RET_NOT_YET_IMPLEMENTED, "Requested function is not yet implemented.", VS_VISIBLE }, +/* Indexlist */ +{ RET_INDEXLIST_MUST_BE_REORDERD, "Index list has to be reordered", VS_VISIBLE }, +{ RET_INDEXLIST_EXCEEDS_MAX_LENGTH, "Index list exceeds its maximal physical length", VS_VISIBLE }, +{ RET_INDEXLIST_CORRUPTED, "Index list corrupted", VS_VISIBLE }, +{ RET_INDEXLIST_OUTOFBOUNDS, "Physical index is out of bounds", VS_VISIBLE }, +{ RET_INDEXLIST_ADD_FAILED, "Adding indices from another index set failed", VS_VISIBLE }, +{ RET_INDEXLIST_INTERSECT_FAILED, "Intersection with another index set failed", VS_VISIBLE }, +/* SubjectTo / Bounds / Constraints */ +{ RET_INDEX_ALREADY_OF_DESIRED_STATUS, "Index is already of desired status", VS_VISIBLE }, +{ RET_ADDINDEX_FAILED, "Adding index to index set failed", VS_VISIBLE }, +{ RET_REMOVEINDEX_FAILED, "Removing index from index set failed", VS_VISIBLE }, +{ RET_SWAPINDEX_FAILED, "Cannot swap between different indexsets", VS_VISIBLE }, +{ RET_NOTHING_TO_DO, "Nothing to do", VS_VISIBLE }, +{ RET_SETUP_BOUND_FAILED, "Setting up bound index failed", VS_VISIBLE }, +{ RET_SETUP_CONSTRAINT_FAILED, "Setting up constraint index failed", VS_VISIBLE }, +{ RET_MOVING_BOUND_FAILED, "Moving bound between index sets failed", VS_VISIBLE }, +{ RET_MOVING_CONSTRAINT_FAILED, "Moving constraint between index sets failed", VS_VISIBLE }, +{ RET_SHIFTING_FAILED, "Shifting of bounds/constraints failed", VS_VISIBLE }, +{ RET_ROTATING_FAILED, "Rotating of bounds/constraints failed", VS_VISIBLE }, +/* QProblem */ +{ RET_QPOBJECT_NOT_SETUP, "The QP object has not been setup correctly, use another constructor", VS_VISIBLE }, +{ RET_QP_ALREADY_INITIALISED, "QProblem has already been initialised", VS_VISIBLE }, +{ RET_NO_INIT_WITH_STANDARD_SOLVER, "Initialisation via extern QP solver is not yet implemented", VS_VISIBLE }, +{ RET_RESET_FAILED, "Reset failed", VS_VISIBLE }, +{ RET_INIT_FAILED, "Initialisation failed", VS_VISIBLE }, +{ RET_INIT_FAILED_TQ, "Initialisation failed due to TQ factorisation", VS_VISIBLE }, +{ RET_INIT_FAILED_CHOLESKY, "Initialisation failed due to Cholesky decomposition", VS_VISIBLE }, +{ RET_INIT_FAILED_HOTSTART, "Initialisation failed! QP could not be solved!", VS_VISIBLE }, +{ RET_INIT_FAILED_INFEASIBILITY, "Initial QP could not be solved due to infeasibility!", VS_VISIBLE }, +{ RET_INIT_FAILED_UNBOUNDEDNESS, "Initial QP could not be solved due to unboundedness!", VS_VISIBLE }, +{ RET_INIT_FAILED_REGULARISATION, "Initialisation failed as Hessian matrix could not be regularised", VS_VISIBLE }, +{ RET_INIT_SUCCESSFUL, "Initialisation done", VS_VISIBLE }, +{ RET_OBTAINING_WORKINGSET_FAILED, "Failed to obtain working set for auxiliary QP", VS_VISIBLE }, +{ RET_SETUP_WORKINGSET_FAILED, "Failed to setup working set for auxiliary QP", VS_VISIBLE }, +{ RET_SETUP_AUXILIARYQP_FAILED, "Failed to setup auxiliary QP for initialised homotopy", VS_VISIBLE }, +{ RET_NO_CHOLESKY_WITH_INITIAL_GUESS, "Externally computed Cholesky factor cannot be combined with an initial guess", VS_VISIBLE }, +{ RET_NO_EXTERN_SOLVER, "No extern QP solver available", VS_VISIBLE }, +{ RET_QP_UNBOUNDED, "QP is unbounded", VS_VISIBLE }, +{ RET_QP_INFEASIBLE, "QP is infeasible", VS_VISIBLE }, +{ RET_QP_NOT_SOLVED, "Problems occurred while solving QP with standard solver", VS_VISIBLE }, +{ RET_QP_SOLVED, "QP successfully solved", VS_VISIBLE }, +{ RET_UNABLE_TO_SOLVE_QP, "Problems occurred while solving QP", VS_VISIBLE }, +{ RET_INITIALISATION_STARTED, "Starting problem initialisation...", VS_VISIBLE }, +{ RET_HOTSTART_FAILED, "Unable to perform homotopy due to internal error", VS_VISIBLE }, +{ RET_HOTSTART_FAILED_TO_INIT, "Unable to initialise problem", VS_VISIBLE }, +{ RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED, "Unable to perform homotopy as previous QP is not solved", VS_VISIBLE }, +{ RET_ITERATION_STARTED, "Iteration", VS_VISIBLE }, +{ RET_SHIFT_DETERMINATION_FAILED, "Determination of shift of the QP data failed", VS_VISIBLE }, +{ RET_STEPDIRECTION_DETERMINATION_FAILED, "Determination of step direction failed", VS_VISIBLE }, +{ RET_STEPLENGTH_DETERMINATION_FAILED, "Determination of step direction failed", VS_VISIBLE }, +{ RET_OPTIMAL_SOLUTION_FOUND, "Optimal solution of neighbouring QP found", VS_VISIBLE }, +{ RET_HOMOTOPY_STEP_FAILED, "Unable to perform homotopy step", VS_VISIBLE }, +{ RET_HOTSTART_STOPPED_INFEASIBILITY, "Premature homotopy termination because QP is infeasible", VS_VISIBLE }, +{ RET_HOTSTART_STOPPED_UNBOUNDEDNESS, "Premature homotopy termination because QP is unbounded", VS_VISIBLE }, +{ RET_WORKINGSET_UPDATE_FAILED, "Unable to update working sets according to initial guesses", VS_VISIBLE }, +{ RET_MAX_NWSR_REACHED, "Maximum number of working set recalculations performed", VS_VISIBLE }, +{ RET_CONSTRAINTS_NOT_SPECIFIED, "Problem does comprise constraints! You have to specify new constraints' bounds", VS_VISIBLE }, +{ RET_INVALID_FACTORISATION_FLAG, "Invalid factorisation flag", VS_VISIBLE }, +{ RET_UNABLE_TO_SAVE_QPDATA, "Unable to save QP data", VS_VISIBLE }, +{ RET_STEPDIRECTION_FAILED_TQ, "Abnormal termination due to TQ factorisation", VS_VISIBLE }, +{ RET_STEPDIRECTION_FAILED_CHOLESKY, "Abnormal termination due to Cholesky factorisation", VS_VISIBLE }, +{ RET_CYCLING_DETECTED, "Cycling detected", VS_VISIBLE }, +{ RET_CYCLING_NOT_RESOLVED, "Cycling cannot be resolved, QP is probably infeasible", VS_VISIBLE }, +{ RET_CYCLING_RESOLVED, "Cycling probably resolved", VS_VISIBLE }, +{ RET_STEPSIZE, "", VS_VISIBLE }, +{ RET_STEPSIZE_NONPOSITIVE, "", VS_VISIBLE }, +{ RET_SETUPSUBJECTTOTYPE_FAILED, "Setup of SubjectToTypes failed", VS_VISIBLE }, +{ RET_ADDCONSTRAINT_FAILED, "Addition of constraint to working set failed", VS_VISIBLE }, +{ RET_ADDCONSTRAINT_FAILED_INFEASIBILITY, "Addition of constraint to working set failed", VS_VISIBLE }, +{ RET_ADDBOUND_FAILED, "Addition of bound to working set failed", VS_VISIBLE }, +{ RET_ADDBOUND_FAILED_INFEASIBILITY, "Addition of bound to working set failed", VS_VISIBLE }, +{ RET_REMOVECONSTRAINT_FAILED, "Removal of constraint from working set failed", VS_VISIBLE }, +{ RET_REMOVEBOUND_FAILED, "Removal of bound from working set failed", VS_VISIBLE }, +{ RET_REMOVE_FROM_ACTIVESET, "Removing from active set:", VS_VISIBLE }, +{ RET_ADD_TO_ACTIVESET, "Adding to active set:", VS_VISIBLE }, +{ RET_REMOVE_FROM_ACTIVESET_FAILED, "Removing from active set failed", VS_VISIBLE }, +{ RET_ADD_TO_ACTIVESET_FAILED, "Adding to active set failed", VS_VISIBLE }, +{ RET_CONSTRAINT_ALREADY_ACTIVE, "Constraint is already active", VS_VISIBLE }, +{ RET_ALL_CONSTRAINTS_ACTIVE, "All constraints are active, no further constraint can be added", VS_VISIBLE }, +{ RET_LINEARLY_DEPENDENT, "New bound/constraint is linearly dependent", VS_VISIBLE }, +{ RET_LINEARLY_INDEPENDENT, "New bound/constraint is linearly independent", VS_VISIBLE }, +{ RET_LI_RESOLVED, "Linear independence of active constraint matrix successfully resolved", VS_VISIBLE }, +{ RET_ENSURELI_FAILED, "Failed to ensure linear independence of active constraint matrix", VS_VISIBLE }, +{ RET_ENSURELI_FAILED_TQ, "Abnormal termination due to TQ factorisation", VS_VISIBLE }, +{ RET_ENSURELI_FAILED_NOINDEX, "QP is infeasible", VS_VISIBLE }, +{ RET_ENSURELI_FAILED_CYCLING, "QP is infeasible", VS_VISIBLE }, +{ RET_BOUND_ALREADY_ACTIVE, "Bound is already active", VS_VISIBLE }, +{ RET_ALL_BOUNDS_ACTIVE, "All bounds are active, no further bound can be added", VS_VISIBLE }, +{ RET_CONSTRAINT_NOT_ACTIVE, "Constraint is not active", VS_VISIBLE }, +{ RET_BOUND_NOT_ACTIVE, "Bound is not active", VS_VISIBLE }, +{ RET_HESSIAN_NOT_SPD, "Projected Hessian matrix not positive definite", VS_VISIBLE }, +{ RET_HESSIAN_INDEFINITE, "Hessian matrix is indefinite", VS_VISIBLE }, +{ RET_MATRIX_SHIFT_FAILED, "Unable to update matrices or to transform vectors", VS_VISIBLE }, +{ RET_MATRIX_FACTORISATION_FAILED, "Unable to calculate new matrix factorisations", VS_VISIBLE }, +{ RET_PRINT_ITERATION_FAILED, "Unable to print information on current iteration", VS_VISIBLE }, +{ RET_NO_GLOBAL_MESSAGE_OUTPUTFILE, "No global message output file initialised", VS_VISIBLE }, +{ RET_DISABLECONSTRAINTS_FAILED, "Unable to disable constraints", VS_VISIBLE }, +{ RET_ENABLECONSTRAINTS_FAILED, "Unable to enable constraints", VS_VISIBLE }, +{ RET_ALREADY_ENABLED, "Bound or constraint is already enabled", VS_VISIBLE }, +{ RET_ALREADY_DISABLED, "Bound or constraint is already disabled", VS_VISIBLE }, +{ RET_NO_HESSIAN_SPECIFIED, "No Hessian matrix has been specified", VS_VISIBLE }, +{ RET_USING_REGULARISATION, "Using regularisation as Hessian matrix is not positive definite", VS_VISIBLE }, +{ RET_EPS_MUST_BE_POSITVE, "Eps for regularisation must be sufficiently positive", VS_VISIBLE }, +{ RET_REGSTEPS_MUST_BE_POSITVE, "Maximum number of regularisation steps must be non-negative", VS_VISIBLE }, +{ RET_HESSIAN_ALREADY_REGULARISED, "Hessian has been already regularised", VS_VISIBLE }, +{ RET_CANNOT_REGULARISE_IDENTITY, "Identity Hessian matrix cannot be regularised", VS_VISIBLE }, +{ RET_CANNOT_REGULARISE_SPARSE, "Sparse matrix cannot be regularised as diagonal entry is missing", VS_VISIBLE }, +{ RET_NO_REGSTEP_NWSR, "No additional regularisation step could be performed due to limits", VS_VISIBLE }, +{ RET_FEWER_REGSTEPS_NWSR, "Fewer additional regularisation steps have been performed due to limits", VS_VISIBLE }, +{ RET_CHOLESKY_OF_ZERO_HESSIAN, "Cholesky decomposition of (unregularised) zero Hessian matrix", VS_VISIBLE }, +{ RET_ZERO_HESSIAN_ASSUMED, "Zero Hessian matrix assumed as null pointer passed without specifying hessianType", VS_VISIBLE }, +{ RET_CONSTRAINTS_ARE_NOT_SCALED, "(should not be thrown, no longer in use)", VS_VISIBLE }, +{ RET_INITIAL_BOUNDS_STATUS_NYI, "(should not be thrown, no longer in use)", VS_VISIBLE }, +{ RET_ERROR_IN_CONSTRAINTPRODUCT, "Error in user-defined constraint product function", VS_VISIBLE }, +{ RET_FIX_BOUNDS_FOR_LP, "All initial bounds must be fixed when solving an (unregularised) LP", VS_VISIBLE }, +{ RET_USE_REGULARISATION_FOR_LP, "Set options.enableRegularisation=BT_TRUE for solving LPs", VS_VISIBLE }, +/* SQProblem */ +{ RET_UPDATEMATRICES_FAILED, "Unable to update QP matrices", VS_VISIBLE }, +{ RET_UPDATEMATRICES_FAILED_AS_QP_NOT_SOLVED, "Unable to update matrices as previous QP is not solved", VS_VISIBLE }, +/* Utils */ +{ RET_UNABLE_TO_OPEN_FILE, "Unable to open file", VS_VISIBLE }, +{ RET_UNABLE_TO_WRITE_FILE, "Unable to write into file", VS_VISIBLE }, +{ RET_UNABLE_TO_READ_FILE, "Unable to read from file", VS_VISIBLE }, +{ RET_FILEDATA_INCONSISTENT, "File contains inconsistent data", VS_VISIBLE }, +/* Options */ +{ RET_OPTIONS_ADJUSTED, "Options needed to be adjusted for consistency reasons", VS_VISIBLE }, +/* SolutionAnalysis */ +{ RET_UNABLE_TO_ANALYSE_QPROBLEM, "Unable to analyse (S)QProblem(B) object", VS_VISIBLE }, +/* Benchmark */ +{ RET_NWSR_SET_TO_ONE, "Maximum number of working set changes was set to 1", VS_VISIBLE }, +{ RET_UNABLE_TO_READ_BENCHMARK, "Unable to read benchmark data", VS_VISIBLE }, +{ RET_BENCHMARK_ABORTED, "Benchmark aborted", VS_VISIBLE }, +{ RET_INITIAL_QP_SOLVED, "Initial QP solved", VS_VISIBLE }, +{ RET_QP_SOLUTION_STARTED, "Solving QP no.", VS_VISIBLE }, +{ RET_BENCHMARK_SUCCESSFUL, "Benchmark terminated successfully", VS_VISIBLE }, +/* Sparse matrices */ +{ RET_NO_DIAGONAL_AVAILABLE, "Sparse matrix does not have entries on full diagonal", VS_VISIBLE }, +{ RET_DIAGONAL_NOT_INITIALISED, "Diagonal data of sparse matrix has not been initialised", VS_VISIBLE }, +/* Dropping of infeasible constraints */ +{ RET_ENSURELI_DROPPED, "Linear independence resolved by dropping blocking constraint", VS_VISIBLE }, +/* Schur complement computations */ +{ RET_KKT_MATRIX_SINGULAR, "KKT matrix is singular", VS_VISIBLE }, +{ RET_QR_FACTORISATION_FAILED, "QR factorization of Schur complement failed", VS_VISIBLE }, +{ RET_INERTIA_CORRECTION_FAILED, "Inertia correction of KKT matrix failed", VS_VISIBLE }, +{ RET_NO_SPARSE_SOLVER, "No Sparse Solver installed", VS_VISIBLE }, +/* Simple exitflags */ +{ RET_SIMPLE_STATUS_P1, "QP problem could not be solved within given number of iterations", VS_VISIBLE }, +{ RET_SIMPLE_STATUS_P0, "QP problem solved", VS_VISIBLE }, +{ RET_SIMPLE_STATUS_M1, "QP problem could not be solved due to an internal error", VS_VISIBLE }, +{ RET_SIMPLE_STATUS_M2, "QP problem is infeasible (and thus could not be solved)", VS_VISIBLE }, +{ RET_SIMPLE_STATUS_M3, "QP problem is unbounded (and thus could not be solved)", VS_VISIBLE }, +/* IMPORTANT: Terminal list element! */ +{ TERMINAL_LIST_ELEMENT, "", VS_HIDDEN } +}; + +#else /* __SUPPRESSANYOUTPUT__ */ + +MessageHandling::ReturnValueList returnValueList[1]; /* Do not use messages for embedded platforms! */ + +#endif /* __SUPPRESSANYOUTPUT__ */ + + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + +/* + * M e s s a g e H a n d l i n g + */ +MessageHandling::MessageHandling( ) +{ + errorVisibility = VS_VISIBLE; + warningVisibility = VS_VISIBLE; + infoVisibility = VS_VISIBLE; + + outputFile = stdFile; + errorCount = 0; +} + +/* + * M e s s a g e H a n d l i n g + */ +MessageHandling::MessageHandling( FILE* _outputFile ) +{ + errorVisibility = VS_VISIBLE; + warningVisibility = VS_HIDDEN; + infoVisibility = VS_HIDDEN; + + outputFile = _outputFile; + errorCount = 0; +} + +/* + * M e s s a g e H a n d l i n g + */ +MessageHandling::MessageHandling( VisibilityStatus _errorVisibility, + VisibilityStatus _warningVisibility, + VisibilityStatus _infoVisibility + ) +{ + errorVisibility = _errorVisibility; + warningVisibility = _warningVisibility; + infoVisibility = _infoVisibility; + + outputFile = stdFile; + errorCount = 0; +} + +/* + * M e s s a g e H a n d l i n g + */ +MessageHandling::MessageHandling( FILE* _outputFile, + VisibilityStatus _errorVisibility, + VisibilityStatus _warningVisibility, + VisibilityStatus _infoVisibility + ) +{ + errorVisibility = _errorVisibility; + warningVisibility = _warningVisibility; + infoVisibility = _infoVisibility; + + outputFile = _outputFile; + errorCount = 0; +} + + + +/* + * M e s s a g e H a n d l i n g + */ +MessageHandling::MessageHandling( const MessageHandling& rhs ) +{ + errorVisibility = rhs.errorVisibility; + warningVisibility = rhs.warningVisibility; + infoVisibility = rhs.infoVisibility; + + outputFile = rhs.outputFile; + errorCount = rhs.errorCount; +} + + +/* + * ~ M e s s a g e H a n d l i n g + */ +MessageHandling::~MessageHandling( ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + if ( ( outputFile != 0 ) && ( outputFile != stdout ) && ( outputFile != stderr ) ) + fclose( outputFile ); + #endif /* __SUPPRESSANYOUTPUT__ */ +} + + +/* + * o p e r a t o r = + */ +MessageHandling& MessageHandling::operator=( const MessageHandling& rhs ) +{ + if ( this != &rhs ) + { + errorVisibility = rhs.errorVisibility; + warningVisibility = rhs.warningVisibility; + infoVisibility = rhs.infoVisibility; + + outputFile = rhs.outputFile; + errorCount = rhs.errorCount; + } + + return *this; +} + + +/* + * t h r o w E r r o r + */ +returnValue MessageHandling::throwError( returnValue Enumber, + const char* additionaltext, + const char* functionname, + const char* filename, + const unsigned long linenumber, + VisibilityStatus localVisibilityStatus + ) +{ + /* consistency check */ + if ( Enumber <= SUCCESSFUL_RETURN ) + return throwError( RET_ERROR_UNDEFINED,0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + + /* Call to common throwMessage function if error shall be displayed. */ + if ( errorVisibility == VS_VISIBLE ) + return throwMessage( Enumber,additionaltext,functionname,filename,linenumber,localVisibilityStatus,"ERROR" ); + else + return Enumber; +} + + +/* + * t h r o w W a r n i n g + */ +returnValue MessageHandling::throwWarning( returnValue Wnumber, + const char* additionaltext, + const char* functionname, + const char* filename, + const unsigned long linenumber, + VisibilityStatus localVisibilityStatus + ) +{ + /* consistency check */ + if ( Wnumber <= SUCCESSFUL_RETURN ) + return throwError( RET_WARNING_UNDEFINED,0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + + /* Call to common throwMessage function if warning shall be displayed. */ + if ( warningVisibility == VS_VISIBLE ) + return throwMessage( Wnumber,additionaltext,functionname,filename,linenumber,localVisibilityStatus,"WARNING" ); + else + return Wnumber; +} + + +/* + * t h r o w I n f o + */ +returnValue MessageHandling::throwInfo( returnValue Inumber, + const char* additionaltext, + const char* functionname, + const char* filename, + const unsigned long linenumber, + VisibilityStatus localVisibilityStatus + ) +{ + /* consistency check */ + if ( Inumber < SUCCESSFUL_RETURN ) + return throwError( RET_INFO_UNDEFINED,0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + + /* Call to common throwMessage function if info shall be displayed. */ + if ( infoVisibility == VS_VISIBLE ) + return throwMessage( Inumber,additionaltext,functionname,filename,linenumber,localVisibilityStatus,"INFO" ); + else + return Inumber; +} + + +/* + * r e s e t + */ +returnValue MessageHandling::reset( ) +{ + setErrorVisibilityStatus( VS_VISIBLE ); + setWarningVisibilityStatus( VS_HIDDEN ); + setInfoVisibilityStatus( VS_HIDDEN ); + + setOutputFile( stdFile ); + setErrorCount( 0 ); + + return SUCCESSFUL_RETURN; +} + + +/* + * l i s t A l l M e s s a g e s + */ +returnValue MessageHandling::listAllMessages( ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + int_t keypos = 0; + char myPrintfString[MAX_STRING_LENGTH]; + + /* Run through whole returnValueList and print each item. */ + while ( returnValueList[keypos].key != TERMINAL_LIST_ELEMENT ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH," %d - %s \n",(int)keypos,returnValueList[keypos].data ); + myPrintf( myPrintfString ); + + ++keypos; + } + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + + +/* + * t h r o w M e s s a g e + */ +returnValue MessageHandling::throwMessage( returnValue RETnumber, + const char* additionaltext, + const char* functionname, + const char* filename, + const unsigned long linenumber, + VisibilityStatus localVisibilityStatus, + const char* RETstring + ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + int_t keypos = 0; + char myPrintfString[MAX_STRING_LENGTH]; + + /* 1) Determine number of whitespace for output. */ + char whitespaces[MAX_STRING_LENGTH]; + int_t numberOfWhitespaces = (errorCount-1)*2; + + if ( numberOfWhitespaces < 0 ) + numberOfWhitespaces = 0; + + if ( numberOfWhitespaces > 40 ) + numberOfWhitespaces = 40; + + if ( numberOfWhitespaces >= (int_t)MAX_STRING_LENGTH ) + numberOfWhitespaces = (int_t)MAX_STRING_LENGTH-1; + + memset( whitespaces, ' ', (size_t) numberOfWhitespaces ); + whitespaces[numberOfWhitespaces] = '\0'; + + /* 2) Find error/warning/info in list. */ + while ( returnValueList[keypos].key != TERMINAL_LIST_ELEMENT ) + { + if ( returnValueList[keypos].key == RETnumber ) + break; + else + ++keypos; + } + + if ( returnValueList[keypos].key == TERMINAL_LIST_ELEMENT ) + { + throwError( RET_EWI_UNDEFINED,0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + return RETnumber; + } + + /* 3) Print error/warning/info. */ + if ( ( returnValueList[keypos].globalVisibilityStatus == VS_VISIBLE ) && ( localVisibilityStatus == VS_VISIBLE ) ) + { + if ( errorCount < 0 ) + { + myPrintf( "\n" ); + errorCount = 0; + } + + if ( errorCount > 0 ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH,"%s->", whitespaces ); + myPrintf( myPrintfString ); + } + + if ( additionaltext == 0 ) + { + #ifdef __DEBUG__ + snprintf( myPrintfString,MAX_STRING_LENGTH,"%s (%s, %s:%d): \t%s\n", + RETstring,functionname,filename,(int_t)linenumber,returnValueList[keypos].data + ); + #else + snprintf( myPrintfString,MAX_STRING_LENGTH,"%s: %s\n", + RETstring,returnValueList[keypos].data + ); + #endif + myPrintf( myPrintfString ); + } + else + { + #ifdef __DEBUG__ + snprintf( myPrintfString,MAX_STRING_LENGTH,"%s (%s, %s:%d): \t%s %s\n", + RETstring,functionname,filename,(int_t)linenumber,returnValueList[keypos].data,additionaltext + ); + #else + snprintf( myPrintfString,MAX_STRING_LENGTH,"%s: %s %s\n", + RETstring,returnValueList[keypos].data,additionaltext + ); + #endif + myPrintf( myPrintfString ); + } + + /* take care of proper indention for subsequent error messages */ + if ( RETstring[0] == 'E' ) + { + ++errorCount; + } + else + { + if ( errorCount > 0 ) + myPrintf( "\n" ); + errorCount = 0; + } + } + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return RETnumber; +} + +/****************************************************************************/ +/* S T A T I C P U B L I C */ +/****************************************************************************/ + +const char* MessageHandling::getErrorCodeMessage( const returnValue _returnValue + ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + int_t keypos = 0; + + /* 2) Find error/warning/info in list. */ + while ( returnValueList[keypos].key != TERMINAL_LIST_ELEMENT ) + { + if ( returnValueList[keypos].key == _returnValue ) + break; + else + ++keypos; + } + + if ( returnValueList[keypos].key == TERMINAL_LIST_ELEMENT ) + { + return "Unknown error code"; + } + + return (returnValueList[keypos].data != 0) ? returnValueList[keypos].data : "No message for this error code"; + + #else /* __SUPPRESSANYOUTPUT__ */ + + return "No message for this error code"; + + #endif /* __SUPPRESSANYOUTPUT__ */ +} + + +/***************************************************************************** + * G L O B A L M E S S A G E H A N D L E R * + *****************************************************************************/ + + +/** Global message handler for all qpOASES modules.*/ +#if defined(__DSPACE__) || defined(__XPCTARGET__) +static MessageHandling globalMessageHandler( stdFile,VS_VISIBLE,VS_HIDDEN,VS_HIDDEN ); +#endif + + +/* + * g e t G l o b a l M e s s a g e H a n d l e r + */ +MessageHandling* getGlobalMessageHandler( ) +{ + #ifndef __DSPACE__ + #ifndef __XPCTARGET__ + static MessageHandling globalMessageHandler( stdFile,VS_VISIBLE,VS_VISIBLE,VS_VISIBLE ); + #endif /* __DSPACE__ */ + #endif /* __XPCTARGET__ */ + + return &globalMessageHandler; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/OQPinterface.cpp b/locomotion/src/third_party/qpOASES/src/OQPinterface.cpp new file mode 100644 index 0000000..f63168a --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/OQPinterface.cpp @@ -0,0 +1,683 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/OQPinterface.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2008-2017 + * + * Implementation of an interface comprising several utility functions + * for solving test problems from the Online QP Benchmark Collection + * (This collection is no longer maintained, see + * http://www.qpOASES.org/onlineQP for a backup). + * + */ + + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + +/* + * r e a d O q p D i m e n s i o n s + */ +returnValue readOqpDimensions( const char* path, + int_t& nQP, int_t& nV, int_t& nC, int_t& nEC + ) +{ + /* 1) Setup file name where dimensions are stored. */ + char filename[MAX_STRING_LENGTH]; + snprintf( filename,MAX_STRING_LENGTH,"%sdims.oqp",path ); + + /* 2) Load dimensions from file. */ + int_t dims[4]; + if ( readFromFile( dims,4,filename ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + + nQP = dims[0]; + nV = dims[1]; + nC = dims[2]; + nEC = dims[3]; + + + /* consistency check */ + if ( ( nQP <= 0 ) || ( nV <= 0 ) || ( nC < 0 ) || ( nEC < 0 ) ) + return THROWERROR( RET_FILEDATA_INCONSISTENT ); + + return SUCCESSFUL_RETURN; +} + + +/* + * r e a d O q p D a t a + */ +returnValue readOqpData( const char* path, + int_t& nQP, int_t& nV, int_t& nC, int_t& nEC, + real_t** H, real_t** g, real_t** A, real_t** lb, real_t** ub, real_t** lbA, real_t** ubA, + real_t** xOpt, real_t** yOpt, real_t** objOpt + ) +{ + char filename[MAX_STRING_LENGTH]; + + /* consistency check */ + if ( ( H == 0 ) || ( g == 0 ) || ( lb == 0 ) || ( ub == 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + + /* 1) Obtain OQP dimensions. */ + if ( readOqpDimensions( path, nQP,nV,nC,nEC ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + + + /* another consistency check */ + if ( ( nC > 0 ) && ( ( A == 0 ) || ( lbA == 0 ) || ( ubA == 0 ) ) ) + return THROWERROR( RET_FILEDATA_INCONSISTENT ); + + + /* 2) Allocate memory and load OQP data: */ + /* Hessian matrix */ + *H = new real_t[nV*nV]; + snprintf( filename,MAX_STRING_LENGTH,"%sH.oqp",path ); + if ( readFromFile( *H,nV,nV,filename ) != SUCCESSFUL_RETURN ) + { + delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + /* gradient vector sequence */ + *g = new real_t[nQP*nV]; + snprintf( filename,MAX_STRING_LENGTH,"%sg.oqp",path ); + if ( readFromFile( *g,nQP,nV,filename ) != SUCCESSFUL_RETURN ) + { + delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + /* lower bound vector sequence */ + *lb = new real_t[nQP*nV]; + snprintf( filename,MAX_STRING_LENGTH,"%slb.oqp",path ); + if ( readFromFile( *lb,nQP,nV,filename ) != SUCCESSFUL_RETURN ) + { + delete[] *lb; delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + /* upper bound vector sequence */ + *ub = new real_t[nQP*nV]; + snprintf( filename,MAX_STRING_LENGTH,"%sub.oqp",path ); + if ( readFromFile( *ub,nQP,nV,filename ) != SUCCESSFUL_RETURN ) + { + delete[] *ub; delete[] *lb; delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + if ( nC > 0 ) + { + /* Constraint matrix */ + *A = new real_t[nC*nV]; + snprintf( filename,MAX_STRING_LENGTH,"%sA.oqp",path ); + if ( readFromFile( *A,nC,nV,filename ) != SUCCESSFUL_RETURN ) + { + delete[] *A; + delete[] *ub; delete[] *lb; delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + /* lower constraints' bound vector sequence */ + *lbA = new real_t[nQP*nC]; + snprintf( filename,MAX_STRING_LENGTH,"%slbA.oqp",path ); + if ( readFromFile( *lbA,nQP,nC,filename ) != SUCCESSFUL_RETURN ) + { + delete[] *lbA; delete[] *A; + delete[] *ub; delete[] *lb; delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + /* upper constraints' bound vector sequence */ + *ubA = new real_t[nQP*nC]; + snprintf( filename,MAX_STRING_LENGTH,"%subA.oqp",path ); + if ( readFromFile( *ubA,nQP,nC,filename ) != SUCCESSFUL_RETURN ) + { + delete[] *ubA; delete[] *lbA; delete[] *A; + delete[] *ub; delete[] *lb; delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + } + else + { + *A = 0; + *lbA = 0; + *ubA = 0; + } + + if ( xOpt != 0 ) + { + /* primal solution vector sequence */ + *xOpt = new real_t[nQP*nV]; + snprintf( filename,MAX_STRING_LENGTH,"%sx_opt.oqp",path ); + if ( readFromFile( *xOpt,nQP,nV,filename ) != SUCCESSFUL_RETURN ) + { + delete[] xOpt; + if ( nC > 0 ) { delete[] *ubA; delete[] *lbA; delete[] *A; }; + delete[] *ub; delete[] *lb; delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + } + + if ( yOpt != 0 ) + { + /* dual solution vector sequence */ + *yOpt = new real_t[nQP*(nV+nC)]; + snprintf( filename,MAX_STRING_LENGTH,"%sy_opt.oqp",path ); + if ( readFromFile( *yOpt,nQP,nV+nC,filename ) != SUCCESSFUL_RETURN ) + { + delete[] yOpt; + if ( xOpt != 0 ) { delete[] xOpt; }; + if ( nC > 0 ) { delete[] *ubA; delete[] *lbA; delete[] *A; }; + delete[] *ub; delete[] *lb; delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + } + + if ( objOpt != 0 ) + { + /* dual solution vector sequence */ + *objOpt = new real_t[nQP]; + snprintf( filename,MAX_STRING_LENGTH,"%sobj_opt.oqp",path ); + if ( readFromFile( *objOpt,nQP,1,filename ) != SUCCESSFUL_RETURN ) + { + delete[] objOpt; + if ( yOpt != 0 ) { delete[] yOpt; }; + if ( xOpt != 0 ) { delete[] xOpt; }; + if ( nC > 0 ) { delete[] *ubA; delete[] *lbA; delete[] *A; }; + delete[] *ub; delete[] *lb; delete[] *g; delete[] *H; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s o l v e O q p B e n c h m a r k + */ +returnValue solveOqpBenchmark( int_t nQP, int_t nV, int_t nC, int_t nEC, + const real_t* const _H, const real_t* const g, const real_t* const _A, + const real_t* const lb, const real_t* const ub, + const real_t* const lbA, const real_t* const ubA, + BooleanType isSparse, + const Options& options, int_t& nWSR, real_t& maxCPUtime, + real_t& maxStationarity, real_t& maxFeasibility, real_t& maxComplementarity + ) +{ + real_t maxNWSR = 0.0; + real_t avgNWSR = 0.0; + real_t avgCPUtime = 0.0; + + returnValue returnvalue = solveOqpBenchmark( nQP,nV,nC,nEC, + _H,g,_A,lb,ub,lbA,ubA, + isSparse,BT_TRUE, + options,nWSR, + maxNWSR,avgNWSR,maxCPUtime,avgCPUtime, + maxStationarity,maxFeasibility,maxComplementarity + ); + nWSR = (int_t)maxNWSR; + + return returnvalue; +} + + + +/* + * s o l v e O q p B e n c h m a r k + */ +returnValue solveOqpBenchmark( int_t nQP, int_t nV, int_t nC, int_t nEC, + const real_t* const _H, const real_t* const g, const real_t* const _A, + const real_t* const lb, const real_t* const ub, + const real_t* const lbA, const real_t* const ubA, + BooleanType isSparse, BooleanType useHotstarts, + const Options& options, int_t maxAllowedNWSR, + real_t& maxNWSR, real_t& avgNWSR, real_t& maxCPUtime, real_t& avgCPUtime, + real_t& maxStationarity, real_t& maxFeasibility, real_t& maxComplementarity + ) +{ + int_t k; + + /* I) SETUP AUXILIARY VARIABLES: */ + /* 1) Keep nWSR and store current and maximum number of + * working set recalculations in temporary variables */ + int_t nWSRcur; + + real_t CPUtimeLimit = maxCPUtime; + real_t CPUtimeCur = CPUtimeLimit; + maxNWSR = 0.0; + avgNWSR = 0.0; + maxCPUtime = 0.0; + avgCPUtime = 0.0; + maxStationarity = 0.0; + maxFeasibility = 0.0; + maxComplementarity = 0.0; + real_t stat, feas, cmpl; + + /* 2) Pointers to data of current QP ... */ + const real_t* gCur; + const real_t* lbCur; + const real_t* ubCur; + const real_t* lbACur; + const real_t* ubACur; + + /* 3) Vectors for solution obtained by qpOASES. */ + real_t* x = new real_t[nV]; + real_t* y = new real_t[nV+nC]; + //real_t obj; + + /* 4) Prepare matrix objects */ + SymmetricMatrix *H; + Matrix *A; + + real_t* H_cpy = new real_t[nV*nV]; + memcpy( H_cpy,_H, ((uint_t)(nV*nV))*sizeof(real_t) ); + real_t* A_cpy = new real_t[nC*nV]; + memcpy( A_cpy,_A, ((uint_t)(nC*nV))*sizeof(real_t) ); + + if ( isSparse == BT_TRUE ) + { + SymSparseMat *Hs; + H = Hs = new SymSparseMat(nV, nV, nV, H_cpy); + A = new SparseMatrixRow(nC, nV, nV, A_cpy); + Hs->createDiagInfo(); + delete[] A_cpy; delete[] H_cpy; + } + else + { + H = new SymDenseMat(nV, nV, nV, const_cast(H_cpy)); + A = new DenseMatrix(nC, nV, nV, const_cast(A_cpy)); + } + + H->doFreeMemory( ); + A->doFreeMemory( ); + + /* II) SETUP QPROBLEM OBJECT */ + QProblem qp( nV,nC ); + qp.setOptions( options ); + //qp.setPrintLevel( PL_LOW ); + + //qp.printOptions(); + + /* III) RUN BENCHMARK SEQUENCE: */ + returnValue returnvalue; + + for( k=0; k maxNWSR ) + maxNWSR = ((double)nWSRcur); + if (stat > maxStationarity) maxStationarity = stat; + if (feas > maxFeasibility) maxFeasibility = feas; + if (cmpl > maxComplementarity) maxComplementarity = cmpl; + + if ( CPUtimeCur > maxCPUtime ) + maxCPUtime = CPUtimeCur; + + avgNWSR += ((double)nWSRcur); + avgCPUtime += CPUtimeCur; + } + avgNWSR /= ((double)nQP); + avgCPUtime /= ((double)nQP); + + delete A; delete H; delete[] y; delete[] x; + + return SUCCESSFUL_RETURN; +} + + +/* + * s o l v e O q p B e n c h m a r k + */ +returnValue solveOqpBenchmark( int_t nQP, int_t nV, + const real_t* const _H, const real_t* const g, + const real_t* const lb, const real_t* const ub, + BooleanType isSparse, + const Options& options, int_t& nWSR, real_t& maxCPUtime, + real_t& maxStationarity, real_t& maxFeasibility, real_t& maxComplementarity + ) +{ + real_t maxNWSR = 0.0; + real_t avgNWSR = 0.0; + real_t avgCPUtime = 0.0; + + returnValue returnvalue = solveOqpBenchmark( nQP,nV, + _H,g,lb,ub, + isSparse,BT_TRUE, + options,nWSR, + maxNWSR,avgNWSR,maxCPUtime,avgCPUtime, + maxStationarity,maxFeasibility,maxComplementarity + ); + nWSR = (int_t)maxNWSR; + + return returnvalue; +} + + +/* + * s o l v e O q p B e n c h m a r k + */ +returnValue solveOqpBenchmark( int_t nQP, int_t nV, + const real_t* const _H, const real_t* const g, + const real_t* const lb, const real_t* const ub, + BooleanType isSparse, BooleanType useHotstarts, + const Options& options, int_t maxAllowedNWSR, + real_t& maxNWSR, real_t& avgNWSR, real_t& maxCPUtime, real_t& avgCPUtime, + real_t& maxStationarity, real_t& maxFeasibility, real_t& maxComplementarity + ) +{ + int_t k; + + /* I) SETUP AUXILIARY VARIABLES: */ + /* 1) Keep nWSR and store current and maximum number of + * working set recalculations in temporary variables */ + int_t nWSRcur; + + real_t CPUtimeLimit = maxCPUtime; + real_t CPUtimeCur = CPUtimeLimit; + real_t stat, feas, cmpl; + maxNWSR = 0; + avgNWSR = 0; + maxCPUtime = 0.0; + avgCPUtime = 0.0; + maxStationarity = 0.0; + maxFeasibility = 0.0; + maxComplementarity = 0.0; + + /* 2) Pointers to data of current QP ... */ + const real_t* gCur; + const real_t* lbCur; + const real_t* ubCur; + + /* 3) Vectors for solution obtained by qpOASES. */ + real_t* x = new real_t[nV]; + real_t* y = new real_t[nV]; + //real_t obj; + + /* 4) Prepare matrix objects */ + SymmetricMatrix *H; + real_t* H_cpy = new real_t[nV*nV]; + memcpy( H_cpy,_H, ((uint_t)(nV*nV))*sizeof(real_t) ); + + if ( isSparse == BT_TRUE ) + { + SymSparseMat *Hs; + H = Hs = new SymSparseMat(nV, nV, nV, H_cpy); + Hs->createDiagInfo(); + delete[] H_cpy; + } + else + { + H = new SymDenseMat(nV, nV, nV, const_cast(H_cpy)); + } + + H->doFreeMemory( ); + + /* II) SETUP QPROBLEM OBJECT */ + QProblemB qp( nV ); + qp.setOptions( options ); + //qp.setPrintLevel( PL_LOW ); + + + /* III) RUN BENCHMARK SEQUENCE: */ + returnValue returnvalue; + + for( k=0; k maxNWSR ) + maxNWSR = ((real_t)nWSRcur); + if (stat > maxStationarity) maxStationarity = stat; + if (feas > maxFeasibility) maxFeasibility = feas; + if (cmpl > maxComplementarity) maxComplementarity = cmpl; + + if ( CPUtimeCur > maxCPUtime ) + maxCPUtime = CPUtimeCur; + + avgNWSR += (real_t)nWSRcur; + avgCPUtime += CPUtimeCur; + } + avgNWSR /= ((real_t)nQP); + avgCPUtime /= ((real_t)nQP); + + delete H; delete[] y; delete[] x; + + return SUCCESSFUL_RETURN; +} + + +/* + * r u n O q p B e n c h m a r k + */ +returnValue runOqpBenchmark( const char* path, BooleanType isSparse, const Options& options, + int_t& nWSR, real_t& maxCPUtime, + real_t& maxStationarity, real_t& maxFeasibility, real_t& maxComplementarity + ) +{ + real_t maxNWSR = 0.0; + real_t avgNWSR = 0.0; + real_t avgCPUtime = 0.0; + + returnValue returnvalue = runOqpBenchmark( path,isSparse,BT_TRUE, + options,nWSR, + maxNWSR,avgNWSR,maxCPUtime,avgCPUtime, + maxStationarity,maxFeasibility,maxComplementarity + ); + nWSR = (int_t)maxNWSR; + + return returnvalue; +} + + +/* + * r u n O q p B e n c h m a r k + */ +returnValue runOqpBenchmark( const char* path, BooleanType isSparse, BooleanType useHotstarts, + const Options& options, int_t maxAllowedNWSR, + real_t& maxNWSR, real_t& avgNWSR, real_t& maxCPUtime, real_t& avgCPUtime, + real_t& maxStationarity, real_t& maxFeasibility, real_t& maxComplementarity + ) +{ + int_t nQP=0, nV=0, nC=0, nEC=0; + + real_t *H=0, *g=0, *A=0, *lb=0, *ub=0, *lbA=0, *ubA=0; + + + returnValue returnvalue; + + /* I) SETUP BENCHMARK: */ + /* 1) Obtain QP sequence dimensions. */ + if ( readOqpDimensions( path, nQP,nV,nC,nEC ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_UNABLE_TO_READ_BENCHMARK ); + + /* 2) Read OQP benchmark data. */ + if ( readOqpData( path, + nQP,nV,nC,nEC, + &H,&g,&A,&lb,&ub,&lbA,&ubA, + 0,0,0 + ) != SUCCESSFUL_RETURN ) + { + return THROWERROR( RET_UNABLE_TO_READ_BENCHMARK ); + } + + // normaliseConstraints( nV,nC,A,lbA,ubA ); //only works when nP==1 + + /* II) SOLVE BENCHMARK */ + if ( nC > 0 ) + { + returnvalue = solveOqpBenchmark( nQP,nV,nC,nEC, + H,g,A,lb,ub,lbA,ubA, + isSparse,useHotstarts, + options,maxAllowedNWSR, + maxNWSR,avgNWSR,maxCPUtime,avgCPUtime, + maxStationarity,maxFeasibility,maxComplementarity + ); + + if ( returnvalue != SUCCESSFUL_RETURN ) + { + if ( H != 0 ) delete[] H; + if ( g != 0 ) delete[] g; + if ( A != 0 ) delete[] A; + if ( lb != 0 ) delete[] lb; + if ( ub != 0 ) delete[] ub; + if ( lbA != 0 ) delete[] lbA; + if ( ubA != 0 ) delete[] ubA; + return THROWERROR( returnvalue ); + } + } + else + { + returnvalue = solveOqpBenchmark( nQP,nV, + H,g,lb,ub, + isSparse,useHotstarts, + options,maxAllowedNWSR, + maxNWSR,avgNWSR,maxCPUtime,avgCPUtime, + maxStationarity,maxFeasibility,maxComplementarity + ); + + if ( returnvalue != SUCCESSFUL_RETURN ) + { + if ( H != 0 ) delete[] H; + if ( g != 0 ) delete[] g; + if ( A != 0 ) delete[] A; + if ( lb != 0 ) delete[] lb; + if ( ub != 0 ) delete[] ub; + return THROWERROR( returnvalue ); + } + } + + if ( H != 0 ) delete[] H; + if ( g != 0 ) delete[] g; + if ( A != 0 ) delete[] A; + if ( lb != 0 ) delete[] lb; + if ( ub != 0 ) delete[] ub; + if ( lbA != 0 ) delete[] lbA; + if ( ubA != 0 ) delete[] ubA; + + return SUCCESSFUL_RETURN; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/Options.cpp b/locomotion/src/third_party/qpOASES/src/Options.cpp new file mode 100644 index 0000000..2b3a362 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/Options.cpp @@ -0,0 +1,563 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/Options.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the Options class designed to manage working sets of + * constraints and bounds within a QProblem. + */ + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * O p t i o n s + */ +Options::Options( ) +{ + setToDefault( ); +} + + +/* + * O p t i o n s + */ +Options::Options( const Options& rhs ) +{ + copy( rhs ); +} + + +/* + * ~ O p t i o n s + */ +Options::~Options( ) +{ +} + + +/* + * o p e r a t o r = + */ +Options& Options::operator=( const Options& rhs ) +{ + if ( this != &rhs ) + { + copy( rhs ); + } + + return *this; +} + + + +/* + * s e t T o D e f a u l t + */ +returnValue Options::setToDefault( ) +{ + printLevel = PL_MEDIUM; + #ifdef __DEBUG__ + printLevel = PL_HIGH; + #endif + #ifdef __SUPPRESSANYOUTPUT__ + printLevel = PL_NONE; + #endif + + enableRamping = BT_TRUE; + enableFarBounds = BT_TRUE; + enableFlippingBounds = BT_TRUE; + enableRegularisation = BT_FALSE; + enableFullLITests = BT_FALSE; + enableNZCTests = BT_TRUE; + enableDriftCorrection = 1; + enableCholeskyRefactorisation = 0; + enableEqualities = BT_FALSE; + + #ifdef __USE_SINGLE_PRECISION__ + terminationTolerance = 1.0e2 * EPS; + boundTolerance = 1.0e2 * EPS; + #else + terminationTolerance = 5.0e6 * EPS; + boundTolerance = 1.0e6 * EPS; + #endif + boundRelaxation = 1.0e4; + #ifdef __USE_SINGLE_PRECISION__ + epsNum = -1.0e2 * EPS; + epsDen = 1.0e2 * EPS; + #else + epsNum = -1.0e3 * EPS; + epsDen = 1.0e3 * EPS; + #endif + maxPrimalJump = 1.0e8; + maxDualJump = 1.0e8; + + initialRamping = 0.5; + finalRamping = 1.0; + initialFarBounds = 1.0e6; + growFarBounds = 1.0e3; + initialStatusBounds = ST_LOWER; + #ifdef __USE_SINGLE_PRECISION__ + epsFlipping = 5.0e1 * EPS; + #else + epsFlipping = 1.0e3 * EPS; + #endif + numRegularisationSteps = 0; + #ifdef __USE_SINGLE_PRECISION__ + epsRegularisation = 2.0e1 * EPS; + numRefinementSteps = 2; + #else + epsRegularisation = 1.0e3 * EPS; + numRefinementSteps = 1; + #endif + epsIterRef = 1.0e2 * EPS; + #ifdef __USE_SINGLE_PRECISION__ + epsLITests = 5.0e1 * EPS; + epsNZCTests = 1.0e2 * EPS; + #else + epsLITests = 1.0e5 * EPS; + epsNZCTests = 3.0e3 * EPS; + #endif + + enableDropInfeasibles = BT_FALSE; + dropBoundPriority = 1; + dropEqConPriority = 1; + dropIneqConPriority = 1; + + enableInertiaCorrection = BT_TRUE; + rcondSMin = 1.0e-14; + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t T o R e l i a b l e + */ +returnValue Options::setToReliable( ) +{ + setToDefault( ); + + enableFullLITests = BT_TRUE; + enableCholeskyRefactorisation = 1; + + #ifdef __USE_SINGLE_PRECISION__ + numRefinementSteps = 3; + #else + numRefinementSteps = 2; + #endif + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t T o M P C + */ +returnValue Options::setToMPC( ) +{ + setToDefault( ); + + enableRamping = BT_FALSE; + enableFarBounds = BT_TRUE; + enableFlippingBounds = BT_FALSE; + enableRegularisation = BT_TRUE; + enableNZCTests = BT_FALSE; + enableDriftCorrection = 0; + enableEqualities = BT_TRUE; + + #ifdef __USE_SINGLE_PRECISION__ + terminationTolerance = 1.0e3 * EPS; + #else + terminationTolerance = 1.0e9 * EPS; + #endif + + initialStatusBounds = ST_INACTIVE; + numRegularisationSteps = 1; + #ifdef __USE_SINGLE_PRECISION__ + numRefinementSteps = 2; + #else + numRefinementSteps = 0; + #endif + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t T o F a s t + */ +returnValue Options::setToFast( ) +{ + return setToMPC( ); +} + + + +/* + * e n s u r e C o n s i s t e n c y + */ +returnValue Options::ensureConsistency( ) +{ + BooleanType needToAdjust = BT_FALSE; + + /* flipping bounds require far bounds */ + /* (ckirches) Removed this as per filter's trust region + if( enableFlippingBounds == BT_TRUE ) + enableFarBounds = BT_TRUE; + */ + + if( enableDriftCorrection < 0 ) + { + enableDriftCorrection = 0; + needToAdjust = BT_TRUE; + } + + if( enableCholeskyRefactorisation < 0 ) + { + enableCholeskyRefactorisation = 0; + needToAdjust = BT_TRUE; + } + + if ( terminationTolerance <= 0.0 ) + { + terminationTolerance = EPS; + needToAdjust = BT_TRUE; + } + + if ( epsIterRef <= 0.0 ) + { + epsIterRef = EPS; + needToAdjust = BT_TRUE; + } + + if ( epsRegularisation <= 0.0 ) + { + epsRegularisation = EPS; + needToAdjust = BT_TRUE; + } + + if ( boundTolerance <= 0.0 ) + { + boundTolerance = EPS; + needToAdjust = BT_TRUE; + } + + if ( boundRelaxation <= 0.0 ) + { + boundRelaxation = EPS; + needToAdjust = BT_TRUE; + } + + if ( maxPrimalJump <= 0.0 ) + { + maxPrimalJump = EPS; + needToAdjust = BT_TRUE; + } + + if ( maxDualJump <= 0.0 ) + { + maxDualJump = EPS; + needToAdjust = BT_TRUE; + } + + + if ( initialRamping < 0.0 ) + { + initialRamping = 0.0; + needToAdjust = BT_TRUE; + } + + if ( finalRamping < 0.0 ) + { + finalRamping = 0.0; + needToAdjust = BT_TRUE; + } + + if ( initialFarBounds <= boundRelaxation ) + { + initialFarBounds = boundRelaxation+EPS; + needToAdjust = BT_TRUE; + } + + if ( growFarBounds < 1.1 ) + { + growFarBounds = 1.1; + needToAdjust = BT_TRUE; + } + + if ( epsFlipping <= 0.0 ) + { + epsFlipping = EPS; + needToAdjust = BT_TRUE; + } + + if ( numRegularisationSteps < 0 ) + { + numRegularisationSteps = 0; + needToAdjust = BT_TRUE; + } + + if ( epsRegularisation < 0.0 ) + { + epsRegularisation = EPS; + needToAdjust = BT_TRUE; + } + + if ( numRefinementSteps < 0 ) + { + numRefinementSteps = 0; + needToAdjust = BT_TRUE; + } + + if ( epsIterRef < 0.0 ) + { + epsIterRef = EPS; + needToAdjust = BT_TRUE; + } + + if ( epsLITests < 0.0 ) + { + epsLITests = EPS; + needToAdjust = BT_TRUE; + } + + if ( epsNZCTests < 0.0 ) + { + epsNZCTests = EPS; + needToAdjust = BT_TRUE; + } + + if ( needToAdjust == BT_TRUE) + return THROWWARNING( RET_OPTIONS_ADJUSTED ); + + return SUCCESSFUL_RETURN; +} + + +/* + * p r i n t + */ +returnValue Options::print( ) const +{ + #ifndef __SUPPRESSANYOUTPUT__ + + char myPrintfString[MAX_STRING_LENGTH]; + char info[MAX_STRING_LENGTH]; + + myPrintf( "\n################### qpOASES -- QP OPTIONS ##################\n" ); + myPrintf( "\n" ); + + convertPrintLevelToString( printLevel,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"printLevel = %s\n",info ); + myPrintf( myPrintfString ); + + myPrintf( "\n" ); + + convertBooleanTypeToString( enableRamping,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableRamping = %s\n",info ); + myPrintf( myPrintfString ); + + convertBooleanTypeToString( enableFarBounds,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableFarBounds = %s\n",info ); + myPrintf( myPrintfString ); + + convertBooleanTypeToString( enableFlippingBounds,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableFlippingBounds = %s\n",info ); + myPrintf( myPrintfString ); + + convertBooleanTypeToString( enableRegularisation,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableRegularisation = %s\n",info ); + myPrintf( myPrintfString ); + + convertBooleanTypeToString( enableFullLITests,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableFullLITests = %s\n",info ); + myPrintf( myPrintfString ); + + convertBooleanTypeToString( enableNZCTests,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableNZCTests = %s\n",info ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableDriftCorrection = %d\n",(int)enableDriftCorrection ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableCholeskyRefactorisation = %d\n",(int)enableCholeskyRefactorisation ); + myPrintf( myPrintfString ); + + convertBooleanTypeToString( enableEqualities,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableEqualities = %s\n",info ); + myPrintf( myPrintfString ); + + convertBooleanTypeToString( enableInertiaCorrection,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"enableInertiaCorrection = %s\n",info ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"rcondSMin = %e\n",rcondSMin ); + myPrintf( myPrintfString ); + + myPrintf( "\n" ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"terminationTolerance = %e\n",terminationTolerance ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"boundTolerance = %e\n",boundTolerance ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"boundRelaxation = %e\n",boundRelaxation ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"epsNum = %e\n",epsNum ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"epsDen = %e\n",epsDen ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"maxPrimalJump = %e\n",maxPrimalJump ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"maxDualJump = %e\n",maxDualJump ); + myPrintf( myPrintfString ); + + myPrintf( "\n" ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"initialRamping = %e\n",initialRamping ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"finalRamping = %e\n",finalRamping ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"initialFarBounds = %e\n",initialFarBounds ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"growFarBounds = %e\n",growFarBounds ); + myPrintf( myPrintfString ); + + convertSubjectToStatusToString( initialStatusBounds,info ); + snprintf( myPrintfString,MAX_STRING_LENGTH,"initialStatusBounds = %s\n",info ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"epsFlipping = %e\n",epsFlipping ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"numRegularisationSteps = %d\n",(int)numRegularisationSteps ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"epsRegularisation = %e\n",epsRegularisation ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"numRefinementSteps = %d\n",(int)numRefinementSteps ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"epsIterRef = %e\n",epsIterRef ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"epsLITests = %e\n",epsLITests ); + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH,"epsNZCTests = %e\n",epsNZCTests ); + myPrintf( myPrintfString ); + + myPrintf( "\n\n" ); + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * c o p y + */ +returnValue Options::copy( const Options& rhs + ) +{ + printLevel = rhs.printLevel; + + enableRamping = rhs.enableRamping; + enableFarBounds = rhs.enableFarBounds; + enableFlippingBounds = rhs.enableFlippingBounds; + enableRegularisation = rhs.enableRegularisation; + enableFullLITests = rhs.enableFullLITests; + enableNZCTests = rhs.enableNZCTests; + enableDriftCorrection = rhs.enableDriftCorrection; + enableCholeskyRefactorisation = rhs.enableCholeskyRefactorisation; + enableEqualities = rhs.enableEqualities; + + terminationTolerance = rhs.terminationTolerance; + boundTolerance = rhs.boundTolerance; + boundRelaxation = rhs.boundRelaxation; + epsNum = rhs.epsNum; + epsDen = rhs.epsDen; + maxPrimalJump = rhs.maxPrimalJump; + maxDualJump = rhs.maxDualJump; + + initialRamping = rhs.initialRamping; + finalRamping = rhs.finalRamping; + initialFarBounds = rhs.initialFarBounds; + growFarBounds = rhs.growFarBounds; + initialStatusBounds = rhs.initialStatusBounds; + epsFlipping = rhs.epsFlipping; + numRegularisationSteps = rhs.numRegularisationSteps; + epsRegularisation = rhs.epsRegularisation; + numRefinementSteps = rhs.numRefinementSteps; + epsIterRef = rhs.epsIterRef; + epsLITests = rhs.epsLITests; + epsNZCTests = rhs.epsNZCTests; + + enableInertiaCorrection = rhs.enableInertiaCorrection; + rcondSMin = rhs.rcondSMin; + + enableDropInfeasibles = rhs.enableDropInfeasibles; + dropBoundPriority = rhs.dropBoundPriority; + dropEqConPriority = rhs.dropEqConPriority; + dropIneqConPriority = rhs.dropIneqConPriority; + + return SUCCESSFUL_RETURN; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/QProblem.cpp b/locomotion/src/third_party/qpOASES/src/QProblem.cpp new file mode 100644 index 0000000..8ea39e1 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/QProblem.cpp @@ -0,0 +1,6461 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/QProblem.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the QProblem class which is able to use the newly + * developed online active set strategy for parametric quadratic programming. + */ + + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * Q P r o b l e m + */ +QProblem::QProblem( ) : QProblemB( ) +{ + freeConstraintMatrix = BT_FALSE; + A = 0; + + lbA = 0; + ubA = 0; + + sizeT = 0; + T = 0; + Q = 0; + + Ax = 0; + Ax_l = 0; + Ax_u = 0; + + constraintProduct = 0; + + tempA = 0; + ZFR_delta_xFRz = 0; + delta_xFRy = 0; + delta_xFRz = 0; + tempB = 0; + delta_yAC_TMP = 0; + tempC = 0; +} + + +/* + * Q P r o b l e m + */ +QProblem::QProblem( int_t _nV, int_t _nC, HessianType _hessianType, BooleanType allocDenseMats ) + : QProblemB( _nV,_hessianType,allocDenseMats ) +{ + int_t i; + + /* consistency checks */ + if ( _nV <= 0 ) + { + _nV = 1; + THROWERROR( RET_INVALID_ARGUMENTS ); + } + + if ( _nC < 0 ) + { + _nC = 0; + THROWERROR( RET_INVALID_ARGUMENTS ); + } + + if ( _nC > 0 ) + { + freeConstraintMatrix = BT_FALSE; + A = 0; + + lbA = new real_t[_nC]; + for( i=0; i<_nC; ++i ) lbA[i] = 0.0; + + ubA = new real_t[_nC]; + for( i=0; i<_nC; ++i ) ubA[i] = 0.0; + } + else + { + /* prevent segmentation faults in case nC == 0 + * (avoiding checks for A!=0 around all calls to A->... */ + freeConstraintMatrix = BT_TRUE; + A = new DenseMatrix( ); + + lbA = 0; + ubA = 0; + } + + constraints.init( _nC ); + + delete[] y; /* y of no constraints version too short! */ + y = new real_t[_nV+_nC]; + for( i=0; i<_nV+_nC; ++i ) y[i] = 0.0; + + if (allocDenseMats == BT_TRUE) + { + sizeT = getMin( _nV,_nC ); + T = new real_t[sizeT*sizeT]; + Q = new real_t[_nV*_nV]; + } + else + { + sizeT = 0; + T = 0; + Q = 0; + } + + if ( _nC > 0 ) + { + Ax = new real_t[_nC]; + Ax_l = new real_t[_nC]; + Ax_u = new real_t[_nC]; + } + else + { + Ax = 0; + Ax_l = 0; + Ax_u = 0; + } + + constraintProduct = 0; + + tempA = new real_t[_nV]; /* nFR */ + ZFR_delta_xFRz = new real_t[_nV]; /* nFR */ + delta_xFRz = new real_t[_nV]; /* nZ */ + + if ( _nC > 0 ) + { + tempB = new real_t[_nC]; /* nAC */ + delta_xFRy = new real_t[_nC]; /* nAC */ + delta_yAC_TMP = new real_t[_nC]; /* nAC */ + tempC = new real_t[_nC]; /* nAC */ + } + else + { + tempB = 0; + delta_xFRy = 0; + delta_yAC_TMP = 0; + tempC = 0; + } + + flipper.init( (uint_t)_nV,(uint_t)_nC ); +} + + +/* + * Q P r o b l e m + */ +QProblem::QProblem( const QProblem& rhs ) : QProblemB( rhs ) +{ + freeConstraintMatrix = BT_FALSE; + A = 0; + + copy( rhs ); +} + + +/* + * ~ Q P r o b l e m + */ +QProblem::~QProblem( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +QProblem& QProblem::operator=( const QProblem& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + QProblemB::operator=( rhs ); + copy( rhs ); + } + + return *this; +} + + +/* + * r e s e t + */ +returnValue QProblem::reset( ) +{ + int_t i; + int_t nV = getNV( ); + int_t nC = getNC( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + + /* 1) Reset bounds, Cholesky decomposition and status flags. */ + if ( QProblemB::reset( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_RESET_FAILED ); + + /* 2) Reset constraints. */ + constraints.init( nC ); + + /* 3) Reset TQ factorisation. */ + if ( T!=0 ) + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + } + + if ( guessedConstraints != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + /* exclude these possibilities in order to avoid inconsistencies */ + if ( ( xOpt == 0 ) && ( yOpt != 0 ) && ( ( guessedBounds != 0 ) || ( guessedConstraints != 0 ) ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( ( _R != 0 ) && ( ( xOpt != 0 ) || ( yOpt != 0 ) || ( guessedBounds != 0 ) || ( guessedConstraints != 0 ) ) ) + return THROWERROR( RET_NO_CHOLESKY_WITH_INITIAL_GUESS ); + + /* 2) Setup QP data. */ + if ( setupQPdata( _H,_g,_A,_lb,_ub,_lbA,_ubA ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + /* 3) Call to main initialisation routine. */ + return solveInitialQP( xOpt,yOpt,guessedBounds,guessedConstraints,_R, nWSR,cputime ); +} + + +/* + * i n i t + */ +returnValue QProblem::init( const real_t* const _H, const real_t* const _g, const real_t* const _A, + const real_t* const _lb, const real_t* const _ub, + const real_t* const _lbA, const real_t* const _ubA, + int_t& nWSR, real_t* const cputime, + const real_t* const xOpt, const real_t* const yOpt, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints, + const real_t* const _R + ) +{ + int_t i; + int_t nV = getNV( ); + int_t nC = getNC( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + /* 1) Consistency checks. */ + if ( isInitialised( ) == BT_TRUE ) + { + THROWWARNING( RET_QP_ALREADY_INITIALISED ); + reset( ); + } + + if ( guessedBounds != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + } + + if ( guessedConstraints != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + /* exclude these possibilities in order to avoid inconsistencies */ + if ( ( xOpt == 0 ) && ( yOpt != 0 ) && ( ( guessedBounds != 0 ) || ( guessedConstraints != 0 ) ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( ( _R != 0 ) && ( ( xOpt != 0 ) || ( yOpt != 0 ) || ( guessedBounds != 0 ) || ( guessedConstraints != 0 ) ) ) + return THROWERROR( RET_NO_CHOLESKY_WITH_INITIAL_GUESS ); + + /* 2) Setup QP data. */ + if ( setupQPdata( _H,_g,_A,_lb,_ub,_lbA,_ubA ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + /* 3) Call to main initialisation routine. */ + return solveInitialQP( xOpt,yOpt,guessedBounds,guessedConstraints,_R, nWSR,cputime ); +} + + +/* + * i n i t + */ +returnValue QProblem::init( const char* const H_file, const char* const g_file, const char* const A_file, + const char* const lb_file, const char* const ub_file, + const char* const lbA_file, const char* const ubA_file, + int_t& nWSR, real_t* const cputime, + const real_t* const xOpt, const real_t* const yOpt, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints, + const char* const R_file + ) +{ + int_t i; + int_t nV = getNV( ); + int_t nC = getNC( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + /* 1) Consistency checks. */ + if ( isInitialised( ) == BT_TRUE ) + { + THROWWARNING( RET_QP_ALREADY_INITIALISED ); + reset( ); + } + + if ( guessedBounds != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + } + + if ( guessedConstraints != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + /* exclude these possibilities in order to avoid inconsistencies */ + if ( ( xOpt == 0 ) && ( yOpt != 0 ) && ( ( guessedBounds != 0 ) || ( guessedConstraints != 0 ) ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( ( R_file != 0 ) && ( ( xOpt != 0 ) || ( yOpt != 0 ) || ( guessedBounds != 0 ) || ( guessedConstraints != 0 ) ) ) + return THROWERROR( RET_NO_CHOLESKY_WITH_INITIAL_GUESS ); + + /* 2) Setup QP data from files. */ + if ( setupQPdataFromFile( H_file,g_file,A_file,lb_file,ub_file,lbA_file,ubA_file ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + + if ( R_file == 0 ) + { + /* 3) Call to main initialisation routine. */ + return solveInitialQP( xOpt,yOpt,guessedBounds,guessedConstraints,0, nWSR,cputime ); + } + else + { + /* Also read Cholesky factor from file and store it directly into R [thus... */ + returnValue returnvalue = readFromFile( R, nV,nV, R_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWWARNING( returnvalue ); + + /* 3) Call to main initialisation routine. ...passing R here!] */ + return solveInitialQP( xOpt,yOpt,guessedBounds,guessedConstraints,R, nWSR,cputime ); + } +} + + + +/* + * h o t s t a r t + */ +returnValue QProblem::hotstart( const real_t* const g_new, + const real_t* const lb_new, const real_t* const ub_new, + const real_t* const lbA_new, const real_t* const ubA_new, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints + ) +{ + int_t i, nActiveFar; + int_t nV = getNV (); + int_t nC = getNC (); + real_t starttime = 0.0; + real_t auxTime = 0.0; + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + + /* Possibly update working sets according to guesses for working sets of bounds and constraints. */ + if ( ( guessedBounds != 0 ) || ( guessedConstraints != 0 ) ) + { + if ( cputime != 0 ) + starttime = getCPUtime( ); + + const Bounds* actualGuessedBounds = ( guessedBounds != 0 ) ? guessedBounds : &bounds; + const Constraints* actualGuessedConstraints = ( guessedConstraints != 0 ) ? guessedConstraints : &constraints; + + if ( setupAuxiliaryQP( actualGuessedBounds,actualGuessedConstraints ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + + status = QPS_AUXILIARYQPSOLVED; + + /* Allow only remaining CPU time for usual hotstart. */ + if ( cputime != 0 ) + { + auxTime = getCPUtime( ) - starttime; + *cputime -= auxTime; + } + } + + returnValue returnvalue = SUCCESSFUL_RETURN; + + /* Simple check for consistency of bounds and constraints. */ + if ( areBoundsConsistent(lb_new, ub_new, lbA_new, ubA_new) != SUCCESSFUL_RETURN ) + return setInfeasibilityFlag(returnvalue,BT_TRUE); + + ++count; + + int_t nWSR_max = nWSR; + int_t nWSR_performed = 0; + + real_t cputime_remaining = INFTY, *pcputime_rem; + real_t cputime_needed = 0.0; + + real_t farbound = options.initialFarBounds; + + /* writeQpDataIntoMatFile( "qpData.mat" ); */ + /* writeQpWorkspaceIntoMatFile( "qpWorkspace.mat" ); */ + + if ( haveCholesky == BT_FALSE ) + { + returnvalue = setupInitialCholesky( ); + if (returnvalue != SUCCESSFUL_RETURN) + return THROWERROR(returnvalue); + } + + BooleanType isFirstCall = BT_TRUE; + + if ( options.enableFarBounds == BT_FALSE ) + { + /* Automatically call standard solveQP if regularisation is not active. */ + returnvalue = solveRegularisedQP( g_new,lb_new,ub_new,lbA_new,ubA_new, + nWSR,cputime,0, + isFirstCall + ); + } + else + { + real_t *ub_new_far = new real_t[nV]; + real_t *lb_new_far = new real_t[nV]; + real_t *ubA_new_far = new real_t[nC]; + real_t *lbA_new_far = new real_t[nC]; + + /* possibly extend initial far bounds to largest bound/constraint data */ + if (ub_new) + for (i = 0; i < nV; i++) + if ((ub_new[i] < INFTY) && (ub_new[i] > farbound)) farbound = ub_new[i]; + if (lb_new) + for (i = 0; i < nV; i++) + if ((lb_new[i] > -INFTY) && (lb_new[i] < -farbound)) farbound = -lb_new[i]; + if (ubA_new) + for (i = 0; i < nC; i++) + if ((ubA_new[i] < INFTY) && (ubA_new[i] > farbound)) farbound = ubA_new[i]; + if (lbA_new) + for (i = 0; i < nC; i++) + if ((lbA_new[i] > -INFTY) && (lbA_new[i] < -farbound)) farbound = -lbA_new[i]; + + updateFarBounds( farbound,nV+nC, + lb_new,lb_new_far, ub_new,ub_new_far, + lbA_new,lbA_new_far, ubA_new,ubA_new_far + ); + + for ( ;; ) + { + nWSR = nWSR_max; + if ( cputime != 0 ) + { + cputime_remaining = *cputime - cputime_needed; + pcputime_rem = &cputime_remaining; + } + else + pcputime_rem = 0; + + /* Automatically call standard solveQP if regularisation is not active. */ + returnvalue = solveRegularisedQP( g_new,lb_new_far,ub_new_far,lbA_new_far,ubA_new_far, + nWSR,pcputime_rem,nWSR_performed, + isFirstCall + ); + + nWSR_performed = nWSR; + cputime_needed += cputime_remaining; + isFirstCall = BT_FALSE; + + /* Check for active far-bounds and move them away */ + nActiveFar = 0; + farbound *= options.growFarBounds; + + if ( infeasible == BT_TRUE ) + { + if ( farbound >= INFTY ) + { + returnvalue = RET_HOTSTART_STOPPED_INFEASIBILITY; + break; // goto farewell; + } + + updateFarBounds( farbound,nV+nC, + lb_new,lb_new_far, ub_new,ub_new_far, + lbA_new,lbA_new_far, ubA_new,ubA_new_far + ); + } + else if ( status == QPS_SOLVED ) + { + real_t tol = farbound/options.growFarBounds * options.boundTolerance; + + for ( i=0; i lb_new[i] ) ) && ( getAbs ( lb_new_far[i] - x[i] ) < tol ) ) + ++nActiveFar; + if ( ( ( ub_new == 0 ) || ( ub_new_far[i] < ub_new[i] ) ) && ( getAbs ( ub_new_far[i] - x[i] ) < tol ) ) + ++nActiveFar; + } + for ( i=0; i lbA_new[i] ) ) && ( getAbs ( lbA_new_far[i] - Ax[i] ) < tol ) ) + ++nActiveFar; + if ( ( ( ubA_new == 0 ) || ( ubA_new_far[i] < ubA_new[i] ) ) && ( getAbs ( ubA_new_far[i] - Ax[i] ) < tol ) ) + ++nActiveFar; + } + + if ( nActiveFar == 0 ) + break; + + status = QPS_HOMOTOPYQPSOLVED; + + if ( farbound >= INFTY ) + { + unbounded = BT_TRUE; + returnvalue = RET_HOTSTART_STOPPED_UNBOUNDEDNESS; + goto farewell; + } + + updateFarBounds( farbound,nV+nC, + lb_new,lb_new_far, ub_new,ub_new_far, + lbA_new,lbA_new_far, ubA_new,ubA_new_far + ); + } + else + { + /* some other error when solving QP */ + break; + } + + /* advance ramp offset to avoid Ramping cycles */ + rampOffset++; + } + + farewell: + /* add time to setup auxiliary QP */ + if ( cputime != 0 ) + *cputime = cputime_needed + auxTime; + delete[] lbA_new_far; delete[] ubA_new_far; + delete[] lb_new_far; delete[] ub_new_far; + } + + return ( returnvalue != SUCCESSFUL_RETURN ) ? THROWERROR( returnvalue ) : returnvalue; +} + + +/* + * h o t s t a r t + */ +returnValue QProblem::hotstart( const char* const g_file, + const char* const lb_file, const char* const ub_file, + const char* const lbA_file, const char* const ubA_file, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints + ) +{ + int_t nV = getNV( ); + int_t nC = getNC( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + /* consistency check */ + if ( g_file == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + + /* 1) Allocate memory (if bounds exist). */ + real_t* g_new = new real_t[nV]; + real_t* lb_new = ( lb_file != 0 ) ? new real_t[nV] : 0; + real_t* ub_new = ( ub_file != 0 ) ? new real_t[nV] : 0; + real_t* lbA_new = ( lbA_file != 0 ) ? new real_t[nC] : 0; + real_t* ubA_new = ( ubA_file != 0 ) ? new real_t[nC] : 0; + + + /* 2) Load new QP vectors from file. */ + returnValue returnvalue; + returnvalue = loadQPvectorsFromFile( g_file,lb_file,ub_file,lbA_file,ubA_file, + g_new,lb_new,ub_new,lbA_new,ubA_new + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + if ( ubA_file != 0 ) + delete[] ubA_new; + if ( lbA_file != 0 ) + delete[] lbA_new; + if ( ub_file != 0 ) + delete[] ub_new; + if ( lb_file != 0 ) + delete[] lb_new; + delete[] g_new; + + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + + /* 3) Actually perform hotstart. */ + returnvalue = hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, + nWSR,cputime, + guessedBounds,guessedConstraints + ); + + + /* 4) Free memory. */ + if ( ubA_file != 0 ) + delete[] ubA_new; + if ( lbA_file != 0 ) + delete[] lbA_new; + if ( ub_file != 0 ) + delete[] ub_new; + if ( lb_file != 0 ) + delete[] lb_new; + delete[] g_new; + + return returnvalue; +} + + +/* + * s o l v e C u r r e n t E Q P + */ +returnValue QProblem::solveCurrentEQP( const int_t n_rhs, + const real_t* g_in, + const real_t* lb_in, + const real_t* ub_in, + const real_t* lbA_in, + const real_t* ubA_in, + real_t* x_out, + real_t* y_out + ) +{ + if ( ( x_out == 0 ) || ( y_out == 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + returnValue returnvalue = SUCCESSFUL_RETURN; + int_t ii, jj; + int_t nV = getNV( ); + int_t nC = getNC( ); + int_t nFR = getNFR( ); + int_t nFX = getNFX( ); + int_t nAC = getNAC( ); + + real_t *delta_xFX = new real_t[nFX]; + real_t *delta_xFR = new real_t[nFR]; + real_t *delta_yAC = new real_t[nAC]; + real_t *delta_yFX = new real_t[nFX]; + + /* 1) Determine index arrays. */ + int_t* FR_idx; + int_t* FX_idx; + int_t* AC_idx; + + bounds.getFree( )->getNumberArray( &FR_idx ); + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + + for ( ii = 0 ; ii < (nV+nC)*n_rhs; ++ii ) + y_out[ii] = 0.0; + + for ( ii = 0 ; ii < n_rhs; ++ii ) + { + returnvalue = determineStepDirection( + g_in, lbA_in, ubA_in, lb_in, ub_in, BT_FALSE, BT_FALSE, + delta_xFX, delta_xFR, delta_yAC, delta_yFX ); + + for ( jj = 0; jj < nFX; ++jj ) + x_out[FX_idx[jj]] = delta_xFX[jj]; + for ( jj = 0; jj < nFR; ++jj ) + x_out[FR_idx[jj]] = delta_xFR[jj]; + for ( jj = 0; jj < nFX; ++jj ) + y_out[FX_idx[jj]] = delta_yFX[jj]; + for ( jj = 0; jj < nAC; ++jj ) + y_out[nV+AC_idx[jj]] = delta_yAC[jj]; + + g_in += nV; + lb_in += nV; + ub_in += nV; + lbA_in += nC; + ubA_in += nC; + x_out += nV; + y_out += nV+nC; + } + + + delete[] delta_yFX; + delete[] delta_yAC; + delete[] delta_xFR; + delete[] delta_xFX; + + return returnvalue; +} + + + +/* + * g e t W o r k i n g S e t + */ +returnValue QProblem::getWorkingSet( real_t* workingSet ) +{ + int_t nV = this->getNV(); + + if ( workingSet == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + /* At which limit are the bounds active? */ + getWorkingSetBounds( workingSet ); + + /* At which limit are the contraints active? */ + getWorkingSetConstraints( &(workingSet[nV]) ); + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t W o r k i n g S e t B o u n d s + */ +returnValue QProblem::getWorkingSetBounds( real_t* workingSetB ) +{ + return QProblemB::getWorkingSetBounds( workingSetB ); +} + + +/* + * g e t W o r k i n g S e t C o n s t r a i n t s + */ +returnValue QProblem::getWorkingSetConstraints( real_t* workingSetC ) +{ + int_t i; + int_t nC = this->getNC(); + + if ( workingSetC == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + for ( i=0; i 0 ) + { + if ( constraints.hasNoLower( ) == BT_TRUE ) + myPrintf( "Constraints are not bounded from below.\n" ); + else + myPrintf( "Constraints are bounded from below.\n" ); + + if ( constraints.hasNoUpper( ) == BT_TRUE ) + myPrintf( "Constraints are not bounded from above.\n" ); + else + myPrintf( "Constraints are bounded from above.\n" ); + } + + myPrintf( "\n" ); + + + /* 3) Further properties. */ + switch ( hessianType ) + { + case HST_ZERO: + myPrintf( "Hessian is zero matrix (i.e. actually an LP is solved).\n" ); + break; + + case HST_IDENTITY: + myPrintf( "Hessian is identity matrix.\n" ); + break; + + case HST_POSDEF: + myPrintf( "Hessian matrix is (strictly) positive definite.\n" ); + break; + + case HST_POSDEF_NULLSPACE: + myPrintf( "Hessian matrix is positive definite on null space of active constraints.\n" ); + break; + + case HST_SEMIDEF: + myPrintf( "Hessian matrix is positive semi-definite.\n" ); + break; + + case HST_INDEF: + myPrintf( "Hessian matrix is indefinite.\n" ); + break; + + default: + myPrintf( "Hessian matrix has unknown type.\n" ); + break; + } + + if ( infeasible == BT_TRUE ) + myPrintf( "QP was found to be infeasible.\n" ); + else + myPrintf( "QP seems to be feasible.\n" ); + + if ( unbounded == BT_TRUE ) + myPrintf( "QP was found to be unbounded from below.\n" ); + else + myPrintf( "QP seems to be bounded from below.\n" ); + + myPrintf( "\n" ); + + + /* 4) QP object properties. */ + switch ( status ) + { + case QPS_NOTINITIALISED: + myPrintf( "Status of QP object: freshly instantiated or reset.\n" ); + break; + + case QPS_PREPARINGAUXILIARYQP: + myPrintf( "Status of QP object: an auxiliary QP is currently setup.\n" ); + break; + + case QPS_AUXILIARYQPSOLVED: + myPrintf( "Status of QP object: an auxilary QP was solved.\n" ); + break; + + case QPS_PERFORMINGHOMOTOPY: + myPrintf( "Status of QP object: a homotopy step is performed.\n" ); + break; + + case QPS_HOMOTOPYQPSOLVED: + myPrintf( "Status of QP object: an intermediate QP along the homotopy path was solved.\n" ); + break; + + case QPS_SOLVED: + myPrintf( "Status of QP object: solution of the actual QP was found.\n" ); + break; + } + + switch ( options.printLevel ) + { + case PL_DEBUG_ITER: + myPrintf( "Print level of QP object is set to display a tabular output for debugging.\n" ); + break; + + case PL_TABULAR: + myPrintf( "Print level of QP object is set to display a tabular output.\n" ); + break; + + case PL_LOW: + myPrintf( "Print level of QP object is low, i.e. only error are printed.\n" ); + break; + + case PL_MEDIUM: + myPrintf( "Print level of QP object is medium, i.e. error and warnings are printed.\n" ); + break; + + case PL_HIGH: + myPrintf( "Print level of QP object is high, i.e. all available output is printed.\n" ); + break; + + default: + break; + } + + myPrintf( "\n" ); + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + +returnValue QProblem::getFreeVariablesFlags( BooleanType* varIsFree ) +{ + int_t nV = getNV( ); + for ( int_t i=0; igetNumberArray( &FR_idx ); + + for ( int_t i=0; iduplicate(); + else + A = rhs.A; + + if ( rhs.lbA != 0 ) + { + lbA = new real_t[_nC]; + setLBA( rhs.lbA ); + } + else + lbA = 0; + + if ( rhs.ubA != 0 ) + { + ubA = new real_t[_nC]; + setUBA( rhs.ubA ); + } + else + ubA = 0; + + if ( rhs.y != 0 ) + { + delete[] y; /* y of no constraints version too short! */ + y = new real_t[_nV+_nC]; + memcpy( y,rhs.y,(_nV+_nC)*sizeof(real_t) ); + } + else + y = 0; + + sizeT = rhs.sizeT; + + if ( rhs.T != 0 ) + { + T = new real_t[sizeT*sizeT]; + memcpy( T,rhs.T,((uint_t)(sizeT*sizeT))*sizeof(real_t) ); + } + else + T = 0; + + if ( rhs.Q != 0 ) + { + Q = new real_t[_nV*_nV]; + memcpy( Q,rhs.Q,_nV*_nV*sizeof(real_t) ); + } + else + Q = 0; + + if ( rhs.Ax != 0 ) + { + Ax = new real_t[_nC]; + memcpy( Ax,rhs.Ax,_nC*sizeof(real_t) ); + } + else + Ax = 0; + + if ( rhs.Ax_l != 0 ) + { + Ax_l = new real_t[_nC]; + memcpy( Ax_l,rhs.Ax_l,_nC*sizeof(real_t) ); + } + else + Ax_l = 0; + + if ( rhs.Ax_u != 0 ) + { + Ax_u = new real_t[_nC]; + memcpy( Ax_u,rhs.Ax_u,_nC*sizeof(real_t) ); + } + else + Ax_u = 0; + + if ( rhs.constraintProduct != 0 ) + constraintProduct = rhs.constraintProduct; + else + constraintProduct = 0; + + tempA = new real_t[_nV]; /* nFR */ + ZFR_delta_xFRz = new real_t[_nV]; /* nFR */ + delta_xFRz = new real_t[_nV]; /* nZ */ + + if ( _nC > 0 ) + { + delta_xFRy = new real_t[_nC]; /* nAC */ + tempB = new real_t[_nC]; /* nAC */ + delta_yAC_TMP = new real_t[_nC]; /* nAC */ + tempC = new real_t[_nC]; /* nAC */ + } + else + { + delta_xFRy = 0; + tempB = 0; + delta_yAC_TMP = 0; + tempC = 0; + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * s o l v e I n i t i a l Q P + */ +returnValue QProblem::solveInitialQP( const real_t* const xOpt, const real_t* const yOpt, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints, + const real_t* const _R, + int_t& nWSR, real_t* const cputime + ) +{ + int_t i,j; + + /* some definitions */ + int_t nV = getNV( ); + int_t nC = getNC( ); + + //writeQpDataIntoMatFile( "qpData.mat" ); + + /* start runtime measurement */ + real_t starttime = 0.0; + if ( cputime != 0 ) + starttime = getCPUtime( ); + + status = QPS_NOTINITIALISED; + + /* I) ANALYSE QP DATA: */ + /* 1) Check if Hessian happens to be the identity matrix. */ + if ( determineHessianType( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED ); + + /* 2) Setup type of bounds and constraints (i.e. unbounded, implicitly fixed etc.). */ + if ( setupSubjectToType( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED ); + + status = QPS_PREPARINGAUXILIARYQP; + + + /* II) SETUP AUXILIARY QP WITH GIVEN OPTIMAL SOLUTION: */ + /* 1) Setup bounds and constraints data structure. */ + if ( bounds.setupAllFree( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED ); + + if ( constraints.setupAllInactive( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED ); + + /* 2) Setup optimal primal/dual solution for auxiliary QP. */ + if ( setupAuxiliaryQPsolution( xOpt,yOpt ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED ); + + /* 3) Obtain linear independent working set for auxiliary QP. */ + Bounds auxiliaryBounds( nV ); + Constraints auxiliaryConstraints( nC ); + + if ( obtainAuxiliaryWorkingSet( xOpt,yOpt,guessedBounds,guessedConstraints, + &auxiliaryBounds,&auxiliaryConstraints ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED ); + + /* 4) Setup working set of auxiliary QP and setup matrix factorisations. */ + /* a) Regularise Hessian if necessary. */ + if ( ( hessianType == HST_ZERO ) || ( hessianType == HST_SEMIDEF ) ) + { + if ( regulariseHessian( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED_REGULARISATION ); + } + + /* b) TQ factorisation. */ + if ( setupTQfactorisation( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED_TQ ); + + /* c) Working set of auxiliary QP. */ + if ( setupAuxiliaryWorkingSet( &auxiliaryBounds,&auxiliaryConstraints,BT_TRUE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INIT_FAILED ); + + /* d) Copy external Cholesky factor if provided */ + haveCholesky = BT_FALSE; + + if ( _R != 0 ) + { + if ( options.initialStatusBounds != ST_INACTIVE ) + { + THROWWARNING( RET_NO_CHOLESKY_WITH_INITIAL_GUESS ); + } + else + { + if ( _R == R ) + { + /* Cholesky factor read from file and already loaded into R. */ + haveCholesky = BT_TRUE; + } + else if ( ( xOpt == 0 ) && ( yOpt == 0 ) && ( guessedBounds == 0 ) && ( guessedConstraints == 0 ) ) + { + for( i=0; ithrowInfo( RET_ITERATION_STARTED,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + /* 2) Determination of shift direction of the gradient and the (constraints') bounds. */ + returnvalue = determineDataShift( g_new,lbA_new,ubA_new,lb_new,ub_new, + delta_g,delta_lbA,delta_ubA,delta_lb,delta_ub, + Delta_bC_isZero, Delta_bB_isZero + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] delta_yAC; delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_ubA; delete[] delta_lbA; delete[] delta_g; + + /* Assign number of working set recalculations and stop runtime measurement. */ + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + THROWERROR( RET_SHIFT_DETERMINATION_FAILED ); + return returnvalue; + } + + /* 3) Determination of step direction of X and Y. */ + returnvalue = determineStepDirection( delta_g,delta_lbA,delta_ubA,delta_lb,delta_ub, + Delta_bC_isZero, Delta_bB_isZero, + delta_xFX,delta_xFR,delta_yAC,delta_yFX + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] delta_yAC; delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_ubA; delete[] delta_lbA; delete[] delta_g; + + /* Assign number of working set recalculations and stop runtime measurement. */ + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + THROWERROR( RET_STEPDIRECTION_DETERMINATION_FAILED ); + return returnvalue; + } + + /* 4) Determination of step length TAU. + * This step along the homotopy path is also taken (without changing working set). */ + returnvalue = performStep( delta_g, delta_lbA,delta_ubA,delta_lb,delta_ub, + delta_xFX,delta_xFR,delta_yAC,delta_yFX, + BC_idx,BC_status,BC_isBound + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] delta_yAC; delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_ubA; delete[] delta_lbA; delete[] delta_g; + + /* Assign number of working set recalculations and stop runtime measurement. */ + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + THROWERROR( RET_STEPLENGTH_DETERMINATION_FAILED ); + return returnvalue; + } + + /* 5) Termination criterion. */ + nV = getNV( ); + nC = getNC( ); + + homotopyLength = getRelativeHomotopyLength( g_new,lb_new,ub_new,lbA_new,ubA_new ); + if ( homotopyLength <= options.terminationTolerance ) + { + status = QPS_SOLVED; + + THROWINFO( RET_OPTIMAL_SOLUTION_FOUND ); + + if ( printIteration( iter,BC_idx,BC_status,BC_isBound,homotopyLength,isFirstCall ) != SUCCESSFUL_RETURN ) + THROWERROR( RET_PRINT_ITERATION_FAILED ); /* do not pass this as return value! */ + + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + delete[] delta_yAC; delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_ubA; delete[] delta_lbA; delete[] delta_g; + + return SUCCESSFUL_RETURN; + } + + /* 6) Change active set. */ + returnvalue = changeActiveSet( BC_idx,BC_status,BC_isBound ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] delta_yAC; delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_ubA; delete[] delta_lbA; delete[] delta_g; + + /* Assign number of working set recalculations and stop runtime measurement. */ + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + /* Checks for infeasibility... */ + if ( isInfeasible( ) == BT_TRUE ) + { + status = QPS_HOMOTOPYQPSOLVED; + return setInfeasibilityFlag( RET_HOTSTART_STOPPED_INFEASIBILITY ); + } + + /* ...unboundedness... */ + if ( unbounded == BT_TRUE ) /* not necessary since objective function convex! */ + return THROWERROR( RET_HOTSTART_STOPPED_UNBOUNDEDNESS ); + + /* ... and throw unspecific error otherwise */ + THROWERROR( RET_HOMOTOPY_STEP_FAILED ); + return returnvalue; + } + + /* 6a) Possibly refactorise projected Hessian from scratch. */ + if ( ( options.enableCholeskyRefactorisation > 0 ) && ( (iter % options.enableCholeskyRefactorisation) == 0 ) ) + { + returnvalue = computeProjectedCholesky( ); + if (returnvalue != SUCCESSFUL_RETURN) + { + delete[] delta_yAC; delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_ubA; delete[] delta_lbA; delete[] delta_g; + return returnvalue; + } + } + + /* 7) Output information of successful QP iteration. */ + status = QPS_HOMOTOPYQPSOLVED; + + if ( printIteration( iter,BC_idx,BC_status,BC_isBound,homotopyLength,isFirstCall ) != SUCCESSFUL_RETURN ) + THROWERROR( RET_PRINT_ITERATION_FAILED ); /* do not pass this as return value! */ + + /* 8) Perform Ramping Strategy on zero homotopy step or drift correction (if desired). */ + if (BC_status != ST_UNDEFINED) + { + if ( ( tau <= EPS ) && ( options.enableRamping == BT_TRUE ) ) + performRamping( ); + else + if ( (options.enableDriftCorrection > 0) + && ((iter+1) % options.enableDriftCorrection == 0) ) + performDriftCorrection( ); /* always returns SUCCESSFUL_RETURN */ + } + else // AW: Added this. Otherwise, I observed that the gradient might become incorrect + { + if ( (options.enableDriftCorrection > 0) + && ((iter+1) % options.enableDriftCorrection == 0) ) + performDriftCorrection( ); /* always returns SUCCESSFUL_RETURN */ + } + } + + delete[] delta_yAC; delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_ubA; delete[] delta_lbA; delete[] delta_g; + + /* stop runtime measurement */ + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + + /* if program gets to here, output information that QP could not be solved + * within the given maximum numbers of working set changes */ + if ( options.printLevel == PL_HIGH ) + { + #ifndef __SUPPRESSANYOUTPUT__ + snprintf( messageString,MAX_STRING_LENGTH,"(nWSR = %d)",(int)iter ); + return getGlobalMessageHandler( )->throwWarning( RET_MAX_NWSR_REACHED,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #else + return RET_MAX_NWSR_REACHED; + #endif + } + else + { + return RET_MAX_NWSR_REACHED; + } +} + + +/* + * s o l v e R e g u l a r i s e d Q P + */ +returnValue QProblem::solveRegularisedQP( const real_t* const g_new, + const real_t* const lb_new, const real_t* const ub_new, + const real_t* const lbA_new, const real_t* const ubA_new, + int_t& nWSR, real_t* const cputime, int_t nWSRperformed, + BooleanType isFirstCall + ) +{ + int_t i, step; + int_t nV = getNV( ); + + + /* Perform normal QP solution if QP has not been regularised. */ + if ( usingRegularisation( ) == BT_FALSE ) + return solveQP( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,cputime,nWSRperformed,isFirstCall ); + + + /* I) SOLVE USUAL REGULARISED QP */ + returnValue returnvalue; + + int_t nWSR_max = nWSR; + int_t nWSR_total = nWSRperformed; + + real_t cputime_total = 0.0; + real_t cputime_cur = 0.0; + + if ( cputime == 0 ) + { + returnvalue = solveQP( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,0,nWSRperformed,isFirstCall ); + } + else + { + cputime_cur = *cputime; + returnvalue = solveQP( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,&cputime_cur,nWSRperformed,isFirstCall ); + } + nWSR_total = nWSR; + cputime_total += cputime_cur; + isFirstCall = BT_FALSE; + + /* Only continue if QP solution has been successful. */ + if ( returnvalue != SUCCESSFUL_RETURN ) + { + if ( cputime != 0 ) + *cputime = cputime_total; + + if ( returnvalue == RET_MAX_NWSR_REACHED ) + THROWWARNING( RET_NO_REGSTEP_NWSR ); + + return returnvalue; + } + + + /* II) PERFORM SUCCESSIVE REGULARISATION STEPS */ + real_t* gMod = new real_t[nV]; + + for( step=0; step= INFTY && bounds.getStatus(i) == ST_UPPER ) + { + returnvalue = removeBound( i, BT_TRUE, BT_FALSE, options.enableNZCTests ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return returnvalue; + g[i] -= y[i]; + y[i] = 0.0; + } + if ( lb_new[i] > -INFTY && lb[i] <= -INFTY ) + { + /* Now a lower bound has become finite. To avoid numerical issues, adjust lb */ + lb[i] = x[i] - options.boundRelaxation; + } + if ( ub_new[i] < INFTY && ub[i] >= INFTY ) + { + /* Now a lower bound has become finite. To avoid numerical issues, adjust lb */ + ub[i] = x[i] + options.boundRelaxation; + } + } + + for ( i=0; i -INFTY ) + { + constraints.setNoLower( BT_FALSE ); + break; + } + } + } + + /* 2) Check if upper constraints' bounds are present. */ + constraints.setNoUpper( BT_TRUE ); + if ( ubA_new != 0 ) + { + for( i=0; i INFTY-options.boundTolerance ) + && (options.enableFarBounds == BT_FALSE)) + { + constraints.setType( i,ST_UNBOUNDED ); + } + else + { + if ( options.enableEqualities && lbA[i] > ubA[i] - options.boundTolerance + && lbA_new[i] > ubA_new[i] - options.boundTolerance) + constraints.setType( i,ST_EQUALITY ); + else + constraints.setType( i,ST_BOUNDED ); + } + } + } + else + { + if ( ( lbA_new == 0 ) && ( ubA_new == 0 ) ) + { + for( i=0; igetNumberArray( &FR_idx ); + + int_t* AC_idx; + constraints.getActive( )->getNumberArray( &AC_idx ); + + /* calculate Z'*H*Z */ + switch ( hessianType ) + { + case HST_ZERO: + if ( usingRegularisation() == BT_TRUE ) + { + Id = createDiagSparseMat( nV, regVal ); + Id->bilinear(bounds.getFree(), nZ, Q, nV, R, nV); + delete Id; + } + else + { + /* Code should not get here, as nZ == 0 always holds for an LP (without regularisation)! */ + if ( nZ > 0 ) + return THROWERROR( RET_UNKNOWN_BUG ); + } + break; + + case HST_IDENTITY: + Id = createDiagSparseMat( nV, 1.0 ); + Id->bilinear(bounds.getFree(), nZ, Q, nV, R, nV); + delete Id; + break; + + default: + if ( getNAC() == 0 ) { + /* make Z trivial */ + for ( j=0; j < nZ; ++j ) { + for ( i=0; i < nV; ++i ) + QQ(i,j) = 0.0; + QQ(FR_idx[j],j) = 1.0; + } + /* now Z is trivial, and so is Z'HZ */ + int_t nFR = getNFR (); + for ( j=0; j < nFR; ++j ) + H->getCol (FR_idx[j], bounds.getFree (), 1.0, &R[j*nV]); + } else { + /* this is expensive if Z is large! */ + H->bilinear(bounds.getFree(), nZ, Q, nV, R, nV); + } + } + + /* R'*R = Z'*H*Z */ + la_int_t info = 0; + la_uint_t _nZ = (la_uint_t)nZ, _nV = (la_uint_t)nV; + + POTRF( "U", &_nZ, R, &_nV, &info ); + + /* <0 = invalid call, =0 ok, >0 not spd */ + if (info > 0) { + if ( R[0] < 0.0 ) + { + /* Cholesky decomposition has tunneled a negative + * diagonal element. */ + options.epsRegularisation = getMin( -R[0]+options.epsRegularisation,getSqrt(getAbs(options.epsRegularisation)) ); + } + + hessianType = HST_SEMIDEF; + return RET_HESSIAN_NOT_SPD; + } + + /* zero first subdiagonal to make givens updates work */ + for (i=0;igetNumberArray( &FR_idx ); + + /* 1) Set Q to unity matrix. */ + for( i=0; igetStatus( i ); + + #ifdef __ALWAYS_INITIALISE_WITH_ALL_EQUALITIES__ + if ( constraints.getType( i ) == ST_EQUALITY ) + { + if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + else + #endif + { + if ( auxiliaryConstraints->setupConstraint( i,guessedStatus ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + } + } + else /* No initial working set specified. */ + { + /* Obtain initial working set by "clipping". */ + if ( ( xOpt != 0 ) && ( yOpt == 0 ) ) + { + for( i=0; isetupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + continue; + } + + if ( ubA[i] - Ax_u[i] <= options.boundTolerance ) + { + if ( auxiliaryConstraints->setupConstraint( i,ST_UPPER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + continue; + } + + /* Moreover, add all equality constraints if specified. */ + #ifdef __ALWAYS_INITIALISE_WITH_ALL_EQUALITIES__ + if ( constraints.getType( i ) == ST_EQUALITY ) + { + if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + else + #endif + { + if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + } + } + + /* Obtain initial working set in accordance to sign of dual solution vector. */ + if ( yOpt != 0 ) + { + for( i=0; i EPS ) + { + if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + continue; + } + + if ( yOpt[nV+i] < -EPS ) + { + if ( auxiliaryConstraints->setupConstraint( i,ST_UPPER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + continue; + } + + /* Moreover, add all equality constraints if specified. */ + #ifdef __ALWAYS_INITIALISE_WITH_ALL_EQUALITIES__ + if ( constraints.getType( i ) == ST_EQUALITY ) + { + if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + else + #endif + { + if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + } + } + + /* If xOpt and yOpt are null pointer and no initial working is specified, + * start with empty working set (or implicitly fixed bounds and equality constraints only) + * for auxiliary QP. */ + if ( ( xOpt == 0 ) && ( yOpt == 0 ) ) + { + for( i=0; isetupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + else + #endif + { + if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + } + } + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * s e t u p A u x i l i a r y W o r k i n g S e t + */ +returnValue QProblem::setupAuxiliaryWorkingSet( const Bounds* const auxiliaryBounds, + const Constraints* const auxiliaryConstraints, + BooleanType setupAfresh + ) +{ + int_t i; + int_t nV = getNV( ); + int_t nC = getNC( ); + BooleanType WSisTrivial = BT_TRUE; + + /* consistency checks */ + if ( auxiliaryBounds != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) ) + return THROWERROR( RET_UNKNOWN_BUG ); + } + else + { + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + if ( auxiliaryConstraints != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) ) + return THROWERROR( RET_UNKNOWN_BUG ); + } + else + { + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + /* Check for trivial working set (all and only bounds active) */ + for (i = 0; i < nV; i++) + if (auxiliaryBounds->getStatus(i) == ST_INACTIVE) + { + WSisTrivial = BT_FALSE; + break; + } + for (i = 0; i < nC; i++) + // (ckirches) here we chose to ignore an invalid ST_INACTIVE on + // constraints that are ST_EQUALITies or may just have become equalities + if ( (constraints.getType(i) == ST_EQUALITY) // NOT auxiliaryConstraints here + || (auxiliaryConstraints->getStatus(i) != ST_INACTIVE) ) + { + WSisTrivial = BT_FALSE; + break; + } + + if (WSisTrivial == BT_TRUE) + { + for (i = 0; i < nV; i++) + if (bounds.getStatus(i) == ST_INACTIVE) + bounds.moveFreeToFixed(i, auxiliaryBounds->getStatus(i)); + + return SUCCESSFUL_RETURN; + } + + + /* I) SETUP CHOLESKY FLAG: + * Cholesky decomposition shall only be updated if working set + * shall be updated (i.e. NOT setup afresh!) */ + BooleanType updateCholesky; + if ( setupAfresh == BT_TRUE ) + updateCholesky = BT_FALSE; + else + updateCholesky = BT_TRUE; + + + BooleanType was_fulli = options.enableFullLITests; + real_t backupEpsLITests = options.epsLITests; + + options.enableFullLITests = BT_FALSE; + /* options.epsLITests = 1e-1; */ + + /* II) REMOVE FORMERLY ACTIVE (CONSTRAINTS') BOUNDS (IF NECESSARY): */ + if ( setupAfresh == BT_FALSE ) + { + /* 1) Remove all active constraints that shall be inactive or disabled AND + * all active constraints that are active at the wrong bound. */ + for( i=0; igetStatus( i ) != ST_LOWER ) ) + if ( removeConstraint( i,updateCholesky,BT_FALSE,options.enableNZCTests ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + + if ( ( constraints.getStatus( i ) == ST_UPPER ) && ( auxiliaryConstraints->getStatus( i ) != ST_UPPER ) ) + if ( removeConstraint( i,updateCholesky,BT_FALSE,options.enableNZCTests ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + + /* 2) Remove all active bounds that shall be inactive AND + * all active bounds that are active at the wrong bound. */ + for( i=0; igetStatus( i ) != ST_LOWER ) ) + if ( removeBound( i,updateCholesky,BT_FALSE,options.enableNZCTests ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + + if ( ( bounds.getStatus( i ) == ST_UPPER ) && ( auxiliaryBounds->getStatus( i ) != ST_UPPER ) ) + if ( removeBound( i,updateCholesky,BT_FALSE,options.enableNZCTests ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + } + + + /* III) ADD NEWLY ACTIVE (CONSTRAINTS') BOUNDS: */ + + /* 1) Add all equality bounds. */ + for( i=0; igetStatus( i ) != ST_INACTIVE ) ) ) + + // (ckirches) force equalities active + + if ( ( bounds.getType( i ) == ST_EQUALITY ) && ( bounds.getStatus( i ) == ST_INACTIVE ) ) + { + // assert ( auxiliaryBounds->getStatus( i ) != ST_INACTIVE ); + /* No check for linear independence necessary. */ + if ( addBound( i,ST_LOWER,updateCholesky ) != SUCCESSFUL_RETURN ) // was auxiliaryBounds->getStatus( i ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + } + + /* 2) Add all equality constraints. */ + for( i=0; igetStatus( i ) != ST_INACTIVE ) ) ) + + // (ckirches) force equalities active + + if ( ( constraints.getType( i ) == ST_EQUALITY ) && ( constraints.getStatus( i ) == ST_INACTIVE ) ) + { + // assert ( auxiliaryConstraints->getStatus( i ) != ST_INACTIVE ); + /* Add constraint only if it is linearly independent from the current working set. */ + if ( addConstraint_checkLI( i ) == RET_LINEARLY_INDEPENDENT ) + { + if ( addConstraint( i,ST_LOWER,updateCholesky ) != SUCCESSFUL_RETURN ) // was auxiliaryConstraints->getStatus( i ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + else + { + /* Equalities are not linearly independent! */ + constraints.setType(i, ST_BOUNDED); + } + } + } + + + /* 3) Add all inactive bounds that shall be active AND + * all formerly active bounds that have been active at the wrong bound. */ + for( i=0; igetStatus( i ) != ST_INACTIVE ) ) ) + { + /* Add bound only if it is linearly independent from the current working set. */ + if ( addBound_checkLI( i ) == RET_LINEARLY_INDEPENDENT ) + { + if ( addBound( i,auxiliaryBounds->getStatus( i ),updateCholesky ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + } + } + + /* 4) Add all inactive constraints that shall be active AND + * all formerly active constraints that have been active at the wrong bound. */ + for( i=0; igetStatus( i ) != ST_INACTIVE ) ) + { + /* formerly inactive */ + if ( constraints.getStatus( i ) == ST_INACTIVE ) + { + /* Add constraint only if it is linearly independent from the current working set. */ + if ( addConstraint_checkLI( i ) == RET_LINEARLY_INDEPENDENT ) + { + if ( addConstraint( i,auxiliaryConstraints->getStatus( i ),updateCholesky ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + } + } + } + + options.enableFullLITests = was_fulli; + options.epsLITests = backupEpsLITests; + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p A u x i l i a r y Q P s o l u t i o n + */ +returnValue QProblem::setupAuxiliaryQPsolution( const real_t* const xOpt, const real_t* const yOpt + ) +{ + int_t i, j; + int_t nV = getNV( ); + int_t nC = getNC( ); + + + /* Setup primal/dual solution vector for auxiliary initial QP: + * if a null pointer is passed, a zero vector is assigned; + * old solution vector is kept if pointer to internal solution vector is passed. */ + if ( xOpt != 0 ) + { + if ( xOpt != x ) + for( i=0; itimes(1, 1.0, x, nV, 0.0, Ax, nC); + + for ( j=0; jtimes(1, -1.0, x, nV, 1.0, g, nV); + break; + } + + /* + A'*yC */ + A->transTimes(1, 1.0, y + nV, nC, 1.0, g, nV); + + return SUCCESSFUL_RETURN; +} + + +/* + * a r e B o u n d s C o n s i s t e n t + */ +returnValue QProblem::areBoundsConsistent( const real_t* const lb_new, const real_t* const ub_new, + const real_t* const lbA_new, const real_t* const ubA_new) const +{ + if (QProblemB::areBoundsConsistent(lb_new, ub_new) == RET_QP_INFEASIBLE) + return RET_QP_INFEASIBLE; + + if (lbA_new && ubA_new) { + for (int_t i = 0; i < getNC(); ++i) { + if (lbA_new[i] > ubA_new[i]+EPS) { + return RET_QP_INFEASIBLE; + } + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p A u x i l i a r y Q P b o u n d s + */ +returnValue QProblem::setupAuxiliaryQPbounds( const Bounds* const auxiliaryBounds, + const Constraints* const auxiliaryConstraints, + BooleanType useRelaxation + ) +{ + int_t i; + int_t nV = getNV( ); + int_t nC = getNC( ); + + + /* 1) Setup bound vectors. */ + for ( i=0; igetStatus( i ) == ST_LOWER ) + lb[i] = x[i]; + else + lb[i] = x[i] - options.boundRelaxation; + + if ( auxiliaryBounds->getStatus( i ) == ST_UPPER ) + ub[i] = x[i]; + else + ub[i] = x[i] + options.boundRelaxation; + } + } + break; + + case ST_LOWER: + lb[i] = x[i]; + if ( bounds.getType( i ) == ST_EQUALITY ) + { + ub[i] = x[i]; + } + else + { + if ( useRelaxation == BT_TRUE ) + ub[i] = x[i] + options.boundRelaxation; + } + break; + + case ST_UPPER: + ub[i] = x[i]; + if ( bounds.getType( i ) == ST_EQUALITY ) + { + lb[i] = x[i]; + } + else + { + if ( useRelaxation == BT_TRUE ) + lb[i] = x[i] - options.boundRelaxation; + } + break; + + case ST_INFEASIBLE_LOWER: + case ST_INFEASIBLE_UPPER: + break; + + default: + return THROWERROR( RET_UNKNOWN_BUG ); + } + } + + /* 2) Setup constraints vectors. */ + for ( i=0; igetStatus( i ) == ST_LOWER ) + lbA[i] = Ax_l[i]; + else + lbA[i] = Ax_l[i] - options.boundRelaxation; + + if ( auxiliaryConstraints->getStatus( i ) == ST_UPPER ) + ubA[i] = Ax_u[i]; + else + ubA[i] = Ax_u[i] + options.boundRelaxation; + } + } + break; + + case ST_LOWER: + lbA[i] = Ax_l[i]; + if ( constraints.getType( i ) == ST_EQUALITY ) + { + ubA[i] = Ax_l[i]; + } + else + { + if ( useRelaxation == BT_TRUE ) + ubA[i] = Ax_l[i] + options.boundRelaxation; + } + break; + + case ST_UPPER: + ubA[i] = Ax_u[i]; + if ( constraints.getType( i ) == ST_EQUALITY ) + { + lbA[i] = Ax_u[i]; + } + else + { + if ( useRelaxation == BT_TRUE ) + lbA[i] = Ax_u[i] - options.boundRelaxation; + } + break; + + case ST_INFEASIBLE_LOWER: + case ST_INFEASIBLE_UPPER: + break; + + default: + return THROWERROR( RET_UNKNOWN_BUG ); + } + Ax_l[i] = Ax_l[i] - lbA[i]; + Ax_u[i] = ubA[i] - Ax_u[i]; + } + + return SUCCESSFUL_RETURN; +} + + +/* + * a d d C o n s t r a i n t + */ +returnValue QProblem::addConstraint( int_t number, SubjectToStatus C_status, + BooleanType updateCholesky, + BooleanType ensureLI + ) +{ + int_t i, j, ii; + + /* consistency checks */ + if ( constraints.getStatus( number ) != ST_INACTIVE ) + return THROWERROR( RET_CONSTRAINT_ALREADY_ACTIVE ); + + if ( ( constraints.getNC( ) - getNAC( ) ) == constraints.getNUC( ) ) + return THROWERROR( RET_ALL_CONSTRAINTS_ACTIVE ); + + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + + /* I) ENSURE LINEAR INDEPENDENCE OF THE WORKING SET, + * i.e. remove a constraint or bound if linear dependence occurs. */ + /* check for LI only if Cholesky decomposition shall be updated! */ + if ( updateCholesky == BT_TRUE && ensureLI == BT_TRUE ) + { + returnValue ensureLIreturnvalue = addConstraint_ensureLI( number,C_status ); + + switch ( ensureLIreturnvalue ) + { + case SUCCESSFUL_RETURN: + break; + + case RET_LI_RESOLVED: + break; + + case RET_ENSURELI_FAILED_NOINDEX: + return RET_ADDCONSTRAINT_FAILED_INFEASIBILITY; + + case RET_ENSURELI_FAILED_CYCLING: + return RET_ADDCONSTRAINT_FAILED_INFEASIBILITY; + + case RET_ENSURELI_DROPPED: + return SUCCESSFUL_RETURN; + + default: + return THROWERROR( RET_ENSURELI_FAILED ); + } + } + + /* some definitions */ + int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nAC = getNAC( ); + int_t nZ = getNZ( ); + + int_t tcol = sizeT - nAC; + + + int_t* FR_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + + real_t* aFR = new real_t[nFR]; + real_t* wZ = new real_t[nZ]; + for( i=0; igetRow(number, bounds.getFree(), 1.0, aFR); + + /* calculate wZ */ + for( i=0; i 0 ) + { + for( j=0; j 0 ) + { + /* II) RESTORE TRIANGULAR FORM OF T: */ + /* Use column-wise Givens rotations to restore reverse triangular form + * of T, simultanenous change of Q (i.e. Z) and R. */ + for( j=0; jgetNumberArray( &FR_idx ); + + + if (options.enableFullLITests) + { + /* + * expensive LI test. Backsolve with refinement using special right + * hand side. This gives an estimate for what should be considered + * "zero". We then check linear independence relative to this estimate. + */ + + int_t *FX_idx, *AC_idx, *IAC_idx; + + real_t *delta_g = new real_t[nV]; + real_t *delta_xFX = new real_t[nFX]; + real_t *delta_xFR = new real_t[nFR]; + real_t *delta_yAC = new real_t[nAC]; + real_t *delta_yFX = new real_t[nFX]; + + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + constraints.getInactive( )->getNumberArray( &IAC_idx ); + + int_t dim = (nC>nV)?nC:nV; + real_t *nul = new real_t[dim]; + for (ii = 0; ii < dim; ++ii) + nul[ii]=0.0; + + A->getRow (number, 0, 1.0, delta_g); + + // AW: I think original line overwrote correct return value + // original: returnvalue = determineStepDirection ( delta_g, + returnValue dsdreturnvalue = determineStepDirection ( delta_g, + nul, nul, nul, nul, + BT_FALSE, BT_FALSE, + delta_xFX, delta_xFR, delta_yAC, delta_yFX); + if (dsdreturnvalue!=SUCCESSFUL_RETURN) + returnvalue = dsdreturnvalue; + + delete[] nul; + + /* compute the weight in inf-norm */ + real_t weight = 0.0; + for (ii = 0; ii < nAC; ++ii) + { + real_t a = getAbs (delta_yAC[ii]); + if (weight < a) weight = a; + } + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_yFX[ii]); + if (weight < a) weight = a; + } + + /* look at the "zero" in a relative inf-norm */ + real_t zero = 0.0; + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_xFX[ii]); + if (zero < a) zero = a; + } + for (ii = 0; ii < nFR; ++ii) + { + real_t a = getAbs (delta_xFR[ii]); + if (zero < a) zero = a; + } + + /* relative test against zero in inf-norm */ + if (zero > options.epsLITests * weight) + returnvalue = RET_LINEARLY_INDEPENDENT; + + delete[] delta_yFX; + delete[] delta_yAC; + delete[] delta_xFR; + delete[] delta_xFX; + delete[] delta_g; + + } + else + { + /* + * cheap LI test for constraint. Check if constraint is + * linearly independent from the the active ones (<=> is element of null + * space of Afr). + */ + + real_t *Arow = new real_t[nFR]; + A->getRow(number, bounds.getFree(), 1.0, Arow); + + real_t sum, l2; + + l2 = 0.0; + for (i = 0; i < nFR; i++) + l2 += Arow[i]*Arow[i]; + + for( j=0; j options.epsLITests*l2 ) + { + /*fprintf(stdFile, "LI test: |sum| = %9.2e, l2 = %9.2e, var = %d\n", getAbs(sum), l2, jj+1); */ + returnvalue = RET_LINEARLY_INDEPENDENT; + break; + } + } + + delete[] Arow; + } + + return THROWINFO( returnvalue ); +} + + +/* + * a d d C o n s t r a i n t _ e n s u r e L I + */ +returnValue QProblem::addConstraint_ensureLI( int_t number, SubjectToStatus C_status ) +{ + int_t i, j, ii, jj; + int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nFX = getNFX( ); + int_t nAC = getNAC( ); + int_t nZ = getNZ( ); + + + /* I) Check if new constraint is linearly independent from the active ones. */ + returnValue returnvalueCheckLI = addConstraint_checkLI( number ); + + if ( returnvalueCheckLI == RET_INDEXLIST_CORRUPTED ) + return THROWERROR( RET_ENSURELI_FAILED ); + + if ( returnvalueCheckLI == RET_LINEARLY_INDEPENDENT ) + return SUCCESSFUL_RETURN; + + + /* II) NEW CONSTRAINT IS LINEARLY DEPENDENT: */ + /* 1) Determine coefficients of linear combination, + * cf. M.J. Best. Applied Mathematics and Parallel Computing, chapter: + * An Algorithm for the Solution of the Parametric Quadratic Programming + * Problem, pages 57-76. Physica-Verlag, Heidelberg, 1996. */ + int_t* FR_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + + int_t* FX_idx; + bounds.getFixed( )->getNumberArray( &FX_idx ); + + real_t* xiC = new real_t[nAC]; + real_t* xiC_TMP = new real_t[nAC]; + real_t* xiB = new real_t[nFX]; + real_t* Arow = new real_t[nFR]; + real_t* num = new real_t[nV]; + + returnValue returnvalue = SUCCESSFUL_RETURN; + + real_t y_min = options.maxDualJump; + int_t y_min_number = -1; + int_t y_min_number_bound = -1; + BooleanType y_min_isBound = BT_FALSE; + + A->getRow(number, bounds.getFree(), C_status == ST_LOWER ? 1.0 : -1.0, Arow); + + /* 2) Calculate xiC */ + if ( nAC > 0 ) + { + for( i=0; igetNumberArray( &AC_idx ); + + A->getRow(number, bounds.getFixed(), C_status == ST_LOWER ? 1.0 : -1.0, xiB); + A->transTimes(constraints.getActive(), bounds.getFixed(), 1, -1.0, xiC, nAC, 1.0, xiB, nFX); + + /* III) DETERMINE CONSTRAINT/BOUND TO BE REMOVED. */ + + /* 1) Constraints. */ + for( i=0; i= 0 ) + { + y_min_number = y_min_number_bound; + y_min_isBound = BT_TRUE; + } + + #ifndef __SUPPRESSANYOUTPUT__ + /* setup output preferences */ + char messageString[MAX_STRING_LENGTH]; + #endif + + /* IV) REMOVE CONSTRAINT/BOUND FOR RESOLVING LINEAR DEPENDENCE: */ + if ( y_min_number >= 0 ) + { + /* Update Lagrange multiplier... */ + for( i=0; ithrowInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeBound( y_min_number,BT_TRUE,BT_FALSE,BT_FALSE ) != SUCCESSFUL_RETURN ) + { + returnvalue = RET_REMOVE_FROM_ACTIVESET_FAILED; + goto farewell; + } + tabularOutput.excRemB = 1; + + y[y_min_number] = 0.0; + } + else + { + #ifndef __SUPPRESSANYOUTPUT__ + snprintf( messageString,MAX_STRING_LENGTH,"constraint no. %d.",(int)y_min_number ); + getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeConstraint( y_min_number,BT_TRUE,BT_FALSE,BT_FALSE ) != SUCCESSFUL_RETURN ) + { + returnvalue = RET_REMOVE_FROM_ACTIVESET_FAILED; + goto farewell; + } + tabularOutput.excRemC = 1; + + y[nV+y_min_number] = 0.0; + } + } + else + { + if (options.enableDropInfeasibles == BT_TRUE) { + /* dropping of infeasible constraints according to drop priorities */ + returnvalue = dropInfeasibles (number, C_status, BT_FALSE, xiB, xiC); + } + else + { + /* no constraint/bound can be removed => QP is infeasible! */ + returnvalue = RET_ENSURELI_FAILED_NOINDEX; + setInfeasibilityFlag( returnvalue ); + } + } + +farewell: + delete[] num; + delete[] Arow; + delete[] xiB; + delete[] xiC_TMP; + delete[] xiC; + + getGlobalMessageHandler( )->throwInfo( RET_LI_RESOLVED,0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + + return ( (returnvalue != SUCCESSFUL_RETURN) && (returnvalue != RET_ENSURELI_FAILED_NOINDEX ) ) ? THROWERROR (returnvalue) : returnvalue; +} + + + +/* + * a d d B o u n d + */ +returnValue QProblem::addBound( int_t number, SubjectToStatus B_status, + BooleanType updateCholesky, + BooleanType ensureLI + ) +{ + int_t i, j, ii; + + /* consistency checks */ + if ( bounds.getStatus( number ) != ST_INACTIVE ) + return THROWERROR( RET_BOUND_ALREADY_ACTIVE ); + + if ( getNFR( ) == bounds.getNUV( ) ) + return THROWERROR( RET_ALL_BOUNDS_ACTIVE ); + + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + + /* I) ENSURE LINEAR INDEPENDENCE OF THE WORKING SET, + * i.e. remove a constraint or bound if linear dependence occurs. */ + /* check for LI only if Cholesky decomposition shall be updated! */ + if ( ( updateCholesky == BT_TRUE ) && ( ensureLI == BT_TRUE ) ) + { + returnValue ensureLIreturnvalue = addBound_ensureLI( number,B_status ); + + switch ( ensureLIreturnvalue ) + { + case SUCCESSFUL_RETURN: + break; + + case RET_LI_RESOLVED: + break; + + case RET_ENSURELI_FAILED_NOINDEX: + return RET_ADDBOUND_FAILED_INFEASIBILITY; + + case RET_ENSURELI_FAILED_CYCLING: + return RET_ADDBOUND_FAILED_INFEASIBILITY; + + case RET_ENSURELI_DROPPED: + return SUCCESSFUL_RETURN; + + default: + return THROWERROR( RET_ENSURELI_FAILED ); + } + } + + + /* some definitions */ + int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nAC = getNAC( ); + int_t nZ = getNZ( ); + + int_t tcol = sizeT - nAC; + + + /* II) SWAP INDEXLIST OF FREE VARIABLES: + * move the variable to be fixed to the end of the list of free variables. */ + int_t lastfreenumber = bounds.getFree( )->getLastNumber( ); + if ( lastfreenumber != number ) + if ( bounds.swapFree( number,lastfreenumber ) != SUCCESSFUL_RETURN ) + THROWERROR( RET_ADDBOUND_FAILED ); + + + int_t* FR_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + + real_t* w = new real_t[nFR]; + + + /* III) ADD NEW ACTIVE BOUND TO TOP OF MATRIX T: */ + /* 1) add row [wZ wY] = [Z Y](number) at the top of T: assign w */ + for( i=0; i 0 ) /* ( nAC == 0 ) <=> ( nZ == nFR ) <=> Y and T are empty => nothing to do */ + { + /* store new column a in a temporary vector instead of shifting T one column to the left */ + real_t* tmp = new real_t[nAC]; + for( i=0; inV)?nC:nV; + real_t *nul = new real_t[dim]; + for (ii = 0; ii < dim; ++ii) + nul[ii]=0.0; + + returnValue dsdReturnValue = determineStepDirection ( + delta_g, nul, nul, nul, nul, BT_FALSE, BT_FALSE, + delta_xFX, delta_xFR, delta_yAC, delta_yFX); + if (dsdReturnValue != SUCCESSFUL_RETURN) + returnvalue = dsdReturnValue; + + /* compute the weight in inf-norm */ + real_t weight = 0.0; + for (ii = 0; ii < nAC; ++ii) + { + real_t a = getAbs (delta_yAC[ii]); + if (weight < a) weight = a; + } + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_yFX[ii]); + if (weight < a) weight = a; + } + + /* look at the "zero" in a relative inf-norm */ + real_t zero = 0.0; + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_xFX[ii]); + if (zero < a) zero = a; + } + for (ii = 0; ii < nFR; ++ii) + { + real_t a = getAbs (delta_xFR[ii]); + if (zero < a) zero = a; + } + + /* relative test against zero in inf-norm */ + if (zero > options.epsLITests * weight) + returnvalue = RET_LINEARLY_INDEPENDENT; + + delete[] nul; + delete[] delta_yFX; + delete[] delta_yAC; + delete[] delta_xFR; + delete[] delta_xFX; + delete[] delta_g; + + } + else + { + /* + * cheap LI test for simple bound. Check if constraint is + * linearly independent from the the active ones (<=> is element of null + * space of Afr). + */ + + /* some definitions */ + int_t nZ = getNZ( ); + + for( i=0; i options.epsLITests ) + { + returnvalue = RET_LINEARLY_INDEPENDENT; + break; + } + } + + return THROWINFO( returnvalue ); +} + + +/* + * a d d B o u n d _ e n s u r e L I + */ +returnValue QProblem::addBound_ensureLI( int_t number, SubjectToStatus B_status ) +{ + int_t i, ii; + int_t nV = getNV( ); + int_t nFX = getNFX( ); + int_t nAC = getNAC( ); + int_t nZ = getNZ( ); + + + /* I) Check if new constraint is linearly independent from the active ones. */ + returnValue returnvalueCheckLI = addBound_checkLI( number ); + + if ( returnvalueCheckLI == RET_INDEXLIST_CORRUPTED ) + return THROWERROR( RET_ENSURELI_FAILED ); + + if ( returnvalueCheckLI == RET_LINEARLY_INDEPENDENT ) + return SUCCESSFUL_RETURN; + + + /* II) NEW BOUND IS LINEARLY DEPENDENT: */ + /* 1) Determine coefficients of linear combination, + * cf. M.J. Best. Applied Mathematics and Parallel Computing, chapter: + * An Algorithm for the Solution of the Parametric Quadratic Programming + * Problem, pages 57-76. Physica-Verlag, Heidelberg, 1996. */ + int_t* FR_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + + int_t* FX_idx; + bounds.getFixed( )->getNumberArray( &FX_idx ); + + int_t* AC_idx; + constraints.getActive( )->getNumberArray( &AC_idx ); + + real_t* xiC = new real_t[nAC]; + real_t* xiC_TMP = new real_t[nAC]; + real_t* xiB = new real_t[nFX]; + real_t* num = new real_t[nV]; + + real_t y_min = options.maxDualJump; + int_t y_min_number = -1; + int_t y_min_number_bound = -1; + BooleanType y_min_isBound = BT_FALSE; + + returnValue returnvalue = SUCCESSFUL_RETURN; + + + /* 2) Calculate xiC. */ + if ( nAC > 0 ) + { + if ( B_status == ST_LOWER ) + { + for( i=0; itransTimes(constraints.getActive(), bounds.getFixed(), 1, -1.0, xiC, nAC, 0.0, xiB, nFX); + + + /* III) DETERMINE CONSTRAINT/BOUND TO BE REMOVED. */ + + /* 1) Constraints. */ + for( i=0; i= 0 ) + { + y_min_number = y_min_number_bound; + y_min_isBound = BT_TRUE; + } + + /* IV) REMOVE CONSTRAINT/BOUND FOR RESOLVING LINEAR DEPENDENCE: */ + #ifndef __SUPPRESSANYOUTPUT__ + char messageString[MAX_STRING_LENGTH]; + #endif + + if ( y_min_number >= 0 ) + { + /* Update Lagrange multiplier... */ + for( i=0; ithrowInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeBound( y_min_number,BT_TRUE,BT_FALSE,BT_FALSE ) != SUCCESSFUL_RETURN ) + { + returnvalue = RET_REMOVE_FROM_ACTIVESET_FAILED; + goto farewell; + } + tabularOutput.excRemB = 1; + + y[y_min_number] = 0.0; + } + else + { + #ifndef __SUPPRESSANYOUTPUT__ + snprintf( messageString,MAX_STRING_LENGTH,"constraint no. %d.",(int)y_min_number ); + getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeConstraint( y_min_number,BT_TRUE,BT_FALSE,BT_FALSE ) != SUCCESSFUL_RETURN ) + { + returnvalue = RET_REMOVE_FROM_ACTIVESET_FAILED; + goto farewell; + } + tabularOutput.excRemC = 1; + + y[nV+y_min_number] = 0.0; + } + } + else + { + if (options.enableDropInfeasibles == BT_TRUE) { + /* dropping of infeasible constraints according to drop priorities */ + returnvalue = dropInfeasibles (number, B_status, BT_TRUE, xiB, xiC); + } + else + { + /* no constraint/bound can be removed => QP is infeasible! */ + returnvalue = RET_ENSURELI_FAILED_NOINDEX; + setInfeasibilityFlag( returnvalue ); + } + } + +farewell: + delete[] num; + delete[] xiB; + delete[] xiC_TMP; + delete[] xiC; + + getGlobalMessageHandler( )->throwInfo( RET_LI_RESOLVED,0,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + + return ( (returnvalue != SUCCESSFUL_RETURN) && (returnvalue != RET_ENSURELI_FAILED_NOINDEX ) ) ? THROWERROR (returnvalue) : returnvalue; +} + + + +/* + * r e m o v e C o n s t r a i n t + */ +returnValue QProblem::removeConstraint( int_t number, + BooleanType updateCholesky, + BooleanType allowFlipping, + BooleanType ensureNZC + ) +{ + int_t i, j, ii, jj; + returnValue returnvalue = SUCCESSFUL_RETURN; + BooleanType hasFlipped = BT_FALSE; + + /* consistency check */ + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + /* some definitions */ + int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nAC = getNAC( ); + int_t nZ = getNZ( ); + + int_t tcol = sizeT - nAC; + int_t number_idx = constraints.getActive( )->getIndex( number ); + + int_t addIdx; + BooleanType addBoundNotConstraint; + SubjectToStatus addStatus; + BooleanType exchangeHappened = BT_FALSE; + + + /* consistency checks */ + if ( constraints.getStatus( number ) == ST_INACTIVE ) + return THROWERROR( RET_CONSTRAINT_NOT_ACTIVE ); + + if ( ( number_idx < 0 ) || ( number_idx >= nAC ) ) + return THROWERROR( RET_CONSTRAINT_NOT_ACTIVE ); + + + int_t* FR_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + + /* N) PERFORM ZERO CURVATURE TEST. */ + if (ensureNZC == BT_TRUE) + { + returnvalue = ensureNonzeroCurvature(BT_FALSE, number, exchangeHappened, addBoundNotConstraint, addIdx, addStatus); + + if (returnvalue != SUCCESSFUL_RETURN) + return returnvalue; + } + + /* save index sets and decompositions for flipping bounds strategy */ + if ( ( exchangeHappened == BT_FALSE ) && ( options.enableFlippingBounds == BT_TRUE ) && ( allowFlipping == BT_TRUE ) ) + flipper.set( &bounds,R,&constraints,Q,T ); + + /* I) REMOVE th ROW FROM T, + * i.e. shift rows number+1 through nAC upwards (instead of the actual + * constraint number its corresponding index within matrix A is used). */ + if ( number_idx < nAC-1 ) + { + for( i=(number_idx+1); i=0; --j ) + { + computeGivens( TT(nAC-2-j,tcol+1+j),TT(nAC-2-j,tcol+j), TT(nAC-2-j,tcol+1+j),TT(nAC-2-j,tcol+j),c,s ); + nu = s/(1.0+c); + + for( i=(nAC-j-1); i<(nAC-1); ++i ) + applyGivens( c,s,nu,TT(i,tcol+1+j),TT(i,tcol+j), TT(i,tcol+1+j),TT(i,tcol+j) ); + + for( i=0; itimes(bounds.getFree(), bounds.getFree(), 1, 1.0, z, nFR, 0.0, Hz, nFR); + delete[] z; + + if ( nZ > 0 ) + { + real_t* ZHz = new real_t[nZ]; + for ( i=0; i options.epsFlipping ) + RR(nZ,nZ) = getSqrt( rho2 ); + else + { + hessianType = HST_SEMIDEF; + + flipper.get( &bounds,R,&constraints,Q,T ); + constraints.flipFixed(number); + tabularOutput.idxAddC = number; + tabularOutput.excAddC = 2; + + switch (constraints.getStatus(number)) + { + case ST_LOWER: + lbA[number] = ubA[number]; Ax_l[number] = -Ax_u[number]; break; + case ST_UPPER: + ubA[number] = lbA[number]; Ax_u[number] = -Ax_l[number]; break; + default: + return THROWERROR( RET_MOVING_BOUND_FAILED ); + } + + hasFlipped = BT_TRUE; + } + } + else if ( exchangeHappened == BT_FALSE ) + { + if ( rho2 > ZERO ) + RR(nZ,nZ) = getSqrt( rho2 ); + else + { + if ( allowFlipping == BT_FALSE ) + { + RR(nZ,nZ) = 100.0*EPS; + } + else + { + hessianType = HST_SEMIDEF; + return THROWERROR( RET_HESSIAN_NOT_SPD ); + } + } + } + } + + + /* IV) UPDATE INDICES */ + tabularOutput.idxRemC = number; + if ( hasFlipped == BT_FALSE ) + { + if ( constraints.moveActiveToInactive( number ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVECONSTRAINT_FAILED ); + } + + if (exchangeHappened == BT_TRUE) + { + /* add bound or constraint */ + + /* hessianType = HST_SEMIDEF; */ + RR(nZ,nZ) = 0.0; + + if ( addBoundNotConstraint ) + { + addBound(addIdx, addStatus, BT_TRUE, BT_FALSE); + tabularOutput.excAddB = 1; + } + else + { + addConstraint(addIdx, addStatus, BT_TRUE, BT_FALSE); + tabularOutput.excAddC = 1; + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * r e m o v e B o u n d + */ +returnValue QProblem::removeBound( int_t number, + BooleanType updateCholesky, + BooleanType allowFlipping, + BooleanType ensureNZC + ) +{ + int_t i, j, ii, jj; + returnValue returnvalue = SUCCESSFUL_RETURN; + int_t addIdx; + BooleanType addBoundNotConstraint; + SubjectToStatus addStatus; + BooleanType exchangeHappened = BT_FALSE; + + + /* consistency checks */ + if ( bounds.getStatus( number ) == ST_INACTIVE ) + return THROWERROR( RET_BOUND_NOT_ACTIVE ); + + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + /* some definitions */ + int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nAC = getNAC( ); + int_t nZ = getNZ( ); + + int_t tcol = sizeT - nAC; + + /* 0) PERFORM ZERO CURVATURE TEST. */ + if (ensureNZC == BT_TRUE) + { + returnvalue = ensureNonzeroCurvature(BT_TRUE, number, exchangeHappened, addBoundNotConstraint, addIdx, addStatus); + + if (returnvalue != SUCCESSFUL_RETURN) + return returnvalue; + } + + /* save index sets and decompositions for flipping bounds strategy */ + if ( ( options.enableFlippingBounds == BT_TRUE ) && ( allowFlipping == BT_TRUE ) && ( exchangeHappened == BT_FALSE ) ) + flipper.set( &bounds,R,&constraints,Q,T ); + + /* I) UPDATE INDICES */ + tabularOutput.idxRemB = number; + if ( bounds.moveFixedToFree( number ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVEBOUND_FAILED ); + + int_t* FR_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + + /* I) APPEND th UNITY VECTOR TO Q. */ + int_t nnFRp1 = FR_idx[nFR]; + for( i=0; i 0 ) + { + /* store new column a in a temporary vector instead of shifting T one column to the left and appending a */ + int_t* AC_idx; + constraints.getActive( )->getNumberArray( &AC_idx ); + + real_t* tmp = new real_t[nAC]; + A->getCol(number, constraints.getActive(), 1.0, tmp); + + + /* II) RESTORE TRIANGULAR FORM OF T, + * use column-wise Givens rotations to restore reverse triangular form + * of T = [T A(:,number)], simultanenous change of Q (i.e. Y and Z). */ + real_t c, s, nu; + + for( j=(nAC-1); j>=0; --j ) + { + computeGivens( tmp[nAC-1-j],TT(nAC-1-j,tcol+j),TT(nAC-1-j,tcol+j),tmp[nAC-1-j],c,s ); + nu = s/(1.0+c); + + for( i=(nAC-j); idiag(nnFRp1) * z2*z2; + + if ( nFR > 0 ) + { + /* Attention: Index list of free variables has already grown by one! */ + real_t* Hz = new real_t[nFR+1]; + real_t* z = new real_t[nFR+1]; + /* 1) Calculate R'*r = Zfr'*Hfr*z1 + z2*Zfr'*h1 =: Zfr'*Hz + z2*Zfr'*h1 =: rhs and + * rho2 = z1'*Hfr*z1 + 2*z2*h1'*z1 + h2*z2^2 - r'*r =: z1'*Hz + 2*z2*h1'*z1 + h2*z2^2 - r'r */ + for( j=0; jtimes(bounds.getFree(), bounds.getFree(), 1, 1.0, z, nFR+1, 0.0, Hz, nFR+1); + H->getCol(nnFRp1, bounds.getFree(), 1.0, z); + + if ( nZ > 0 ) + { + real_t* r = new real_t[nZ]; + real_t* rhs = new real_t[nZ]; + for( i=0; i options.epsFlipping ) + RR(nZ,nZ) = getSqrt( rho2 ); + else + { + if ( hessianType != HST_ZERO ) + hessianType = HST_SEMIDEF; + + flipper.get( &bounds,R,&constraints,Q,T ); + bounds.flipFixed(number); + tabularOutput.idxAddB = number; + tabularOutput.excAddB = 2; + + switch (bounds.getStatus(number)) + { + case ST_LOWER: + lb[number] = ub[number]; + break; + case ST_UPPER: + ub[number] = lb[number]; + break; + default: return THROWERROR( RET_MOVING_BOUND_FAILED ); + } + + } + } + else if ( exchangeHappened == BT_FALSE ) + { + if ( rho2 > ZERO ) + RR(nZ,nZ) = getSqrt( rho2 ); + else + { + if ( allowFlipping == BT_FALSE ) + RR(nZ,nZ) = 100.0*EPS; + else + { + hessianType = HST_SEMIDEF; + return THROWERROR( RET_HESSIAN_NOT_SPD ); + } + } + } + else + { + /* add bound or constraint */ + + /* hessianType = HST_SEMIDEF; */ + RR(nZ,nZ) = 0.0; + + if ( addBoundNotConstraint ) + { + addBound(addIdx, addStatus, BT_TRUE, BT_FALSE); + tabularOutput.excAddB = 1; + } + else + { + addConstraint(addIdx, addStatus, BT_TRUE, BT_FALSE); + tabularOutput.excAddC = 1; + } + } + } + + return SUCCESSFUL_RETURN; +} + + + +returnValue QProblem::performPlainRatioTest( int_t nIdx, + const int_t* const idxList, + const real_t* const num, + const real_t* const den, + real_t epsNum, + real_t epsDen, + real_t& t, + int_t& BC_idx + ) const +{ + int_t i; + for (i = 0; i < nIdx; i++) + if ( (num[i] > epsNum) && (den[i] > epsDen) && (t * den[i] > num[i]) ) + { + t = num[i] / den[i]; + BC_idx = idxList[i]; + } + + return SUCCESSFUL_RETURN; +} + + +returnValue QProblem::ensureNonzeroCurvature( BooleanType removeBoundNotConstraint, + int_t remIdx, + BooleanType &exchangeHappened, + BooleanType &addBoundNotConstraint, + int_t &addIdx, + SubjectToStatus &addStatus + ) +{ + int_t i, ii; + int_t addLBndIdx = -1, addLCnstrIdx = -1, addUBndIdx = -1, addUCnstrIdx = -1; /* exchange indices */ + int_t *FX_idx, *AC_idx, *IAC_idx; + returnValue returnvalue = SUCCESSFUL_RETURN; + + int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nAC = getNAC( ); + int_t nC = getNC( ); + int_t nFX = getNFX( ); + int_t nIAC = getNIAC( ); + + int_t* FR_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + +// real_t *delta_g = new real_t[nV]; + real_t *delta_xFX = new real_t[nFX]; + real_t *delta_xFR = new real_t[nFR]; + real_t *delta_yAC = new real_t[nAC]; + real_t *delta_yFX = new real_t[nFX]; + + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + constraints.getInactive( )->getNumberArray( &IAC_idx ); + + addBoundNotConstraint = BT_TRUE; + addStatus = ST_INACTIVE; + exchangeHappened = BT_FALSE; + + if (removeBoundNotConstraint) + { + int_t dim = nV < nC ? nC : nV; + real_t *nul = new real_t[dim]; + real_t *ek = new real_t[nV]; /* minus e_k (bound k is removed) */ + for (ii = 0; ii < dim; ++ii) + nul[ii]=0.0; + for (ii = 0; ii < nV; ++ii) + ek[ii]=0.0; + ek[remIdx] = bounds.getStatus(remIdx) == ST_LOWER ? 1.0 : -1.0; + + returnvalue = determineStepDirection (nul, nul, nul, ek, ek, + BT_FALSE, BT_FALSE, + delta_xFX, delta_xFR, delta_yAC, delta_yFX); + delete[] ek; + delete[] nul; + } + else + { + real_t *nul = new real_t[nV]; + real_t *ek = new real_t[nC]; /* minus e_k (constraint k is removed) */ + for (ii = 0; ii < nV; ++ii) + nul[ii]=0.0; + for (ii = 0; ii < nC; ++ii) + ek[ii]=0.0; + ek[remIdx] = constraints.getStatus(remIdx) == ST_LOWER ? 1.0 : -1.0; + + returnvalue = determineStepDirection (nul, + ek, ek, nul, nul, + BT_FALSE, BT_TRUE, + delta_xFX, delta_xFR, delta_yAC, delta_yFX); + delete[] ek; + delete[] nul; + } + + /* compute the weight in inf-norm */ + real_t normXi = 0.0; + for (ii = 0; ii < nAC; ++ii) + { + real_t a = getAbs (delta_yAC[ii]); + if (normXi < a) normXi = a; + } + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_yFX[ii]); + if (normXi < a) normXi = a; + } + + /* look at the "zero" in a relative inf-norm */ + real_t normS = 0.0; + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_xFX[ii]); + if (normS < a) normS = a; + } + for (ii = 0; ii < nFR; ++ii) + { + real_t a = getAbs (delta_xFR[ii]); + if (normS < a) normS = a; + } + + /* relative test against zero in inf-norm */ + if (normXi < options.epsNZCTests * normS) + { + /* determine jump in x via ratio tests */ + real_t sigmaLBnd, sigmaLCnstr, sigmaUBnd, sigmaUCnstr, sigma; + + /* bounds */ + + /* compress x-u */ + real_t *x_W = new real_t[getMax(1,nFR)]; + for (i = 0; i < nFR; i++) + { + ii = FR_idx[i]; + x_W[i] = ub[ii] - x[ii]; + } + /* performRatioTest( nFR,FR_idx,&bounds, x_W,delta_xFR, options.epsNum,options.epsDen, sigmaUBnd,addUBndIdx ); */ + sigmaUBnd = options.maxPrimalJump; + addUBndIdx = -1; + performPlainRatioTest(nFR, FR_idx, x_W, delta_xFR, options.epsNum, options.epsDen, sigmaUBnd, addUBndIdx); + if (removeBoundNotConstraint == BT_TRUE && bounds.getStatus(remIdx) == ST_LOWER) + { + /* also consider bound which is to be removed */ + real_t one = 1.0; + x_W[0] = ub[remIdx] - x[remIdx]; + performPlainRatioTest(1, &remIdx, x_W, &one, options.epsNum, options.epsDen, sigmaUBnd, addUBndIdx); + } + + /* compress x-l */ + for (i = 0; i < nFR; i++) + { + ii = FR_idx[i]; + x_W[i] = x[ii] - lb[ii]; + } + for (i = 0; i < nFR; i++) + delta_xFR[i] = -delta_xFR[i]; + /* performRatioTest( nFR,FR_idx,&bounds, x_W,delta_xFR, options.epsNum,options.epsDen, sigmaLBnd,addLBndIdx ); */ + sigmaLBnd = options.maxPrimalJump; + addLBndIdx = -1; + performPlainRatioTest(nFR, FR_idx, x_W, delta_xFR, options.epsNum, options.epsDen, sigmaLBnd, addLBndIdx); + if (removeBoundNotConstraint == BT_TRUE && bounds.getStatus(remIdx) == ST_UPPER) + { + /* also consider bound which is to be removed */ + real_t one = 1.0; + x_W[0] = x[remIdx] - lb[remIdx]; + performPlainRatioTest(1, &remIdx, x_W, &one, options.epsNum, options.epsDen, sigmaLBnd, addLBndIdx); + } + for (i = 0; i < nFR; i++) + delta_xFR[i] = -delta_xFR[i]; + + delete[] x_W; + + /* constraints */ + + /* compute As (compressed to inactive constraints) */ + real_t *As = new real_t[nIAC]; + A->times(constraints.getInactive(), bounds.getFixed(), 1, 1.0, delta_xFX, nFX, 0.0, As, nIAC); + A->times(constraints.getInactive(), bounds.getFree(), 1, 1.0, delta_xFR, nFR, 1.0, As, nIAC); + + /* compress Ax_u */ + real_t *Ax_W = new real_t[nIAC]; + for (i = 0; i < nIAC; i++) + { + ii = IAC_idx[i]; + Ax_W[i] = Ax_u[ii]; + } + /* performRatioTest( nIAC,IAC_idx,&constraints, Ax_W,As, options.epsNum,options.epsDen, sigmaUCnstr,addUCnstrIdx ); */ + sigmaUCnstr = options.maxPrimalJump; + addUCnstrIdx = -1; + performPlainRatioTest(nIAC, IAC_idx, Ax_W, As, options.epsNum, options.epsDen, sigmaUCnstr, addUCnstrIdx); + if (removeBoundNotConstraint == BT_FALSE && constraints.getStatus(remIdx) == ST_LOWER) + { + /* also consider constraint which is to be removed */ + real_t one = 1.0; + performPlainRatioTest(1, &remIdx, &Ax_u[remIdx], &one, options.epsNum, options.epsDen, sigmaUCnstr, addUCnstrIdx); + } + + /* compress Ax_l */ + for (i = 0; i < nIAC; i++) + { + ii = IAC_idx[i]; + Ax_W[i] = Ax_l[ii]; + } + for (i = 0; i < nIAC; i++) + As[i] = -As[i]; + /* performRatioTest( nIAC,IAC_idx,&constraints, Ax_W,As, options.epsNum,options.epsDen, sigmaLCnstr,addLCnstrIdx ); */ + sigmaLCnstr = options.maxPrimalJump; + addLCnstrIdx = -1; + performPlainRatioTest(nIAC, IAC_idx, Ax_W, As, options.epsNum, options.epsDen, sigmaLCnstr, addLCnstrIdx); + if (removeBoundNotConstraint == BT_FALSE && constraints.getStatus(remIdx) == ST_UPPER) + { + /* also consider constraint which is to be removed */ + real_t one = 1.0; + performPlainRatioTest(1, &remIdx, &Ax_l[remIdx], &one, options.epsNum, options.epsDen, sigmaLCnstr, addLCnstrIdx); + } + + /* perform primal jump */ + sigma = options.maxPrimalJump; + if (sigmaUCnstr < sigma) { sigma = sigmaUCnstr; addStatus = ST_UPPER; addBoundNotConstraint = BT_FALSE; addIdx = addUCnstrIdx; } + if (sigmaLCnstr < sigma) { sigma = sigmaLCnstr; addStatus = ST_LOWER; addBoundNotConstraint = BT_FALSE; addIdx = addLCnstrIdx; } + if (sigmaUBnd < sigma) { sigma = sigmaUBnd; addStatus = ST_UPPER; addBoundNotConstraint = BT_TRUE; addIdx = addUBndIdx; } + if (sigmaLBnd < sigma) { sigma = sigmaLBnd; addStatus = ST_LOWER; addBoundNotConstraint = BT_TRUE; addIdx = addLBndIdx; } + + if (sigma >= options.maxPrimalJump) + { + unbounded = BT_TRUE; + returnvalue = RET_HOTSTART_STOPPED_UNBOUNDEDNESS; + } + else + { + for (i = 0; i < nFR; i++) + x[FR_idx[i]] += sigma * delta_xFR[i]; + + for (i = 0; i < nFX; i++) + x[FX_idx[i]] += sigma * delta_xFX[i]; + + /* update Ax, Ax_u, and Ax_l */ + A->times(1, 1.0, x, nV, 0.0, Ax, nC); + for (i = 0; i < nC; i++) Ax_u[i] = ubA[i] - Ax[i]; + for (i = 0; i < nC; i++) Ax_l[i] = Ax[i] - lbA[i]; + + /* change working set later */ + exchangeHappened = BT_TRUE; + } + + delete[] Ax_W; + delete[] As; + } + + delete[] delta_yFX; + delete[] delta_yAC; + delete[] delta_xFR; + delete[] delta_xFX; +// delete[] delta_g; + + return returnvalue; +} + + + +/* + * b a c k s o l v e T + */ +returnValue QProblem::backsolveT( const real_t* const b, BooleanType transposed, real_t* const a ) const +{ + int_t i, j; + int_t nT = getNAC( ); + int_t tcol = sizeT - nT; + + real_t sum; + + /* nothing to do */ + if ( nT <= 0 ) + return SUCCESSFUL_RETURN; + + + /* Solve Ta = b, where T might be transposed. */ + if ( transposed == BT_FALSE ) + { + /* solve Ta = b */ + for( i=0; i EPS ) + a[nT-1-i] = sum / TT(i,sizeT-1-i); + else + return THROWERROR( RET_DIV_BY_ZERO ); + } + } + else + { + /* solve T^T*a = b */ + for( i=0; i EPS ) + a[nT-1-i] = sum / TT(nT-1-i,tcol+i); + else + return THROWERROR( RET_DIV_BY_ZERO ); + } + } + + + return SUCCESSFUL_RETURN; +} + + +/* + * d e t e r m i n e D a t a S h i f t + */ +returnValue QProblem::determineDataShift( const real_t* const g_new, const real_t* const lbA_new, const real_t* const ubA_new, + const real_t* const lb_new, const real_t* const ub_new, + real_t* const delta_g, real_t* const delta_lbA, real_t* const delta_ubA, + real_t* const delta_lb, real_t* const delta_ub, + BooleanType& Delta_bC_isZero, BooleanType& Delta_bB_isZero + ) +{ + int_t i, ii; + int_t nC = getNC( ); + int_t nAC = getNAC( ); + + int_t* FX_idx; + int_t* AC_idx; + + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + + + + /* I) DETERMINE DATA SHIFT FOR BOUNDS */ + QProblemB::determineDataShift( g_new,lb_new,ub_new, + delta_g,delta_lb,delta_ub, + Delta_bB_isZero ); + + + /* II) DETERMINE DATA SHIFT FOR CONSTRAINTS */ + /* 1) Calculate shift directions. */ + for( i=0; i EPS ) || ( getAbs( delta_ubA[ii] ) > EPS ) ) + { + Delta_bC_isZero = BT_FALSE; + break; + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * d e t e r m i n e S t e p D i r e c t i o n + */ +returnValue QProblem::determineStepDirection( const real_t* const delta_g, const real_t* const delta_lbA, const real_t* const delta_ubA, + const real_t* const delta_lb, const real_t* const delta_ub, + BooleanType Delta_bC_isZero, BooleanType Delta_bB_isZero, + real_t* const delta_xFX, real_t* const delta_xFR, + real_t* const delta_yAC, real_t* const delta_yFX + ) +{ + int_t i, j, ii, jj, r; + int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nFX = getNFX( ); + int_t nAC = getNAC( ); + int_t nZ = getNZ( ); + + int_t* FR_idx; + int_t* FX_idx; + int_t* AC_idx; + + bounds.getFree( )->getNumberArray( &FR_idx ); + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + + + /* I) DETERMINE delta_xFX (this is exact, does not need refinement) */ + if ( Delta_bB_isZero == BT_FALSE ) + { + for( i=0; i 0 ) + { + for( i=0; i 0 ) + { + if ( ( Delta_bC_isZero == BT_TRUE ) && ( Delta_bB_isZero == BT_TRUE ) ) + { + for( i=0; i + * in refinements r>=1, delta_xFX is exactly zero */ + if ( ( Delta_bB_isZero == BT_FALSE ) && ( r == 0 ) ) + A->times(constraints.getActive(), bounds.getFixed(), 1, -1.0, delta_xFX, nFX, 1.0, tempB, nAC); + + if ( backsolveT( tempB, BT_FALSE, delta_xFRy ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_STEPDIRECTION_FAILED_TQ ); + + for( i=0; i 0 ) + return THROWERROR( RET_UNKNOWN_BUG ); + } + } + } + else + { + /* compute HMX*delta_xFX. DESTROY delta_gFR that was in tempA */ + if ( ( Delta_bB_isZero == BT_FALSE ) && ( r == 0 ) ) + H->times(bounds.getFree(), bounds.getFixed(), 1, 1.0, delta_xFX, nFX, 1.0, tempA, nFR); + + /* compute HFR*delta_xFRy */ + if ( ( nAC > 0 ) && ( ( Delta_bC_isZero == BT_FALSE ) || ( Delta_bB_isZero == BT_FALSE ) ) ) + H->times(bounds.getFree(), bounds.getFree(), 1, 1.0, delta_xFR_TMP, nFR, 1.0, tempA, nFR); + + /* compute ZFR_delta_xFRz = (Z'*HFR*Z) \ Z * (HFR*delta_xFR + HMX*delta_xFX + delta_gFR) */ + if ( nZ > 0 ) + { + for( j=0; j 0 ) + { + for( i=0; i 0 ) /* => ( nFR = nZ + nAC > 0 ) */ + { + if ( ( hessianType == HST_ZERO ) || ( hessianType == HST_IDENTITY ) ) + { + /* if zero: delta_yAC = (T')^-1 * ( Yfr*delta_gFR + eps*delta_xFRy ), + * if identity: delta_yAC = (T')^-1 * ( Yfr*delta_gFR + delta_xFRy ) + * + * DESTROY residual_bA that was stored in tempB + * If we come here, residual_gFR in tempA is STILL VALID + */ + if ( hessianType == HST_IDENTITY ) + { + for( j=0; j 0 ) + H->times(bounds.getFree(), bounds.getFree(), 1, 1.0, ZFR_delta_xFRz, nFR, 1.0, tempA, nFR); + + for( i=0; i 0 ) + { + /* compute residuals in tempA and tempB, and max-norm */ + for ( i=0; itimes(bounds.getFree(), bounds.getFree(), 1, 1.0, delta_xFR, nFR, 1.0, tempA, nFR); + H->times(bounds.getFree(), bounds.getFixed(), 1, 1.0, delta_xFX, nFX, 1.0, tempA, nFR); + break; + } + + A->transTimes(constraints.getActive(), bounds.getFree(), 1, -1.0, delta_yAC, nAC, 1.0, tempA, nFR); + real_t rnrm = 0.0; + for ( i=0; itimes(constraints.getActive(), bounds.getFree(), 1, -1.0, delta_xFR, nFR, 1.0, tempB, nAC); + A->times(constraints.getActive(), bounds.getFixed(), 1, -1.0, delta_xFX, nFX, 1.0, tempB, nAC); + for ( i=0; i 0 ) + { + for( i=0; itransTimes(constraints.getActive(), bounds.getFixed(), 1, -1.0, delta_yAC, nAC, 1.0, delta_yFX, nFX); + + switch( hessianType ) + { + case HST_ZERO: + if ( usingRegularisation( ) == BT_TRUE ) + for( i=0; itimes(bounds.getFixed(), bounds.getFree(), 1, 1.0, delta_xFR, nFR, 1.0, delta_yFX, nFX); + H->times(bounds.getFixed(), bounds.getFixed(), 1, 1.0, delta_xFX, nFX, 1.0, delta_yFX, nFX); + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * p e r f o r m S t e p + */ +returnValue QProblem::performStep( const real_t* const delta_g, + const real_t* const delta_lbA, const real_t* const delta_ubA, + const real_t* const delta_lb, const real_t* const delta_ub, + const real_t* const delta_xFX, const real_t* const delta_xFR, + const real_t* const delta_yAC, const real_t* const delta_yFX, + int_t& BC_idx, SubjectToStatus& BC_status, BooleanType& BC_isBound + ) +{ + int_t i, j, ii, jj; + int_t nV = getNV( ); + int_t nC = getNC( ); + int_t nFR = getNFR( ); + int_t nFX = getNFX( ); + int_t nAC = getNAC( ); + int_t nIAC = getNIAC( ); + + int_t* FR_idx; + int_t* FX_idx; + int_t* AC_idx; + int_t* IAC_idx; + + bounds.getFree( )->getNumberArray( &FR_idx ); + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + constraints.getInactive( )->getNumberArray( &IAC_idx ); + + /* initialise maximum steplength array */ + tau = 1.0; + BC_idx = -1; + BC_status = ST_UNDEFINED; + + int_t BC_idx_tmp = -1; + + real_t* num = new real_t[ getMax( nV,nC ) ]; + real_t* den = new real_t[ getMax( nV,nC ) ]; + + real_t* delta_Ax_l = new real_t[nC]; + real_t* delta_Ax_u = new real_t[nC]; + real_t* delta_Ax = new real_t[nC]; + + real_t* delta_x = new real_t[nV]; + for( j=0; j= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_INACTIVE; + BC_isBound = BT_FALSE; + } + + + /* 2) Ensure that active dual bounds remain valid + * (ignoring implicitly fixed variables). */ + for( i=0; i= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_INACTIVE; + BC_isBound = BT_TRUE; + } + + + /* II) DETERMINE MAXIMUM PRIMAL STEPLENGTH */ + /* 1) Ensure that inactive constraints' bounds remain valid + * (ignoring unbounded constraints). */ + + /* calculate product A*x */ + if ( constraintProduct == 0 ) + { + A->times(constraints.getInactive(), 0, 1, 1.0, delta_x, nV, 0.0, delta_Ax, nC, BT_FALSE); + } + else + { + for( i=0; i= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_LOWER; + BC_isBound = BT_FALSE; + } + } + + if ( constraints.hasNoUpper( ) == BT_FALSE ) + { + for( i=0; i= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_UPPER; + BC_isBound = BT_FALSE; + } + } + + + for( i=0; i= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_LOWER; + BC_isBound = BT_TRUE; + } + } + + /* inactive upper bounds */ + if ( bounds.hasNoUpper( ) == BT_FALSE ) + { + for( i=0; i= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_UPPER; + BC_isBound = BT_TRUE; + } + } + + delete[] den; + delete[] num; + delete[] delta_x; + + + #ifndef __SUPPRESSANYOUTPUT__ + char messageString[MAX_STRING_LENGTH]; + + if ( BC_status == ST_UNDEFINED ) + snprintf( messageString,MAX_STRING_LENGTH,"Stepsize is %.15e!",tau ); + else + snprintf( messageString,MAX_STRING_LENGTH,"Stepsize is %.15e! (idx = %d, isBound = %d, status = %d)",tau,(int)BC_idx,(int)BC_isBound,(int)BC_status ); + + getGlobalMessageHandler( )->throwInfo( RET_STEPSIZE_NONPOSITIVE,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + + /* III) PERFORM STEP ALONG HOMOTOPY PATH */ + if ( tau > ZERO ) + { + /* 1) Perform step in primal and dual space... */ + for( i=0; itimes( constraints.getActive(),0, 1, 1.0, x, nV, 0.0, Ax, nC, BT_FALSE ); + for( i=0; ithrowWarning( RET_STEPSIZE,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + } + + delete[] delta_Ax; delete[] delta_Ax_u; delete[] delta_Ax_l; + + return SUCCESSFUL_RETURN; +} + + +/* + * c h a n g e A c t i v e S e t + */ +returnValue QProblem::changeActiveSet( int_t BC_idx, SubjectToStatus BC_status, BooleanType BC_isBound ) +{ + int_t nV = getNV( ); + + #ifndef __SUPPRESSANYOUTPUT__ + char messageString[MAX_STRING_LENGTH]; + #endif + + switch ( BC_status ) + { + /* Optimal solution found as no working set change detected. */ + case ST_UNDEFINED: + return SUCCESSFUL_RETURN; + + /* Remove one variable from active set. */ + case ST_INACTIVE: + if ( BC_isBound == BT_TRUE ) + { + #ifndef __SUPPRESSANYOUTPUT__ + snprintf( messageString,MAX_STRING_LENGTH,"bound no. %d.",(int)BC_idx ); + getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeBound( BC_idx,BT_TRUE,BT_TRUE,options.enableNZCTests ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED ); + + y[BC_idx] = 0.0; + } + else + { + #ifndef __SUPPRESSANYOUTPUT__ + snprintf( messageString,MAX_STRING_LENGTH,"constraint no. %d.",(int)BC_idx ); + getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeConstraint( BC_idx,BT_TRUE,BT_TRUE,options.enableNZCTests ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED ); + + y[nV+BC_idx] = 0.0; + } + break; + + + /* Add one variable to active set. */ + default: + returnValue returnvalue; + if ( BC_isBound == BT_TRUE ) + { + #ifndef __SUPPRESSANYOUTPUT__ + if ( BC_status == ST_LOWER ) + snprintf( messageString,MAX_STRING_LENGTH,"lower bound no. %d.",(int)BC_idx ); + else + snprintf( messageString,MAX_STRING_LENGTH,"upper bound no. %d.",(int)BC_idx ); + getGlobalMessageHandler( )->throwInfo( RET_ADD_TO_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + returnvalue = addBound( BC_idx,BC_status,BT_TRUE ); + if ( returnvalue == RET_ADDBOUND_FAILED_INFEASIBILITY ) + return returnvalue; + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( RET_ADD_TO_ACTIVESET_FAILED ); + } + else + { + #ifndef __SUPPRESSANYOUTPUT__ + if ( BC_status == ST_LOWER ) + snprintf( messageString,MAX_STRING_LENGTH,"lower constraint's bound no. %d.",(int)BC_idx ); + else + snprintf( messageString,MAX_STRING_LENGTH,"upper constraint's bound no. %d.",(int)BC_idx ); + getGlobalMessageHandler( )->throwInfo( RET_ADD_TO_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + returnvalue = addConstraint( BC_idx,BC_status,BT_TRUE ); + if ( returnvalue == RET_ADDCONSTRAINT_FAILED_INFEASIBILITY ) + return returnvalue; + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( RET_ADD_TO_ACTIVESET_FAILED ); + } + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * g e t R e l a t i v e H o m o t o p y L e n g t h + */ +real_t QProblem::getRelativeHomotopyLength( const real_t* const g_new, const real_t* const lb_new, const real_t* const ub_new, + const real_t* const lbA_new, const real_t* const ubA_new + ) +{ + int_t i; + int_t nC = getNC( ); + real_t len = QProblemB::getRelativeHomotopyLength( g_new,lb_new,ub_new ); + real_t d, s; + + /*fprintf( stdFile, "len in homotopyLength = %.3e\n",len ); */ + + /* lower constraint bounds */ + if ( lbA_new != 0 ) + { + for (i = 0; i < nC; i++) + { + s = getAbs(lbA_new[i]); + if (s < 1.0) s = 1.0; + d = getAbs(lbA_new[i] - lbA[i]) / s; + if (d > len) len = d; + } + } + /*fprintf( stdFile, "len in homotopyLength = %.3e\n",len ); */ + + /* upper constraint bounds */ + if ( ubA_new != 0 ) + { + for (i = 0; i < nC; i++) + { + s = getAbs(ubA_new[i]); + if (s < 1.0) s = 1.0; + d = getAbs(ubA_new[i] - ubA[i]) / s; + if (d > len) len = d; + } + } + /*fprintf( stdFile, "len in homotopyLength = %.3e\n",len ); */ + + return len; +} + + +/* + * p e r f o r m R a m p i n g + */ +returnValue QProblem::performRamping( ) +{ + int_t nV = getNV( ), nC = getNC( ), bstat, cstat, i, nRamp; + real_t tP, rampValP, tD, rampValD, sca; + + /* compute number of values in ramp */ + nRamp = nV + nC + nC + nV; + + /* ramp inactive variable bounds and active dual bound variables */ + for (i = 0; i < nV; i++) + { + switch (bounds.getType(i)) + { + case ST_EQUALITY: + lb[i] = x[i]; ub[i] = x[i]; /* reestablish exact feasibility */ + continue; + + case ST_BOUNDED: + tP = static_cast((i+rampOffset) % nRamp) / static_cast(nRamp-1); + rampValP = (1.0-tP) * ramp0 + tP * ramp1; + tD = static_cast((nV+nC+nC+i+rampOffset) % nRamp) / static_cast(nRamp-1); + rampValD = (1.0-tD) * ramp0 + tD * ramp1; + bstat = bounds.getStatus(i); + if (bstat != ST_LOWER) { sca = getMax(getAbs(x[i]), 1.0); lb[i] = x[i] - sca * rampValP; } + if (bstat != ST_UPPER) { sca = getMax(getAbs(x[i]), 1.0); ub[i] = x[i] + sca * rampValP; } + if (bstat == ST_LOWER) { lb[i] = x[i]; y[i] = +rampValD; } + if (bstat == ST_UPPER) { ub[i] = x[i]; y[i] = -rampValD; } + if (bstat == ST_INACTIVE) y[i] = 0.0; /* reestablish exact complementarity */ + break; + + case ST_UNBOUNDED: + case ST_DISABLED: + default: + continue; + } + } + + /* ramp inactive constraints and active dual constraint variables */ + for (i = 0; i < nC; i++) + { + switch (constraints.getType(i)) + { + case ST_EQUALITY: + lbA[i] = Ax[i]; ubA[i] = Ax[i]; /* reestablish exact feasibility */ + continue; + + case ST_BOUNDED: + tP = static_cast((nV+i+rampOffset) % nRamp) / static_cast(nRamp-1); + rampValP = (1.0-tP) * ramp0 + tP * ramp1; + tD = static_cast((nV+nC+i+rampOffset) % nRamp) / static_cast(nRamp-1); + rampValD = (1.0-tD) * ramp0 + tD * ramp1; + cstat = constraints.getStatus(i); + if (cstat != ST_LOWER) { sca = getMax(getAbs(Ax[i]), 1.0); lbA[i] = Ax[i] - sca * rampValP; } + if (cstat != ST_UPPER) { sca = getMax(getAbs(Ax[i]), 1.0); ubA[i] = Ax[i] + sca * rampValP; } + if (cstat == ST_LOWER) { lbA[i] = Ax[i]; y[nV+i] = +rampValD; } + if (cstat == ST_UPPER) { ubA[i] = Ax[i]; y[nV+i] = -rampValD; } + if (cstat == ST_INACTIVE) y[nV+i] = 0.0; /* reestablish exact complementarity */ + + Ax_l[i] = Ax[i] - lbA[i]; + Ax_u[i] = ubA[i] - Ax[i]; + break; + + case ST_UNBOUNDED: + case ST_DISABLED: + default: + continue; + } + } + + /* reestablish exact stationarity */ + setupAuxiliaryQPgradient( ); + + /* advance ramp offset to avoid Ramping cycles */ + rampOffset++; + + return SUCCESSFUL_RETURN; +} + + +/* + * u p d a t e F a r B o u n d s + */ +returnValue QProblem::updateFarBounds( real_t curFarBound, int_t nRamp, + const real_t* const lb_new, real_t* const lb_new_far, + const real_t* const ub_new, real_t* const ub_new_far, + const real_t* const lbA_new, real_t* const lbA_new_far, + const real_t* const ubA_new, real_t* const ubA_new_far + ) const +{ + int_t i; + real_t rampVal, t; + int_t nV = getNV( ); + int_t nC = getNC( ); + + returnValue returnvalue = QProblemB::updateFarBounds( curFarBound,nRamp, + lb_new,lb_new_far, ub_new,ub_new_far + ); + if ( returnvalue != SUCCESSFUL_RETURN ) { + return returnvalue; + } + + if ( options.enableRamping == BT_TRUE ) + { + for ( i=0; i((nV+i + rampOffset) % nRamp) / static_cast(nRamp-1); + rampVal = curFarBound * (1.0 + (1.0-t)*ramp0 + t*ramp1); + + if ( lbA_new == 0 ) + lbA_new_far[i] = -rampVal; + else + lbA_new_far[i] = getMax( -rampVal,lbA_new[i] ); + + if ( ubA_new == 0 ) + ubA_new_far[i] = rampVal; + else + ubA_new_far[i] = getMin( rampVal,ubA_new[i] ); + } + } + else + { + for ( i=0; itimes(1, 1.0, x, nV, 0.0, Ax, nC); + for ( j=0; jgetStatus( i ) != bounds.getStatus( i ) ) + ++differenceNumberBounds; + + /* 2) Determine number of constraints that have same status + * in guessed AND current constraints.*/ + int_t differenceNumberConstraints = 0; + + for( i=0; igetStatus( i ) != constraints.getStatus( i ) ) + ++differenceNumberConstraints; + + /* 3) Decide wheter to refactorise or not. */ + if ( 2*(differenceNumberBounds+differenceNumberConstraints) > guessedConstraints->getNAC( )+guessedBounds->getNFX( ) ) + return BT_TRUE; + else + return BT_FALSE; +} + + +/* + * s e t u p Q P d a t a + */ +returnValue QProblem::setupQPdata( SymmetricMatrix *_H, const real_t* const _g, Matrix *_A, + const real_t* const _lb, const real_t* const _ub, + const real_t* const _lbA, const real_t* const _ubA + ) +{ + int_t nC = getNC( ); + +#ifdef __WRITE_DATA_FILES__ + { + int_t i; + const double Infinity = 1e20; + int_t nV = getNV( ); + GlobalOutputFileCounter++; + char buf[256]; + snprintf(buf,256,"QP%d_setupQPdata.dat",GlobalOutputFileCounter); + MyPrintf("+++ Writing output file %s\n", buf); + + FILE* output_file = fopen(buf,"w"); + + fprintf(output_file,"nVar = %d\n", nV); + fprintf(output_file,"nCon = %d\n", nC); + + _H->writeToFile(output_file,"H_"); + for (i=0; iwriteToFile(output_file,"A_"); + for (i=0; i 0 ) && ( _A == 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( nC > 0 ) + { + /* 2) Setup lower/upper constraints' bounds vector. */ + setLBA( _lbA ); + setUBA( _ubA ); + + /* 3) Only load constraint matrix after setting up vectors! */ + setA( _A ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p Q P d a t a + */ +returnValue QProblem::setupQPdata( const real_t* const _H, const real_t* const _g, const real_t* const _A, + const real_t* const _lb, const real_t* const _ub, + const real_t* const _lbA, const real_t* const _ubA + ) +{ + int_t nC = getNC( ); + + /* 1) Load Hessian matrix as well as lower and upper bounds vectors. */ + if ( QProblemB::setupQPdata( _H,_g,_lb,_ub ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( ( nC > 0 ) && ( _A == 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( nC > 0 ) + { + /* 2) Setup lower/upper constraints' bounds vector. */ + setLBA( _lbA ); + setUBA( _ubA ); + + /* 3) Only load constraint matrix after setting up vectors! */ + setA( _A ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p Q P d a t a F r o m F i l e + */ +returnValue QProblem::setupQPdataFromFile( const char* const H_file, const char* const g_file, const char* const A_file, + const char* const lb_file, const char* const ub_file, + const char* const lbA_file, const char* const ubA_file + ) +{ + int_t i; + int_t nV = getNV( ); + int_t nC = getNC( ); + + returnValue returnvalue; + + + /* 1) Load Hessian matrix as well as lower and upper bounds vectors from files. */ + returnvalue = QProblemB::setupQPdataFromFile( H_file,g_file,lb_file,ub_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( returnvalue ); + + if ( ( nC > 0 ) && ( A_file == 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( nC > 0 ) + { + /* 2) Load lower constraints' bounds vector from file. */ + if ( lbA_file != 0 ) + { + returnvalue = readFromFile( lbA, nC, lbA_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( returnvalue ); + } + else + { + /* if no lower constraints' bounds are specified, set them to -infinity */ + for( i=0; idoFreeMemory( ); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * l o a d Q P v e c t o r s F r o m F i l e + */ +returnValue QProblem::loadQPvectorsFromFile( const char* const g_file, const char* const lb_file, const char* const ub_file, + const char* const lbA_file, const char* const ubA_file, + real_t* const g_new, real_t* const lb_new, real_t* const ub_new, + real_t* const lbA_new, real_t* const ubA_new + ) const +{ + int_t nC = getNC( ); + + returnValue returnvalue; + + + /* 1) Load gradient vector as well as lower and upper bounds vectors from files. */ + returnvalue = QProblemB::loadQPvectorsFromFile( g_file,lb_file,ub_file, g_new,lb_new,ub_new ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( returnvalue ); + + if ( nC > 0 ) + { + /* 2) Load lower constraints' bounds vector from file. */ + if ( lbA_file != 0 ) + { + if ( lbA_new != 0 ) + { + returnvalue = readFromFile( lbA_new, nC, lbA_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( returnvalue ); + } + else + { + /* If filename is given, storage must be provided! */ + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + } + + /* 3) Load upper constraints' bounds vector from file. */ + if ( ubA_file != 0 ) + { + if ( ubA_new != 0 ) + { + returnvalue = readFromFile( ubA_new, nC, ubA_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( returnvalue ); + } + else + { + /* If filename is given, storage must be provided! */ + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * p r i n t I t e r a t i o n + */ +returnValue QProblem::printIteration( int_t iter, + int_t BC_idx, SubjectToStatus BC_status, BooleanType BC_isBound, real_t homotopyLength, + BooleanType isFirstCall + ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + /* consistency check */ + if ( iter < 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + int_t i; + int_t nV = getNV(); + int_t nC = getNC(); + int_t nAC = getNAC(); + + real_t stat, bfeas, cfeas, bcmpl, ccmpl, Tmaxomin; + real_t *grad = 0; + real_t *AX = 0; + real_t Tmin, Tmax; + + char myPrintfString[MAX_STRING_LENGTH]; + char info[MAX_STRING_LENGTH]; + const char excStr[] = " ef"; + + switch ( options.printLevel ) + { + case PL_DEBUG_ITER: + grad = new real_t[nV]; + AX = new real_t[nC]; + stat = bfeas = cfeas = bcmpl = ccmpl = Tmaxomin = 0.0; + + /* stationarity */ + for (i = 0; i < nV; i++) grad[i] = g[i] - y[i]; + + switch ( hessianType ) + { + case HST_ZERO: + for( i=0; itimes(1, 1.0, x, nV, 1.0, grad, nV); + break; + } + + A->transTimes(1, -1.0, y+nV, nC, 1.0, grad, nV); + for (i = 0; i < nV; i++) if (getAbs(grad[i]) > stat) stat = getAbs(grad[i]); + + /* feasibility */ + for (i = 0; i < nV; i++) if (lb[i] - x[i] > bfeas) bfeas = lb[i] - x[i]; + for (i = 0; i < nV; i++) if (x[i] - ub[i] > bfeas) bfeas = x[i] - ub[i]; + A->times(1, 1.0, x, nV, 0.0, AX, nC); + for (i = 0; i < nC; i++) if (lbA[i] - AX[i] > cfeas) cfeas = lbA[i] - AX[i]; + for (i = 0; i < nC; i++) if (AX[i] - ubA[i] > cfeas) cfeas = AX[i] - ubA[i]; + + /* complementarity */ + for (i = 0; i < nV; i++) if (y[i] > +EPS && getAbs((lb[i] - x[i])*y[i]) > bcmpl) bcmpl = getAbs((lb[i] - x[i])*y[i]); + for (i = 0; i < nV; i++) if (y[i] < -EPS && getAbs((ub[i] - x[i])*y[i]) > bcmpl) bcmpl = getAbs((ub[i] - x[i])*y[i]); + for (i = 0; i < nC; i++) if (y[nV+i] > +EPS && getAbs((lbA[i]-AX[i])*y[nV+i]) > ccmpl) ccmpl = getAbs((lbA[i]-AX[i])*y[nV+i]); + for (i = 0; i < nC; i++) if (y[nV+i] < -EPS && getAbs((ubA[i]-AX[i])*y[nV+i]) > ccmpl) ccmpl = getAbs((ubA[i]-AX[i])*y[nV+i]); + + Tmin = 1.0e16; Tmax = 0.0; + for (i = 0; i < nAC; i++) + if (getAbs(TT(i,sizeT-i-1)) < Tmin) + Tmin = getAbs(TT(i,sizeT-i-1)); + else if (getAbs(TT(i,sizeT-i-1)) > Tmax) + Tmax = getAbs(TT(i,sizeT-i-1)); + Tmaxomin = Tmax/Tmin; + + if ( (iter % 10 == 0) && ( isFirstCall == BT_TRUE ) ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "\n%5s %4s %4s %4s %4s %9s %9s %9s %9s %9s %9s %9s %9s\n", + "iter", "addB", "remB", "addC", "remC", "hom len", "tau", "stat", + "bfeas", "cfeas", "bcmpl", "ccmpl", "Tmin"); + myPrintf( myPrintfString ); + } + + if ( isFirstCall == BT_TRUE ) + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d ",(int)iter ); + else + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d*",(int)iter ); + myPrintf( myPrintfString ); + + if (tabularOutput.idxAddB >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%4d ",(int)(tabularOutput.idxAddB) ); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + if (tabularOutput.idxRemB >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%4d ",(int)(tabularOutput.idxRemB) ); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + if (tabularOutput.idxAddC >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%4d ",(int)(tabularOutput.idxAddC) ); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + if (tabularOutput.idxRemC >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%4d ",(int)(tabularOutput.idxRemC) ); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + snprintf( myPrintfString,MAX_STRING_LENGTH, "%9.2e %9.2e %9.2e %9.2e %9.2e %9.2e %9.2e %9.2e\n", + homotopyLength, tau, stat, bfeas, cfeas, bcmpl, ccmpl, Tmin); + myPrintf( myPrintfString ); + + delete[] AX; + delete[] grad; + break; + + case PL_TABULAR: + if ( (iter % 10 == 0) && ( isFirstCall == BT_TRUE ) ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "\n%5s %6s %6s %6s %6s %9s %9s\n", + "iter", "addB", "remB", "addC", "remC", "hom len", "tau" ); + myPrintf( myPrintfString ); + } + if ( isFirstCall == BT_TRUE ) + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d ",(int)iter); + else + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d*",(int)iter); + myPrintf( myPrintfString ); + + if (tabularOutput.idxAddB >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d%c ",(int)(tabularOutput.idxAddB), excStr[tabularOutput.excAddB]); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + if (tabularOutput.idxRemB >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d%c ",(int)(tabularOutput.idxRemB), excStr[tabularOutput.excRemB]); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + if (tabularOutput.idxAddC >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d%c ",(int)(tabularOutput.idxAddC), excStr[tabularOutput.excAddC]); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + if (tabularOutput.idxRemC >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d%c ",(int)(tabularOutput.idxRemC), excStr[tabularOutput.excRemC]); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + snprintf( myPrintfString,MAX_STRING_LENGTH, "%9.2e %9.2e\n", homotopyLength, tau); + myPrintf( myPrintfString ); + break; + + case PL_MEDIUM: + /* 1) Print header at first iteration. */ + if ( ( iter == 0 ) && ( isFirstCall == BT_TRUE ) ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH,"\n\n#################### qpOASES -- QP NO. %3.0d #####################\n\n",(int)count ); + myPrintf( myPrintfString ); + + myPrintf( " Iter | StepLength | Info | nFX | nAC \n" ); + myPrintf( " ----------+------------------+------------------+---------+--------- \n" ); + } + + /* 2) Print iteration line. */ + if ( BC_status == ST_UNDEFINED ) + { + if ( hessianType == HST_ZERO ) + snprintf( info,3,"LP" ); + else + snprintf( info,3,"QP" ); + + if ( isFirstCall == BT_TRUE ) + snprintf( myPrintfString,MAX_STRING_LENGTH," %5.1d | %1.6e | %s SOLVED | %4.1d | %4.1d \n", (int)iter,tau,info,(int)getNFX( ),(int)getNAC( ) ); + else + snprintf( myPrintfString,MAX_STRING_LENGTH," %5.1d* | %1.6e | %s SOLVED | %4.1d | %4.1d \n", (int)iter,tau,info,(int)getNFX( ),(int)getNAC( ) ); + myPrintf( myPrintfString ); + } + else + { + if ( BC_status == ST_INACTIVE ) + snprintf( info,5,"REM " ); + else + snprintf( info,5,"ADD " ); + + if ( BC_isBound == BT_TRUE ) + snprintf( &(info[4]),4,"BND" ); + else + snprintf( &(info[4]),4,"CON" ); + + snprintf( myPrintfString,MAX_STRING_LENGTH," %5.1d | %1.6e | %s %4.1d | %4.1d | %4.1d \n", (int)iter,tau,info,(int)BC_idx,(int)getNFX( ),(int)getNAC( ) ); + myPrintf( myPrintfString ); + } + break; + + default: + /* nothing to display */ + break; + } + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + +/* + * d r o p I n f e a s i b l e s + */ +returnValue QProblem::dropInfeasibles( int_t BC_number, SubjectToStatus BC_status, BooleanType BC_isBound, + real_t *xiB, real_t *xiC ) +{ + int_t i; + + int_t nAC = getNAC (); + int_t nFX = getNFX (); + int_t blockingPriority = (BC_isBound) ? options.dropBoundPriority : options.dropIneqConPriority; + int_t y_min_number = -1; + BooleanType y_min_isBound = BC_isBound; + int_t y_min_priority = blockingPriority; + + int_t* AC_idx; + constraints.getActive( )->getNumberArray( &AC_idx ); + + int_t* FX_idx; + bounds.getFixed( )->getNumberArray( &FX_idx ); + + if (options.dropEqConPriority <= y_min_priority) + { + // look for an equality constraint we can drop according to priorities + for ( i = 0; i < nAC; ++i ) + if ( (constraints.getType (i) == ST_EQUALITY) + && (getAbs (xiC[i]) > options.epsDen) ) + { + y_min_number = AC_idx[i]; + y_min_isBound = BT_FALSE; + y_min_priority = options.dropEqConPriority; + break; + } + } + + if (options.dropIneqConPriority <= y_min_priority) + { + // look for an inequality constraint we can drop according to priorities + for ( i = 0; i < nAC; ++i ) + if ( (constraints.getType (i) == ST_BOUNDED) + && (getAbs (xiC[i]) > options.epsDen) ) + { + y_min_number = AC_idx[i]; + y_min_isBound = BT_FALSE; + y_min_priority = options.dropIneqConPriority; + break; + } + } + + if (options.dropBoundPriority <= y_min_priority) + { + // look for a simple bound we can drop according to priorities + for ( i = 0; i < nFX; ++i ) + if (getAbs (xiB[i]) > options.epsDen) + { + y_min_number = FX_idx[i]; + y_min_isBound = BT_TRUE; + y_min_priority = options.dropBoundPriority; + break; + } + } + + if (y_min_number >= 0) { + + // drop active equality or active bound we have found + if (y_min_isBound) { + SubjectToStatus status_ = bounds.getStatus (y_min_number); + removeBound (y_min_number, BT_TRUE, BT_FALSE, BT_FALSE); + bounds.setStatus (y_min_number, (status_ == ST_LOWER) ? ST_INFEASIBLE_LOWER : ST_INFEASIBLE_UPPER); + // TODO: fix duals y[] + /* fprintf (stdFile, "Dropping bounds %d for %s %d\n", y_min_number, BC_isBound?"bound":"constraint", BC_number); */ + } else { + SubjectToStatus status_ = constraints.getStatus (y_min_number); + removeConstraint (y_min_number, BT_TRUE, BT_FALSE, BT_FALSE); + constraints.setStatus (y_min_number, (status_ == ST_LOWER) ? ST_INFEASIBLE_LOWER : ST_INFEASIBLE_UPPER); + // TODO: fix duals y[] + /* fprintf (stdFile, "Dropping constraint %d for %s %d\n", y_min_number, BC_isBound?"bound":"constraint", BC_number); */ + } + + // ... now return, add the blocking constraint, and continue solving QP with dropped bound/constraint + return SUCCESSFUL_RETURN; + + } else { + + // nothing found, then drop the blocking (still inactive) constraint + if (BC_isBound) + bounds.setStatus (BC_number, (BC_status == ST_LOWER) ? ST_INFEASIBLE_LOWER : ST_INFEASIBLE_UPPER); + else + constraints.setStatus (BC_number, (BC_status == ST_LOWER) ? ST_INFEASIBLE_LOWER : ST_INFEASIBLE_UPPER); + + /* fprintf (stdFile, "Dropping %s %d itself\n", BC_isBound?"bound":"constraint", BC_number); */ + + // ... now return, and continue solving QP with dropped bound/constraint + return RET_ENSURELI_DROPPED; + } +} + + + +/* + * w r i t e Q p D a t a I n t o M a t F i l e + */ +returnValue QProblem::writeQpDataIntoMatFile( const char* const filename + ) const +{ + #ifndef __SUPPRESSANYOUTPUT__ + + FILE* matFile; + matFile = fopen( filename,"w+" ); + + if ( matFile == 0 ) + return RET_UNABLE_TO_OPEN_FILE; + + int_t nV = getNV(); + int_t nC = getNC(); + + real_t* Hfull = H->full(); + writeIntoMatFile( matFile, Hfull, nV,nV, "H" ); + delete[] Hfull; + + writeIntoMatFile( matFile, g, nV,1, "g" ); + + real_t* Afull = A->full(); + writeIntoMatFile( matFile, Afull, nC,nV, "A" ); + delete[] Afull; + + writeIntoMatFile( matFile, lb, nV,1, "lb" ); + writeIntoMatFile( matFile, ub, nV,1, "ub" ); + writeIntoMatFile( matFile, lbA, nC,1, "lbA" ); + writeIntoMatFile( matFile, ubA, nC,1, "ubA" ); + + fclose( matFile ); + + return SUCCESSFUL_RETURN; + + #else /* __SUPPRESSANYOUTPUT__ */ + + return RET_NOT_YET_IMPLEMENTED; + + #endif /* __SUPPRESSANYOUTPUT__ */ +} + + +/* + * w r i t e Q p W o r k s p a c e I n t o M a t F i l e + */ +returnValue QProblem::writeQpWorkspaceIntoMatFile( const char* const filename + ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + FILE* matFile; + matFile = fopen( filename,"w+" ); + + if ( matFile == 0 ) + return RET_UNABLE_TO_OPEN_FILE; + + int_t nV = getNV(); + int_t nC = getNC(); + int_t nFR = getNFR(); + int_t nFX = getNFX(); + int_t nAC = getNAC(); + int_t nIAC = getNIAC(); + + + writeIntoMatFile( matFile, T, sizeT,sizeT, "T" ); + writeIntoMatFile( matFile, Q, nV,nV, "Q" ); + + writeIntoMatFile( matFile, Ax, nC,1, "Ax" ); + writeIntoMatFile( matFile, Ax_l, nC,1, "Ax_l" ); + writeIntoMatFile( matFile, Ax_u, nC,1, "Ax_u" ); + + + int_t *FR_idx, *FX_idx, *AC_idx, *IAC_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + constraints.getInactive( )->getNumberArray( &IAC_idx ); + + writeIntoMatFile( matFile, FR_idx, nFR, 1, "FR_idx" ); + writeIntoMatFile( matFile, FX_idx, nFX, 1, "FX_idx" ); + writeIntoMatFile( matFile, AC_idx, nAC, 1, "AC_idx" ); + writeIntoMatFile( matFile, IAC_idx, nIAC,1, "IAC_idx" ); + + fclose( matFile ); + + return SUCCESSFUL_RETURN; + + #else /* __SUPPRESSANYOUTPUT__ */ + + return RET_NOT_YET_IMPLEMENTED; + + #endif /* __SUPPRESSANYOUTPUT__ */ +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/QProblemB.cpp b/locomotion/src/third_party/qpOASES/src/QProblemB.cpp new file mode 100644 index 0000000..52620e0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/QProblemB.cpp @@ -0,0 +1,3859 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/QProblemB.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the QProblemB class which is able to use the newly + * developed online active set strategy for parametric quadratic programming. + */ + + +#include +#include + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * Q P r o b l e m B + */ +QProblemB::QProblemB( ) +{ + /* print copyright notice */ + if (options.printLevel != PL_NONE) + printCopyrightNotice( ); + + /* reset global message handler */ + getGlobalMessageHandler( )->reset( ); + + freeHessian = BT_FALSE; + H = 0; + + g = 0; + lb = 0; + ub = 0; + + R = 0; + haveCholesky = BT_FALSE; + + x = 0; + y = 0; + + tau = 0.0; + + hessianType = HST_UNKNOWN; + regVal = 0.0; + + infeasible = BT_FALSE; + unbounded = BT_FALSE; + + status = QPS_NOTINITIALISED; + + count = 0; + + ramp0 = options.initialRamping; + ramp1 = options.finalRamping; + rampOffset = 0; + + delta_xFR_TMP = 0; + + setPrintLevel( options.printLevel ); +} + + +/* + * Q P r o b l e m B + */ +QProblemB::QProblemB( int_t _nV, HessianType _hessianType, BooleanType allocDenseMats ) +{ + int_t i; + + /* print copyright notice */ + if (options.printLevel != PL_NONE) + printCopyrightNotice( ); + + /* consistency check */ + if ( _nV <= 0 ) + { + _nV = 1; + THROWERROR( RET_INVALID_ARGUMENTS ); + } + + /* reset global message handler */ + getGlobalMessageHandler( )->reset( ); + + freeHessian = BT_FALSE; + H = 0; + + g = new real_t[_nV]; + for( i=0; i<_nV; ++i ) g[i] = 0.0; + + lb = new real_t[_nV]; + for( i=0; i<_nV; ++i ) lb[i] = 0.0; + + ub = new real_t[_nV]; + for( i=0; i<_nV; ++i ) ub[i] = 0.0; + + bounds.init( _nV ); + + if ( allocDenseMats == BT_TRUE ) + { + R = new real_t[_nV*_nV]; + for( i=0; i<_nV*_nV; ++i ) R[i] = 0.0; + } + else R = 0; + haveCholesky = BT_FALSE; + + x = new real_t[_nV]; + for( i=0; i<_nV; ++i ) x[i] = 0.0; + + y = new real_t[_nV]; + for( i=0; i<_nV; ++i ) y[i] = 0.0; + + tau = 0.0; + + hessianType = _hessianType; + regVal = 0.0; + + infeasible = BT_FALSE; + unbounded = BT_FALSE; + + status = QPS_NOTINITIALISED; + + count = 0; + + ramp0 = options.initialRamping; + ramp1 = options.finalRamping; + rampOffset = 0; + + delta_xFR_TMP = new real_t[_nV]; + + setPrintLevel( options.printLevel ); + + flipper.init( (uint_t)_nV ); +} + + +/* + * Q P r o b l e m B + */ +QProblemB::QProblemB( const QProblemB& rhs ) +{ + freeHessian = BT_FALSE; + H = 0; + + copy( rhs ); +} + + +/* + * ~ Q P r o b l e m B + */ +QProblemB::~QProblemB( ) +{ + clear( ); + + /* reset global message handler */ + getGlobalMessageHandler( )->reset( ); +} + + +/* + * o p e r a t o r = + */ +QProblemB& QProblemB::operator=( const QProblemB& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + copy( rhs ); + } + + return *this; +} + + +/* + * r e s e t + */ +returnValue QProblemB::reset( ) +{ + int_t i; + int_t nV = getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + /* 1) Reset bounds. */ + bounds.init( nV ); + + /* 2) Reset Cholesky decomposition. */ + if ( R!=0 ) + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + } + + /* exclude this possibility in order to avoid inconsistencies */ + if ( ( xOpt == 0 ) && ( yOpt != 0 ) && ( guessedBounds != 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( ( _R != 0 ) && ( ( xOpt != 0 ) || ( yOpt != 0 ) || ( guessedBounds != 0 ) ) ) + return THROWERROR( RET_NO_CHOLESKY_WITH_INITIAL_GUESS ); + + /* 2) Setup QP data. */ + if ( setupQPdata( _H,_g,_lb,_ub ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + /* 3) Call to main initialisation routine. */ + return solveInitialQP( xOpt,yOpt,guessedBounds,_R, nWSR,cputime ); +} + + +/* + * i n i t + */ +returnValue QProblemB::init( const real_t* const _H, const real_t* const _g, + const real_t* const _lb, const real_t* const _ub, + int_t& nWSR, real_t* const cputime, + const real_t* const xOpt, const real_t* const yOpt, + const Bounds* const guessedBounds, + const real_t* const _R + ) +{ + int_t i; + int_t nV = getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + /* 1) Consistency checks. */ + if ( isInitialised( ) == BT_TRUE ) + { + THROWWARNING( RET_QP_ALREADY_INITIALISED ); + reset( ); + } + + if ( guessedBounds != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + } + + /* exclude this possibility in order to avoid inconsistencies */ + if ( ( xOpt == 0 ) && ( yOpt != 0 ) && ( guessedBounds != 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( ( _R != 0 ) && ( ( xOpt != 0 ) || ( yOpt != 0 ) || ( guessedBounds != 0 ) ) ) + return THROWERROR( RET_NO_CHOLESKY_WITH_INITIAL_GUESS ); + + /* 2) Setup QP data. */ + if ( setupQPdata( _H,_g,_lb,_ub ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + /* 3) Call to main initialisation routine. */ + return solveInitialQP( xOpt,yOpt,guessedBounds,_R, nWSR,cputime ); +} + + +/* + * i n i t + */ +returnValue QProblemB::init( const char* const H_file, const char* const g_file, + const char* const lb_file, const char* const ub_file, + int_t& nWSR, real_t* const cputime, + const real_t* const xOpt, const real_t* const yOpt, + const Bounds* const guessedBounds, + const char* const R_file + ) +{ + int_t i; + int_t nV = getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + /* 1) Consistency checks. */ + if ( isInitialised( ) == BT_TRUE ) + { + THROWWARNING( RET_QP_ALREADY_INITIALISED ); + reset( ); + } + + if ( guessedBounds != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + } + + /* exclude this possibility in order to avoid inconsistencies */ + if ( ( xOpt == 0 ) && ( yOpt != 0 ) && ( guessedBounds != 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( ( R_file != 0 ) && ( ( xOpt != 0 ) || ( yOpt != 0 ) || ( guessedBounds != 0 ) ) ) + return THROWERROR( RET_NO_CHOLESKY_WITH_INITIAL_GUESS ); + + /* 2) Setup QP data from files. */ + if ( setupQPdataFromFile( H_file,g_file,lb_file,ub_file ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + + if ( R_file == 0 ) + { + /* 3) Call to main initialisation routine. */ + return solveInitialQP( xOpt,yOpt,guessedBounds,0, nWSR,cputime ); + } + else + { + /* Also read Cholesky factor from file and store it directly into R [thus... */ + returnValue returnvalue = readFromFile( R, nV,nV, R_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWWARNING( returnvalue ); + + /* 3) Call to main initialisation routine. ...passing R here!] */ + return solveInitialQP( xOpt,yOpt,guessedBounds,R, nWSR,cputime ); + } +} + + + +/* + * h o t s t a r t + */ +returnValue QProblemB::hotstart( const real_t* const g_new, + const real_t* const lb_new, const real_t* const ub_new, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds + ) +{ + int_t i, nActiveFar; + int_t nV = getNV (); + real_t starttime = 0.0; + real_t auxTime = 0.0; + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + + /* Possibly update working set according to guess for working set of bounds. */ + if ( guessedBounds != 0 ) + { + if ( cputime != 0 ) + starttime = getCPUtime( ); + + if ( setupAuxiliaryQP( guessedBounds ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + + status = QPS_AUXILIARYQPSOLVED; + + /* Allow only remaining CPU time for usual hotstart. */ + if ( cputime != 0 ) + { + auxTime = getCPUtime( ) - starttime; + *cputime -= auxTime; + } + } + + + returnValue returnvalue = SUCCESSFUL_RETURN; + + /* Simple check for consistency of bounds */ + if ( areBoundsConsistent( lb_new,ub_new ) != SUCCESSFUL_RETURN ) + return setInfeasibilityFlag(returnvalue,BT_TRUE); + + ++count; + + + int_t nWSR_max = nWSR; + int_t nWSR_performed = 0; + + real_t cputime_remaining = INFTY; + real_t cputime_needed = 0.0; + + real_t farbound = options.initialFarBounds; + + if ( haveCholesky == BT_FALSE ) + { + returnvalue = setupInitialCholesky( ); + if (returnvalue != SUCCESSFUL_RETURN) + return THROWERROR(returnvalue); + } + + BooleanType isFirstCall = BT_TRUE; + + if ( options.enableFarBounds == BT_FALSE ) + { + /* Automatically call standard solveQP if regularisation is not active. */ + returnvalue = solveRegularisedQP( g_new,lb_new,ub_new, + nWSR,cputime,0, + isFirstCall + ); + } + else + { + real_t *ub_new_far = new real_t[nV]; + real_t *lb_new_far = new real_t[nV]; + + /* possibly extend initial far bounds to largest bound/constraint data */ + if (ub_new) + for (i = 0; i < nV; i++) + if ((ub_new[i] < INFTY) && (ub_new[i] > farbound)) farbound = ub_new[i]; + if (lb_new) + for (i = 0; i < nV; i++) + if ((lb_new[i] > -INFTY) && (lb_new[i] < -farbound)) farbound = -lb_new[i]; + + updateFarBounds( farbound,nV, + lb_new,lb_new_far, ub_new,ub_new_far + ); + + for ( ;; ) + { + nWSR = nWSR_max; + if ( cputime != 0 ) + cputime_remaining = *cputime - cputime_needed; + + /* Automatically call standard solveQP if regularisation is not active. */ + returnvalue = solveRegularisedQP( g_new,lb_new_far,ub_new_far, + nWSR,&cputime_remaining,nWSR_performed, + isFirstCall + ); + + nWSR_performed = nWSR; + cputime_needed += cputime_remaining; + isFirstCall = BT_FALSE; + + /* Check for active far-bounds and move them away */ + nActiveFar = 0; + farbound *= options.growFarBounds; + + if ( infeasible == BT_TRUE ) + { + if ( farbound >= INFTY ) + { + returnvalue = RET_HOTSTART_STOPPED_INFEASIBILITY; + goto farewell; + } + + updateFarBounds( farbound,nV, + lb_new,lb_new_far, ub_new,ub_new_far + ); + } + else if ( status == QPS_SOLVED ) + { + real_t tol = farbound/options.growFarBounds * options.boundTolerance; + nActiveFar = 0; + for ( i=0; i lb_new[i] ) ) && ( getAbs ( lb_new_far[i] - x[i] ) < tol ) ) + ++nActiveFar; + if ( ( ( ub_new == 0 ) || ( ub_new_far[i] < ub_new[i] ) ) && ( getAbs ( ub_new_far[i] - x[i] ) < tol ) ) + ++nActiveFar; + } + + if ( nActiveFar == 0 ) + break; + + status = QPS_HOMOTOPYQPSOLVED; + + if ( farbound >= INFTY ) + { + unbounded = BT_TRUE; + returnvalue = RET_HOTSTART_STOPPED_UNBOUNDEDNESS; + goto farewell; + } + + updateFarBounds( farbound,nV, + lb_new,lb_new_far, ub_new,ub_new_far + ); + } + else + { + /* some other error when solving QP */ + break; + } + + /* advance ramp offset to avoid Ramping cycles */ + rampOffset++; + } + + farewell: + /* add time to setup auxiliary QP */ + if ( cputime != 0 ) + *cputime = cputime_needed + auxTime; + delete[] lb_new_far; delete[] ub_new_far; + } + + return ( returnvalue != SUCCESSFUL_RETURN ) ? THROWERROR( returnvalue ) : returnvalue; +} + + +/* + * h o t s t a r t + */ +returnValue QProblemB::hotstart( const char* const g_file, + const char* const lb_file, const char* const ub_file, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds + ) +{ + int_t nV = getNV( ); + + if ( nV == 0 ) + return THROWERROR( RET_QPOBJECT_NOT_SETUP ); + + /* consistency check */ + if ( g_file == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + + /* 1) Allocate memory (if bounds exist). */ + real_t* g_new = new real_t[nV]; + real_t* lb_new = ( lb_file != 0 ) ? new real_t[nV] : 0; + real_t* ub_new = ( ub_file != 0 ) ? new real_t[nV] : 0; + + + /* 2) Load new QP vectors from file. */ + returnValue returnvalue; + returnvalue = loadQPvectorsFromFile( g_file,lb_file,ub_file, + g_new,lb_new,ub_new + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + if ( ub_file != 0 ) + delete[] ub_new; + if ( lb_file != 0 ) + delete[] lb_new; + delete[] g_new; + + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + + /* 3) Actually perform hotstart. */ + returnvalue = hotstart( g_new,lb_new,ub_new, + nWSR,cputime, + guessedBounds + ); + + + /* 4) Free memory. */ + if ( ub_file != 0 ) + delete[] ub_new; + if ( lb_file != 0 ) + delete[] lb_new; + delete[] g_new; + + return returnvalue; +} + + +/* + * g e t W o r k i n g S e t + */ +returnValue QProblemB::getWorkingSet( real_t* workingSet ) +{ + return getWorkingSetBounds( workingSet ); +} + + +/* + * g e t W o r k i n g S e t B o u n d s + */ +returnValue QProblemB::getWorkingSetBounds( real_t* workingSetB ) +{ + int_t i; + int_t nV = this->getNV(); + + if ( workingSetB == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + for ( i=0; itimes(1, 1.0, _x, nV, 0.0, Hx, nV); + for( i=0; isetErrorVisibilityStatus( VS_HIDDEN ); + getGlobalMessageHandler( )->setWarningVisibilityStatus( VS_HIDDEN ); + getGlobalMessageHandler( )->setInfoVisibilityStatus( VS_HIDDEN ); + break; + + case PL_TABULAR: + case PL_LOW: + getGlobalMessageHandler( )->setErrorVisibilityStatus( VS_VISIBLE ); + getGlobalMessageHandler( )->setWarningVisibilityStatus( VS_HIDDEN ); + getGlobalMessageHandler( )->setInfoVisibilityStatus( VS_HIDDEN ); + break; + + case PL_DEBUG_ITER: + case PL_MEDIUM: + getGlobalMessageHandler( )->setErrorVisibilityStatus( VS_VISIBLE ); + getGlobalMessageHandler( )->setWarningVisibilityStatus( VS_VISIBLE ); + getGlobalMessageHandler( )->setInfoVisibilityStatus( VS_HIDDEN ); + break; + + default: /* PL_HIGH */ + getGlobalMessageHandler( )->setErrorVisibilityStatus( VS_VISIBLE ); + getGlobalMessageHandler( )->setWarningVisibilityStatus( VS_VISIBLE ); + getGlobalMessageHandler( )->setInfoVisibilityStatus( VS_VISIBLE ); + break; + } + + return SUCCESSFUL_RETURN; +} + + +/* + * p r i n t P r o p e r t i e s + */ +returnValue QProblemB::printProperties( ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + /* Do not print properties if print level is set to none! */ + if ( options.printLevel == PL_NONE ) + return SUCCESSFUL_RETURN; + + char myPrintfString[MAX_STRING_LENGTH]; + + myPrintf( "\n################# qpOASES -- QP PROPERTIES #################\n" ); + myPrintf( "\n" ); + + /* 1) Variables properties. */ + snprintf( myPrintfString,MAX_STRING_LENGTH, "Number of Variables: %4.1d\n",(int)getNV( ) ); + myPrintf( myPrintfString ); + + if ( bounds.hasNoLower( ) == BT_TRUE ) + myPrintf( "Variables are not bounded from below.\n" ); + else + myPrintf( "Variables are bounded from below.\n" ); + + if ( bounds.hasNoUpper( ) == BT_TRUE ) + myPrintf( "Variables are not bounded from above.\n" ); + else + myPrintf( "Variables are bounded from above.\n" ); + + myPrintf( "\n" ); + + + /* 2) Further properties. */ + switch ( hessianType ) + { + case HST_ZERO: + myPrintf( "Hessian is zero matrix (i.e. actually an LP is solved).\n" ); + break; + + case HST_IDENTITY: + myPrintf( "Hessian is identity matrix.\n" ); + break; + + case HST_POSDEF: + myPrintf( "Hessian matrix is (strictly) positive definite.\n" ); + break; + + case HST_POSDEF_NULLSPACE: + myPrintf( "Hessian matrix is positive definite on null space of active constraints.\n" ); + break; + + case HST_SEMIDEF: + myPrintf( "Hessian matrix is positive semi-definite.\n" ); + break; + + case HST_INDEF: + myPrintf( "Hessian matrix is indefinite.\n" ); + break; + + default: + myPrintf( "Hessian matrix has unknown type.\n" ); + break; + } + + if ( infeasible == BT_TRUE ) + myPrintf( "QP was found to be infeasible.\n" ); + else + myPrintf( "QP seems to be feasible.\n" ); + + if ( unbounded == BT_TRUE ) + myPrintf( "QP was found to be unbounded from below.\n" ); + else + myPrintf( "QP seems to be bounded from below.\n" ); + + myPrintf( "\n" ); + + + /* 3) QP object properties. */ + switch ( status ) + { + case QPS_NOTINITIALISED: + myPrintf( "Status of QP object: freshly instantiated or reset.\n" ); + break; + + case QPS_PREPARINGAUXILIARYQP: + myPrintf( "Status of QP object: an auxiliary QP is currently setup.\n" ); + break; + + case QPS_AUXILIARYQPSOLVED: + myPrintf( "Status of QP object: an auxilary QP was solved.\n" ); + break; + + case QPS_PERFORMINGHOMOTOPY: + myPrintf( "Status of QP object: a homotopy step is performed.\n" ); + break; + + case QPS_HOMOTOPYQPSOLVED: + myPrintf( "Status of QP object: an intermediate QP along the homotopy path was solved.\n" ); + break; + + case QPS_SOLVED: + myPrintf( "Status of QP object: solution of the actual QP was found.\n" ); + break; + } + + switch ( options.printLevel ) + { + case PL_DEBUG_ITER: + myPrintf( "Print level of QP object is set to display a tabular output for debugging.\n" ); + break; + + case PL_TABULAR: + myPrintf( "Print level of QP object is set to display a tabular output.\n" ); + break; + + case PL_LOW: + myPrintf( "Print level of QP object is low, i.e. only error are printed.\n" ); + break; + + case PL_MEDIUM: + myPrintf( "Print level of QP object is medium, i.e. error and warnings are printed.\n" ); + break; + + case PL_HIGH: + myPrintf( "Print level of QP object is high, i.e. all available output is printed.\n" ); + break; + + default: + break; + } + + myPrintf( "\n" ); + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + +returnValue QProblemB::printOptions( ) const +{ + return options.print( ); +} + + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * c l e a r + */ +returnValue QProblemB::clear( ) +{ + if ( ( freeHessian == BT_TRUE ) && ( H != 0 ) ) + { + delete H; + H = 0; + } + + if ( g != 0 ) + { + delete[] g; + g = 0; + } + + if ( lb != 0 ) + { + delete[] lb; + lb = 0; + } + + if ( ub != 0 ) + { + delete[] ub; + ub = 0; + } + + if ( R != 0 ) + { + delete[] R; + R = 0; + } + + if ( x != 0 ) + { + delete[] x; + x = 0; + } + + if ( y != 0 ) + { + delete[] y; + y = 0; + } + + if ( delta_xFR_TMP != 0 ) + { + delete[] delta_xFR_TMP; + delta_xFR_TMP = 0; + } + + return SUCCESSFUL_RETURN; +} + + +/* + * c o p y + */ +returnValue QProblemB::copy( const QProblemB& rhs + ) +{ + uint_t _nV = (uint_t)rhs.getNV( ); + + bounds = rhs.bounds; + + freeHessian = rhs.freeHessian; + + if ( freeHessian == BT_TRUE ) + H = (SymmetricMatrix *)(rhs.H->duplicateSym()); + else + H = rhs.H; + + if ( rhs.g != 0 ) + { + g = new real_t[_nV]; + setG( rhs.g ); + } + else + g = 0; + + if ( rhs.lb != 0 ) + { + lb = new real_t[_nV]; + setLB( rhs.lb ); + } + else + lb = 0; + + if ( rhs.ub != 0 ) + { + ub = new real_t[_nV]; + setUB( rhs.ub ); + } + else + ub = 0; + + if ( rhs.R != 0 ) + { + R = new real_t[_nV*_nV]; + memcpy( R,rhs.R,_nV*_nV*sizeof(real_t) ); + } + else + R = 0; + + haveCholesky = rhs.haveCholesky; + + if ( rhs.x != 0 ) + { + x = new real_t[_nV]; + memcpy( x,rhs.x,_nV*sizeof(real_t) ); + } + else + x = 0; + + if ( rhs.y != 0 ) + { + y = new real_t[_nV]; + memcpy( y,rhs.y,_nV*sizeof(real_t) ); + } + else + y = 0; + + tau = rhs.tau; + + hessianType = rhs.hessianType; + regVal = rhs.regVal; + + infeasible = rhs.infeasible; + unbounded = rhs.unbounded; + + status = rhs.status; + + count = rhs.count; + + ramp0 = rhs.ramp0; + ramp1 = rhs.ramp1; + // AW: Following line seemed to be missing + rampOffset = rhs.rampOffset; + + delta_xFR_TMP = new real_t[_nV]; /* nFR */ + + options = rhs.options; + setPrintLevel( options.printLevel ); + + flipper = rhs.flipper; + + return SUCCESSFUL_RETURN; +} + + +/* + * d e t e r m i n e H e s s i a n T y p e + */ +returnValue QProblemB::determineHessianType( ) +{ + int_t i; + int_t nV = getNV( ); + real_t curDiag; + + /* if Hessian type has been set by user, do NOT change it! */ + switch ( hessianType ) + { + case HST_ZERO: + /* ensure regularisation as default options do not always solve LPs */ + if ( options.enableRegularisation == BT_FALSE ) + { + options.enableRegularisation = BT_TRUE; + options.numRegularisationSteps = 1; + } + return SUCCESSFUL_RETURN; + + case HST_IDENTITY: + return SUCCESSFUL_RETURN; + + case HST_POSDEF: + case HST_POSDEF_NULLSPACE: + case HST_SEMIDEF: + case HST_INDEF: + /* if H == 0, continue to reset hessianType to HST_ZERO + * to avoid segmentation faults! */ + if ( H != 0 ) + return SUCCESSFUL_RETURN; + + default: + /* HST_UNKNOWN, continue */ + break; + } + + /* if Hessian has not been allocated, assume it to be all zeros! */ + if ( H == 0 ) + { + hessianType = HST_ZERO; + THROWINFO( RET_ZERO_HESSIAN_ASSUMED ); + + /* ensure regularisation as default options do not always solve LPs */ + if ( options.enableRegularisation == BT_FALSE ) + { + options.enableRegularisation = BT_TRUE; + options.numRegularisationSteps = 1; + } + + return SUCCESSFUL_RETURN; + } + + /* 1) If Hessian has outer-diagonal elements, + * Hessian is assumed to be positive definite. */ + hessianType = HST_POSDEF; + if ( H->isDiag() == BT_FALSE ) + return SUCCESSFUL_RETURN; + + /* 2) Otherwise it is diagonal and test for identity or zero matrix is performed. */ + BooleanType isIdentity = BT_TRUE; + BooleanType isZero = BT_TRUE; + + for ( i=0; idiag(i); + if ( curDiag >= INFTY ) + return RET_DIAGONAL_NOT_INITIALISED; + + if ( curDiag < -ZERO ) + { + hessianType = HST_INDEF; + if ( options.enableFlippingBounds == BT_FALSE ) + return THROWERROR( RET_HESSIAN_INDEFINITE ); + else + return SUCCESSFUL_RETURN; + } + + if ( getAbs( curDiag - 1.0 ) > EPS ) + isIdentity = BT_FALSE; + + if ( getAbs( curDiag ) > EPS ) + isZero = BT_FALSE; + } + + if ( isIdentity == BT_TRUE ) + hessianType = HST_IDENTITY; + + if ( isZero == BT_TRUE ) + { + hessianType = HST_ZERO; + + /* ensure regularisation as default options do not always solve LPs */ + if ( options.enableRegularisation == BT_FALSE ) + { + options.enableRegularisation = BT_TRUE; + options.numRegularisationSteps = 1; + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p S u b j e c t T o T y p e + */ +returnValue QProblemB::setupSubjectToType( ) +{ + return setupSubjectToType( lb,ub ); +} + + +/* + * s e t u p S u b j e c t T o T y p e + */ +returnValue QProblemB::setupSubjectToType( const real_t* const lb_new, const real_t* const ub_new ) +{ + int_t i; + int_t nV = getNV( ); + + + /* 1) Check if lower bounds are present. */ + bounds.setNoLower( BT_TRUE ); + if ( lb_new != 0 ) + { + for( i=0; i -INFTY ) + { + bounds.setNoLower( BT_FALSE ); + break; + } + } + } + + /* 2) Check if upper bounds are present. */ + bounds.setNoUpper( BT_TRUE ); + if ( ub_new != 0 ) + { + for( i=0; i INFTY-options.boundTolerance ) + && (options.enableFarBounds == BT_FALSE)) + { + bounds.setType( i,ST_UNBOUNDED ); + } + else + { + if (options.enableEqualities + && lb[i] > ub[i] - options.boundTolerance + && lb_new[i] > ub_new[i] - options.boundTolerance) + bounds.setType( i,ST_EQUALITY ); + else + bounds.setType( i,ST_BOUNDED ); + } + } + } + else + { + if ( ( lb_new == 0 ) && ( ub_new == 0 ) ) + { + for( i=0; i 0 ) + { + int_t* FR_idx; + bounds.getFree( )->getNumberArray( &FR_idx ); + + /* get H */ + for ( j=0; j < nFR; ++j ) + H->getCol (FR_idx[j], bounds.getFree (), 1.0, &(R[j*nV]) ); + + /* R'*R = H */ + la_int_t info = 0; + la_uint_t _nFR = (la_uint_t)nFR, _nV = (la_uint_t)nV; + + POTRF( "U", &_nFR, R, &_nV, &info ); + + /* <0 = invalid call, =0 ok, >0 not spd */ + if (info > 0) { + if ( R[0] < 0.0 ) + { + /* Cholesky decomposition has tunneled a negative + * diagonal element. */ + options.epsRegularisation = getMin( -R[0]+options.epsRegularisation,getSqrt(getAbs(options.epsRegularisation)) ); + } + + hessianType = HST_SEMIDEF; + return RET_HESSIAN_NOT_SPD; + } + + /* zero first subdiagonal to make givens updates work */ + for ( i=0; isetupBound( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + else + #endif + { + if ( auxiliaryBounds->setupBound( i,guessedBounds->getStatus( i ) ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + } + } + else /* No initial working set specified. */ + { + if ( ( xOpt != 0 ) && ( yOpt == 0 ) ) + { + /* Obtain initial working set by "clipping". */ + for( i=0; isetupBound( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + continue; + } + + if ( xOpt[i] >= ub[i] - options.boundTolerance ) + { + if ( auxiliaryBounds->setupBound( i,ST_UPPER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + continue; + } + + /* Moreover, add all implictly fixed variables if specified. */ + #ifdef __ALWAYS_INITIALISE_WITH_ALL_EQUALITIES__ + if ( bounds.getType( i ) == ST_EQUALITY ) + { + if ( auxiliaryBounds->setupBound( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + else + #endif + { + if ( auxiliaryBounds->setupBound( i,ST_INACTIVE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + } + } + + if ( yOpt != 0 ) + { + /* Obtain initial working set in accordance to sign of dual solution vector. */ + for( i=0; i EPS ) + { + if ( auxiliaryBounds->setupBound( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + continue; + } + + if ( yOpt[i] < -EPS ) + { + if ( auxiliaryBounds->setupBound( i,ST_UPPER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + continue; + } + + /* Moreover, add all implictly fixed variables if specified. */ + #ifdef __ALWAYS_INITIALISE_WITH_ALL_EQUALITIES__ + if ( bounds.getType( i ) == ST_EQUALITY ) + { + if ( auxiliaryBounds->setupBound( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + else + #endif + { + if ( auxiliaryBounds->setupBound( i,ST_INACTIVE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + } + } + } + + /* If xOpt and yOpt are null pointer and no initial working is specified, + * start with empty working set (or implicitly fixed bounds only) + * for auxiliary QP. */ + if ( ( xOpt == 0 ) && ( yOpt == 0 ) ) + { + for( i=0; isetupBound( i,ST_INACTIVE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + break; + + /* Only add all implictly fixed variables if specified. */ + #ifdef __ALWAYS_INITIALISE_WITH_ALL_EQUALITIES__ + case ST_EQUALITY: + if ( auxiliaryBounds->setupBound( i,ST_LOWER ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + break; + #endif + + default: + if ( auxiliaryBounds->setupBound( i,options.initialStatusBounds ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED ); + break; + } + } + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * b a c k s o l v e R + */ +returnValue QProblemB::backsolveR( const real_t* const b, BooleanType transposed, + real_t* const a + ) const +{ + /* Call standard backsolve procedure (i.e. removingBound == BT_FALSE). */ + return backsolveR( b,transposed,BT_FALSE,a ); +} + + +/* + * b a c k s o l v e R + */ +returnValue QProblemB::backsolveR( const real_t* const b, BooleanType transposed, + BooleanType removingBound, + real_t* const a + ) const +{ + int_t i, j; + int_t nV = getNV( ); + int_t nR = getNZ( ); + + real_t sum; + + /* if backsolve is called while removing a bound, reduce nZ by one. */ + if ( removingBound == BT_TRUE ) + --nR; + + /* nothing to do */ + if ( nR <= 0 ) + return SUCCESSFUL_RETURN; + + + /* Solve Ra = b, where R might be transposed. */ + if ( transposed == BT_FALSE ) + { + /* solve Ra = b */ + for( i=(nR-1); i>=0; --i ) + { + sum = b[i]; + for( j=(i+1); j= ZERO*getAbs( sum ) ) + a[i] = sum / RR(i,i); + else + return THROWERROR( RET_DIV_BY_ZERO ); + } + } + else + { + /* solve R^T*a = b */ + for( i=0; i= ZERO*getAbs( sum ) ) + a[i] = sum / RR(i,i); + else + return THROWERROR( RET_DIV_BY_ZERO ); + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * d e t e r m i n e D a t a S h i f t + */ +returnValue QProblemB::determineDataShift( const real_t* const g_new, const real_t* const lb_new, const real_t* const ub_new, + real_t* const delta_g, real_t* const delta_lb, real_t* const delta_ub, + BooleanType& Delta_bB_isZero + ) +{ + int_t i, ii; + int_t nV = getNV( ); + int_t nFX = getNFX( ); + + int_t* FX_idx; + bounds.getFixed( )->getNumberArray( &FX_idx ); + + + /* 1) Calculate shift directions. */ + for( i=0; i EPS ) || ( getAbs( delta_ub[ii] ) > EPS ) ) + { + Delta_bB_isZero = BT_FALSE; + break; + } + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * s e t u p Q P d a t a + */ +returnValue QProblemB::setupQPdata( SymmetricMatrix *_H, const real_t* const _g, + const real_t* const _lb, const real_t* const _ub + ) +{ + /* 1) Setup Hessian matrix. */ + setH( _H ); + + /* 2) Setup gradient vector. */ + if ( _g == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + else + setG( _g ); + + /* 3) Setup lower/upper bounds vector. */ + setLB( _lb ); + setUB( _ub ); + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p Q P d a t a + */ +returnValue QProblemB::setupQPdata( const real_t* const _H, const real_t* const _g, + const real_t* const _lb, const real_t* const _ub + ) +{ + /* 1) Setup Hessian matrix. */ + setH( _H ); + + /* 2) Setup gradient vector. */ + if ( _g == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + else + setG( _g ); + + /* 3) Setup lower/upper bounds vector. */ + setLB( _lb ); + setUB( _ub ); + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p Q P d a t a F r o m F i l e + */ +returnValue QProblemB::setupQPdataFromFile( const char* const H_file, const char* const g_file, + const char* const lb_file, const char* const ub_file + ) +{ + int_t i; + int_t nV = getNV( ); + + returnValue returnvalue; + + + /* 1) Load Hessian matrix from file. */ + if ( H_file != 0 ) + { + real_t* _H = new real_t[nV * nV]; + returnvalue = readFromFile( _H, nV,nV, H_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] _H; + return THROWERROR( returnvalue ); + } + setH( _H ); + H->doFreeMemory( ); + } + else + { + real_t* _H = 0; + setH( _H ); + } + + /* 2) Load gradient vector from file. */ + if ( g_file == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + returnvalue = readFromFile( g, nV, g_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( returnvalue ); + + /* 3) Load lower bounds vector from file. */ + if ( lb_file != 0 ) + { + returnvalue = readFromFile( lb, nV, lb_file ); + if ( returnvalue != SUCCESSFUL_RETURN ) + return THROWERROR( returnvalue ); + } + else + { + /* if no lower bounds are specified, set them to -infinity */ + for( i=0; i ub_new[i]+EPS) { + return RET_QP_INFEASIBLE; + } + } + } + return SUCCESSFUL_RETURN; +} + + + +/* + * i s C P U t i m e L i m i t E x c e e d e d + */ +BooleanType QProblemB::isCPUtimeLimitExceeded( const real_t* const cputime, + real_t starttime, + int_t nWSR + ) const +{ + /* Always perform next QP iteration if no CPU time limit is given. */ + if ( cputime == 0 ) + return BT_FALSE; + + /* Always perform first QP iteration. */ + if ( nWSR <= 0 ) + return BT_FALSE; + + real_t elapsedTime = getCPUtime( ) - starttime; + real_t timePerIteration = elapsedTime / ((real_t) nWSR); + + /* Determine if next QP iteration exceed CPU time limit + * considering the (current) average CPU time per iteration. */ + if ( ( elapsedTime + timePerIteration*1.25 ) <= ( *cputime ) ) + return BT_FALSE; + else + return BT_TRUE; +} + + +/* + * r e g u l a r i s e H e s s i a n + */ +returnValue QProblemB::regulariseHessian( ) +{ + /* Do nothing if Hessian regularisation is disbaled! */ + if ( options.enableRegularisation == BT_FALSE ) + return SUCCESSFUL_RETURN; + + /* Regularisation of identity Hessian not possible. */ + if ( hessianType == HST_IDENTITY ) + return THROWERROR( RET_CANNOT_REGULARISE_IDENTITY ); + + /* Determine regularisation parameter. */ + if ( usingRegularisation( ) == BT_TRUE ) + return SUCCESSFUL_RETURN; /*THROWERROR( RET_HESSIAN_ALREADY_REGULARISED );*/ + else + { + /* Regularisation of zero Hessian is done implicitly. */ + if ( hessianType == HST_ZERO ) + { + regVal = getNorm( g,getNV() ) * options.epsRegularisation; + } + else + { + regVal = H->getNorm() * options.epsRegularisation; + + if ( H->addToDiag( regVal ) == RET_NO_DIAGONAL_AVAILABLE ) + return THROWERROR( RET_CANNOT_REGULARISE_SPARSE ); + } + + THROWINFO( RET_USING_REGULARISATION ); + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * c r e a t e D i a g S p a r s e M a t + */ +SymSparseMat* QProblemB::createDiagSparseMat( int_t n, real_t diagVal ) +{ + real_t* M_val = new real_t[n]; + sparse_int_t* M_jc = new sparse_int_t[n+1]; + sparse_int_t* M_ir = new sparse_int_t[n+1]; + + for( int_t ii=0; iicreateDiagInfo( ); + M->doFreeMemory( ); + + return M; +} + + + +/* + * p e r f o r m R a t i o T e s t + */ +returnValue QProblemB::performRatioTest( int_t nIdx, + const int_t* const idxList, + const SubjectTo* const subjectTo, + const real_t* const num, + const real_t* const den, + real_t epsNum, + real_t epsDen, + real_t& t, + int_t& BC_idx + ) const +{ + int_t i, ii; + + BC_idx = -1; + + for( i=0; igetType( ii ) != ST_EQUALITY ) + { + if ( ( subjectTo->getStatus( ii ) == ST_LOWER ) || ( subjectTo->getStatus( ii ) == ST_INACTIVE ) ) + { + if ( isBlocking( num[i],den[i],epsNum,epsDen,t ) == BT_TRUE ) + { + t = num[i] / den[i]; + BC_idx = ii; + } + } + else + if ( subjectTo->getStatus( ii ) == ST_UPPER ) + { + if ( isBlocking( -num[i],-den[i],epsNum,epsDen,t ) == BT_TRUE ) + { + t = num[i] / den[i]; + BC_idx = ii; + } + } + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t R e l a t i v e H o m o t o p y L e n g t h + */ +real_t QProblemB::getRelativeHomotopyLength( const real_t* const g_new, const real_t* const lb_new, const real_t* const ub_new + ) +{ + int_t i; + int_t nV = getNV( ); + real_t d, s, len = 0.0; + + /* gradient */ + for (i = 0; i < nV; i++) + { + s = getAbs(g_new[i]); + if (s < 1.0) s = 1.0; + d = getAbs(g_new[i] - g[i]) / s; + if (d > len) len = d; + } + /*fprintf( stderr, "homLen = %e\n", len );*/ + + /* lower bounds */ + if ( lb_new != 0 ) + { + for (i = 0; i < nV; i++) + { + s = getAbs(lb_new[i]); + if (s < 1.0) s = 1.0; + d = getAbs(lb_new[i] - lb[i]) / s; + if (d > len) len = d; + } + } + /*fprintf( stderr, "homLen = %e\n", len );*/ + + /* upper bounds */ + if ( ub_new != 0 ) + { + for (i = 0; i < nV; i++) + { + s = getAbs(ub_new[i]); + if (s < 1.0) s = 1.0; + d = getAbs(ub_new[i] - ub[i]) / s; + if (d > len) len = d; + } + } + /*fprintf( stderr, "homLen = %e\n", len );*/ + + return len; +} + + +/* + * p e r f o r m R a m p i n g + */ +returnValue QProblemB::performRamping( ) +{ + int_t nV = getNV( ), bstat, i; + real_t t, rampVal; + + /* ramp inactive bounds and active dual variables */ + for (i = 0; i < nV; i++) + { + switch (bounds.getType(i)) + { + case ST_EQUALITY: lb[i] = x[i]; ub[i] = x[i]; continue; /* reestablish exact feasibility */ + case ST_UNBOUNDED: continue; + case ST_DISABLED: continue; + default: break; + } + + t = static_cast((i + rampOffset) % nV) / static_cast(nV-1); + rampVal = (1.0-t) * ramp0 + t * ramp1; + bstat = bounds.getStatus(i); + if (bstat != ST_LOWER) { lb[i] = x[i] - rampVal; } + if (bstat != ST_UPPER) { ub[i] = x[i] + rampVal; } + if (bstat == ST_LOWER) { lb[i] = x[i]; y[i] = +rampVal; } + if (bstat == ST_UPPER) { ub[i] = x[i]; y[i] = -rampVal; } + if (bstat == ST_INACTIVE) y[i] = 0.0; /* reestablish exact complementarity */ + } + + /* reestablish exact stationarity */ + setupAuxiliaryQPgradient( ); + + /* advance ramp offset to avoid Ramping cycles */ + rampOffset++; + + return SUCCESSFUL_RETURN; +} + + +/* + * u p d a t e F a r B o u n d s + */ +returnValue QProblemB::updateFarBounds( real_t curFarBound, int_t nRamp, + const real_t* const lb_new, real_t* const lb_new_far, + const real_t* const ub_new, real_t* const ub_new_far + ) const +{ + int_t i; + real_t rampVal, t; + int_t nV = getNV( ); + + if ( options.enableRamping == BT_TRUE ) + { + for ( i=0; i((i + rampOffset) % nRamp) / static_cast(nRamp-1); + rampVal = curFarBound * (1.0 + (1.0-t)*ramp0 + t*ramp1); + + if ( lb_new == 0 ) + lb_new_far[i] = -rampVal; + else + lb_new_far[i] = getMax( -rampVal,lb_new[i] ); + + if ( ub_new == 0 ) + ub_new_far[i] = rampVal; + else + ub_new_far[i] = getMin( rampVal,ub_new[i] ); + } + } + else + { + for ( i=0; ithrowInfo( RET_ITERATION_STARTED,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + /* 2) Initialise shift direction of the gradient and the bounds. */ + returnvalue = determineDataShift( g_new,lb_new,ub_new, + delta_g,delta_lb,delta_ub, + Delta_bB_isZero + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_g; + + /* Assign number of working set recalculations and stop runtime measurement. */ + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + THROWERROR( RET_SHIFT_DETERMINATION_FAILED ); + return returnvalue; + } + + /* 3) Determination of step direction of X and Y. */ + returnvalue = determineStepDirection( delta_g,delta_lb,delta_ub, + Delta_bB_isZero, + delta_xFX,delta_xFR,delta_yFX + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_g; + + /* Assign number of working set recalculations and stop runtime measurement. */ + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + THROWERROR( RET_STEPDIRECTION_DETERMINATION_FAILED ); + return returnvalue; + } + + + /* 4) Determination of step length TAU. + * This step along the homotopy path is also taken (without changing working set). */ + returnvalue = performStep( delta_g,delta_lb,delta_ub, + delta_xFX,delta_xFR,delta_yFX, + BC_idx,BC_status + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_g; + + /* Assign number of working set recalculations and stop runtime measurement. */ + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + THROWERROR( RET_STEPLENGTH_DETERMINATION_FAILED ); + return returnvalue; + } + + /* 5) Termination criterion. */ + homotopyLength = getRelativeHomotopyLength(g_new, lb_new, ub_new); + if ( homotopyLength <= options.terminationTolerance ) + { + status = QPS_SOLVED; + + THROWINFO( RET_OPTIMAL_SOLUTION_FOUND ); + + if ( printIteration( iter,BC_idx,BC_status,homotopyLength,isFirstCall ) != SUCCESSFUL_RETURN ) + THROWERROR( RET_PRINT_ITERATION_FAILED ); /* do not pass this as return value! */ + + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_g; + + return SUCCESSFUL_RETURN; + } + + + /* 6) Change active set. */ + returnvalue = changeActiveSet( BC_idx,BC_status ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_g; + + /* Assign number of working set recalculations and stop runtime measurement. */ + nWSR = iter; + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + /* checks for infeasibility... */ + if ( infeasible == BT_TRUE ) + { + status = QPS_HOMOTOPYQPSOLVED; + return setInfeasibilityFlag( RET_HOTSTART_STOPPED_INFEASIBILITY ); + } + + /* ...unboundedness... */ + if ( unbounded == BT_TRUE ) /* not necessary since objective function convex! */ + return THROWERROR( RET_HOTSTART_STOPPED_UNBOUNDEDNESS ); + + /* ... and throw unspecific error otherwise */ + THROWERROR( RET_HOMOTOPY_STEP_FAILED ); + return returnvalue; + } + + /* 6a) Possibly refactorise projected Hessian from scratch. */ + if ( ( options.enableCholeskyRefactorisation > 0 ) && ( (iter % options.enableCholeskyRefactorisation) == 0 ) ) + { + returnvalue = computeCholesky( ); + if (returnvalue != SUCCESSFUL_RETURN) + { + delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_g; + return returnvalue; + } + } + + + /* 7) Perform Ramping Strategy on zero homotopy step or drift correction (if desired). */ + if ( ( tau <= EPS ) && ( options.enableRamping == BT_TRUE ) ) + performRamping( ); + else + if ( (options.enableDriftCorrection > 0) && ((iter+1) % options.enableDriftCorrection == 0) ) + performDriftCorrection( ); /* always returns SUCCESSFUL_RETURN */ + + /* 8) Output information of successful QP iteration. */ + status = QPS_HOMOTOPYQPSOLVED; + + if ( printIteration( iter,BC_idx,BC_status,homotopyLength,isFirstCall ) != SUCCESSFUL_RETURN ) + THROWERROR( RET_PRINT_ITERATION_FAILED ); /* do not pass this as return value! */ + } + + delete[] delta_yFX; delete[] delta_xFX; delete[] delta_xFR; + delete[] delta_ub; delete[] delta_lb; delete[] delta_g; + + /* stop runtime measurement */ + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + + /* if programm gets to here, output information that QP could not be solved + * within the given maximum numbers of working set changes */ + if ( options.printLevel == PL_HIGH ) + { + #ifndef __SUPPRESSANYOUTPUT__ + snprintf( messageString,MAX_STRING_LENGTH,"(nWSR = %d)",(int)iter ); + return getGlobalMessageHandler( )->throwWarning( RET_MAX_NWSR_REACHED,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #else + return RET_MAX_NWSR_REACHED; + #endif + } + else + { + return RET_MAX_NWSR_REACHED; + } +} + + +/* + * s o l v e R e g u l a r i s e d Q P + */ +returnValue QProblemB::solveRegularisedQP( const real_t* const g_new, + const real_t* const lb_new, const real_t* const ub_new, + int_t& nWSR, real_t* const cputime, int_t nWSRperformed, + BooleanType isFirstCall + ) +{ + int_t i, step; + int_t nV = getNV( ); + + + /* Perform normal QP solution if QP has not been regularised. */ + if ( usingRegularisation( ) == BT_FALSE ) + return solveQP( g_new,lb_new,ub_new, nWSR,cputime,nWSRperformed,isFirstCall ); + + + /* I) SOLVE USUAL REGULARISED QP */ + returnValue returnvalue; + + int_t nWSR_max = nWSR; + int_t nWSR_total = nWSRperformed; + + real_t cputime_total = 0.0; + real_t cputime_cur = 0.0; + + if ( cputime == 0 ) + { + returnvalue = solveQP( g_new,lb_new,ub_new, nWSR,0,nWSRperformed,isFirstCall ); + } + else + { + cputime_cur = *cputime; + returnvalue = solveQP( g_new,lb_new,ub_new, nWSR,&cputime_cur,nWSRperformed,isFirstCall ); + } + nWSR_total = nWSR; + cputime_total += cputime_cur; + isFirstCall = BT_FALSE; + + + /* Only continue if QP solution has been successful. */ + if ( returnvalue != SUCCESSFUL_RETURN ) + { + if ( cputime != 0 ) + *cputime = cputime_total; + + if ( returnvalue == RET_MAX_NWSR_REACHED ) + THROWWARNING( RET_NO_REGSTEP_NWSR ); + + return returnvalue; + } + + + /* II) PERFORM SUCCESSIVE REGULARISATION STEPS */ + real_t* gMod = new real_t[nV]; + + for( step=0; stepgetStatus( i ) == ST_UNDEFINED ) ) + return THROWERROR( RET_UNKNOWN_BUG ); + } + else + { + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + + /* I) SETUP CHOLESKY FLAG: + * Cholesky decomposition shall only be updated if working set + * shall be updated (i.e. NOT setup afresh!) */ + BooleanType updateCholesky; + if ( setupAfresh == BT_TRUE ) + updateCholesky = BT_FALSE; + else + updateCholesky = BT_TRUE; + + + /* II) REMOVE FORMERLY ACTIVE BOUNDS (IF NECESSARY): */ + if ( setupAfresh == BT_FALSE ) + { + /* Remove all active bounds that shall be inactive AND + * all active bounds that are active at the wrong bound. */ + for( i=0; igetStatus( i ) != ST_LOWER ) ) + if ( removeBound( i,updateCholesky ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + + if ( ( bounds.getStatus( i ) == ST_UPPER ) && ( auxiliaryBounds->getStatus( i ) != ST_UPPER ) ) + if ( removeBound( i,updateCholesky ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + } + + + /* III) ADD NEWLY ACTIVE BOUNDS: */ + /* Add all inactive bounds that shall be active AND + * all formerly active bounds that have been active at the wrong bound. */ + for( i=0; igetStatus( i ) != ST_INACTIVE ) ) + { + if ( addBound( i,auxiliaryBounds->getStatus( i ),updateCholesky ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p A u x i l i a r y Q P s o l u t i o n + */ +returnValue QProblemB::setupAuxiliaryQPsolution( const real_t* const xOpt, const real_t* const yOpt + ) +{ + int_t i; + int_t nV = getNV( ); + + + /* Setup primal/dual solution vectors for auxiliary initial QP: + * if a null pointer is passed, a zero vector is assigned; + * old solution vector is kept if pointer to internal solution vector is passed. */ + if ( xOpt != 0 ) + { + if ( xOpt != x ) + for( i=0; itimes(1, -1.0, x, nV, 1.0, g, nV); + + break; + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p A u x i l i a r y Q P b o u n d s + */ +returnValue QProblemB::setupAuxiliaryQPbounds( BooleanType useRelaxation ) +{ + int_t i; + int_t nV = getNV( ); + + + /* Setup bound vectors. */ + for ( i=0; igetNumberArray( &FR_idx ); + bounds.getFixed( )->getNumberArray( &FX_idx ); + + + /* This routine computes + * delta_xFX := delta_b + * delta_xFR := R \ R' \ -( delta_g + HMX*delta_xFX ) + * delta_yFX := HMX'*delta_xFR + HFX*delta_xFX { + eps*delta_xFX } + */ + + /* I) DETERMINE delta_xFX := delta_{l|u}b */ + if ( Delta_bB_isZero == BT_FALSE ) + { + for( i=0; i 0 ) + { + /* Add - HMX*delta_xFX + * This is skipped if delta_b=0 or mixed part HM=0 (H=0 or H=Id) */ + if ( ( hessianType != HST_ZERO ) && ( hessianType != HST_IDENTITY ) && ( Delta_bB_isZero == BT_FALSE ) && ( r == 0 ) ) + H->times(bounds.getFree(), bounds.getFixed(), 1, -1.0, delta_xFX, nFX, 1.0, delta_xFR_TMP, nFR); + + /* Determine R' \ ( - HMX*delta_xFX - delta_gFR ) where R'R = HFR */ + if ( backsolveR( delta_xFR_TMP,BT_TRUE,delta_xFR_TMP ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_STEPDIRECTION_FAILED_CHOLESKY ); + + /* Determine HFR \ ( - HMX*delta_xFX - delta_gFR ) */ + if ( backsolveR( delta_xFR_TMP,BT_FALSE,delta_xFR_TMP ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_STEPDIRECTION_FAILED_CHOLESKY ); + } + + /* refine solution found for delta_xFR so far */ + for ( i=0; i 0 ) + { + real_t rnrm = 0.0; + /* compute new residual in delta_xFR_TMP: + * residual := - HFR*delta_xFR - HMX*delta_xFX - delta_gFR + * set to -delta_gFR */ + for ( i=0; itimes(bounds.getFree(), bounds.getFree(), 1, -1.0, delta_xFR, nFR, 1.0, delta_xFR_TMP, nFR); + H->times(bounds.getFree(), bounds.getFixed(), 1, -1.0, delta_xFX, nFX, 1.0, delta_xFR_TMP, nFR); + + /* compute max norm */ + for ( i=0; i 0 ) + { + if ( ( hessianType == HST_ZERO ) || ( hessianType == HST_IDENTITY ) ) + { + for( i=0; itimes(bounds.getFixed(), bounds.getFree(), 1, 1.0, delta_xFR, nFR, 1.0, delta_yFX, nFX); + if (Delta_bB_isZero == BT_FALSE) + H->times(bounds.getFixed(), bounds.getFixed(), 1, 1.0, delta_xFX, nFX, 1.0, delta_yFX, nFX); + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * p e r f o r m S t e p + */ +returnValue QProblemB::performStep( const real_t* const delta_g, + const real_t* const delta_lb, const real_t* const delta_ub, + const real_t* const delta_xFX, + const real_t* const delta_xFR, + const real_t* const delta_yFX, + int_t& BC_idx, SubjectToStatus& BC_status + ) +{ + int_t i, ii; + int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nFX = getNFX( ); + + int_t* FR_idx; + int_t* FX_idx; + + bounds.getFree( )->getNumberArray( &FR_idx ); + bounds.getFixed( )->getNumberArray( &FX_idx ); + + tau = 1.0; + BC_idx = -1; + BC_status = ST_UNDEFINED; + + int_t BC_idx_tmp = -1; + + real_t* num = new real_t[nV]; + real_t* den = new real_t[nV]; + + + /* I) DETERMINE MAXIMUM DUAL STEPLENGTH, i.e. ensure that + * active dual bounds remain valid (ignoring implicitly fixed variables): */ + for( i=0; i= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_INACTIVE; + } + + + /* II) DETERMINE MAXIMUM PRIMAL STEPLENGTH, i.e. ensure that + * inactive bounds remain valid (ignoring unbounded variables). */ + /* 1) Inactive lower bounds. */ + if ( bounds.hasNoLower( ) == BT_FALSE ) + { + for( i=0; i= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_LOWER; + } + } + + /* 2) Inactive upper bounds. */ + if ( bounds.hasNoUpper( ) == BT_FALSE ) + { + for( i=0; i= 0 ) + { + BC_idx = BC_idx_tmp; + BC_status = ST_UPPER; + } + } + + delete[] den; + delete[] num; + + + #ifndef __SUPPRESSANYOUTPUT__ + char messageString[MAX_STRING_LENGTH]; + + if ( BC_status == ST_UNDEFINED ) + snprintf( messageString,MAX_STRING_LENGTH,"Stepsize is %.15e!",tau ); + else + snprintf( messageString,MAX_STRING_LENGTH,"Stepsize is %.15e! (idx = %d, status = %d)",tau,(int)BC_idx,(int)BC_status ); + + getGlobalMessageHandler( )->throwInfo( RET_STEPSIZE_NONPOSITIVE,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + + /* III) PERFORM STEP ALONG HOMOTOPY PATH */ + if ( tau > ZERO ) + { + /* 1) Perform step in primal und dual space. */ + for( i=0; ithrowWarning( RET_STEPSIZE,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + } + + + return SUCCESSFUL_RETURN; +} + + +/* + * c h a n g e A c t i v e S e t + */ +returnValue QProblemB::changeActiveSet( int_t BC_idx, SubjectToStatus BC_status ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + char messageString[MAX_STRING_LENGTH]; + #endif + + /* IV) UPDATE ACTIVE SET */ + switch ( BC_status ) + { + /* Optimal solution found as no working set change detected. */ + case ST_UNDEFINED: + return RET_OPTIMAL_SOLUTION_FOUND; + + + /* Remove one variable from active set. */ + case ST_INACTIVE: + #ifndef __SUPPRESSANYOUTPUT__ + snprintf( messageString,MAX_STRING_LENGTH,"bound no. %d.",(int)BC_idx ); + getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeBound( BC_idx,BT_TRUE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED ); + + y[BC_idx] = 0.0; + break; + + + /* Add one variable to active set. */ + default: + #ifndef __SUPPRESSANYOUTPUT__ + if ( BC_status == ST_LOWER ) { + snprintf( messageString,MAX_STRING_LENGTH,"lower bound no. %d.",(int)BC_idx ); + } + else { + snprintf( messageString,MAX_STRING_LENGTH,"upper bound no. %d.",(int)BC_idx ); + } + getGlobalMessageHandler( )->throwInfo( RET_ADD_TO_ACTIVESET,messageString,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( addBound( BC_idx,BC_status,BT_TRUE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_ADD_TO_ACTIVESET_FAILED ); + break; + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * p e r f o r m D r i f t C o r r e c t i o n + */ +returnValue QProblemB::performDriftCorrection( ) +{ + int_t i; + int_t nV = getNV (); + + for ( i=0; igetStatus( i ) != bounds.getStatus( i ) ) + ++differenceNumber; + + /* 2) Decide wheter to refactorise or not. */ + if ( 2*differenceNumber > guessedBounds->getNFX( ) ) + return BT_TRUE; + else + return BT_FALSE; +} + + +/* + * a d d B o u n d + */ +returnValue QProblemB::addBound( int_t number, SubjectToStatus B_status, + BooleanType updateCholesky + ) +{ + int_t i, j; + int_t nV = getNV( ); + int_t nFR = getNFR( ); + + + /* consistency check */ + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + /* Perform cholesky updates only if QProblemB has been initialised! */ + if ( getStatus( ) == QPS_PREPARINGAUXILIARYQP ) + { + /* UPDATE INDICES */ + if ( bounds.moveFreeToFixed( number,B_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_ADDBOUND_FAILED ); + + return SUCCESSFUL_RETURN; + } + + + /* I) PERFORM CHOLESKY UPDATE: */ + if ( ( updateCholesky == BT_TRUE ) && + ( hessianType != HST_ZERO ) && ( hessianType != HST_IDENTITY ) ) + { + /* 1) Index of variable to be added within the list of free variables. */ + int_t number_idx = bounds.getFree( )->getIndex( number ); + + real_t c, s, nu; + + /* 2) Use row-wise Givens rotations to restore upper triangular form of R. */ + for( i=number_idx+1; ith column and ... */ + for( i=0; igetNumberArray( &FR_idx ); + + /* 1) Calculate new column of cholesky decomposition. */ + real_t* rhs = new real_t[nFR+1]; + real_t* r = new real_t[nFR]; + + real_t r0; + switch ( hessianType ) + { + case HST_ZERO: /* TODO: Code can/should? never get here!! */ + if ( usingRegularisation( ) == BT_FALSE ) + r0 = 0.0; + else + r0 = regVal; + for( i=0; igetRow(number, bounds.getFree(), 1.0, rhs); + r0 = H->diag(number); + break; + } + + if ( backsolveR( rhs,BT_TRUE,BT_TRUE,r ) != SUCCESSFUL_RETURN ) + { + delete[] rhs; delete[] r; + return THROWERROR( RET_REMOVEBOUND_FAILED ); + } + + for( i=0; i options.epsFlipping ) + RR(nFR,nFR) = getSqrt( r0 ); + else + { + hessianType = HST_SEMIDEF; + + flipper.get( &bounds,R ); + bounds.flipFixed(number); + + switch (bounds.getStatus(number)) + { + case ST_LOWER: lb[number] = ub[number]; break; + case ST_UPPER: ub[number] = lb[number]; break; + default: delete[] rhs; delete[] r; return THROWERROR( RET_MOVING_BOUND_FAILED ); + } + + } + } + else + { + if ( r0 > ZERO ) + RR(nFR,nFR) = getSqrt( r0 ); + else + { + delete[] rhs; delete[] r; + + hessianType = HST_SEMIDEF; + return THROWERROR( RET_HESSIAN_NOT_SPD ); + } + } + + delete[] rhs; delete[] r; + } + + if ( ( hessianType == HST_ZERO ) && ( options.enableFlippingBounds == BT_TRUE ) ) + { + flipper.get( &bounds,R ); + bounds.flipFixed(number); + + switch (bounds.getStatus(number)) + { + case ST_LOWER: lb[number] = ub[number]; break; + case ST_UPPER: ub[number] = lb[number]; break; + default: return THROWERROR( RET_MOVING_BOUND_FAILED ); + } + + } + + return SUCCESSFUL_RETURN; +} + + + +/* + * p r i n t I t e r a t i o n + */ +returnValue QProblemB::printIteration( int_t iter, + int_t BC_idx, SubjectToStatus BC_status, real_t homotopyLength, + BooleanType isFirstCall + ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + /* consistency check */ + if ( iter < 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + int_t i; + int_t nV = getNV(); + real_t stat, bfeas, bcmpl; + real_t *grad = 0; + + char myPrintfString[MAX_STRING_LENGTH]; + char info[MAX_STRING_LENGTH]; + const char excStr[] = " ef"; + + switch ( options.printLevel ) + { + case PL_DEBUG_ITER: + grad = new real_t[nV]; + stat = bfeas = bcmpl = 0.0; + + /* stationarity */ + for (i = 0; i < nV; i++) grad[i] = g[i] - y[i]; + H->times(1, 1.0, x, nV, 1.0, grad, nV); + for (i = 0; i < nV; i++) if (getAbs(grad[i]) > stat) stat = getAbs(grad[i]); + + /* feasibility */ + for (i = 0; i < nV; i++) if (lb[i] - x[i] > bfeas) bfeas = lb[i] - x[i]; + for (i = 0; i < nV; i++) if (x[i] - ub[i] > bfeas) bfeas = x[i] - ub[i]; + + /* complementarity */ + for (i = 0; i < nV; i++) if (y[i] > +EPS && getAbs((lb[i] - x[i])*y[i]) > bcmpl) bcmpl = getAbs((lb[i] - x[i])*y[i]); + for (i = 0; i < nV; i++) if (y[i] < -EPS && getAbs((ub[i] - x[i])*y[i]) > bcmpl) bcmpl = getAbs((ub[i] - x[i])*y[i]); + + if ( (iter % 10 == 0) && ( isFirstCall == BT_TRUE ) ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "\n%5s %4s %4s %9s %9s %9s %9s %9s\n", + "iter", "addB", "remB", "hom len", "tau", "stat", "bfeas", "bcmpl"); + } + myPrintf( myPrintfString ); + + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d ",(int)iter ); + myPrintf( myPrintfString ); + + if (tabularOutput.idxAddB >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%4d ",(int)(tabularOutput.idxAddB) ); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + if (tabularOutput.idxRemB >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%4d ",(int)(tabularOutput.idxRemB) ); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + snprintf( myPrintfString,MAX_STRING_LENGTH, "%9.2e %9.2e %9.2e %9.2e %9.2e\n", + homotopyLength, tau, stat, bfeas, bcmpl); + myPrintf( myPrintfString ); + + delete[] grad; + break; + + case PL_TABULAR: + if ( (iter % 10 == 0) && ( isFirstCall == BT_TRUE ) ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "\n%5s %6s %6s %9s %9s\n", + "iter", "addB", "remB", "hom len", "tau"); + myPrintf( myPrintfString ); + } + + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d ",(int)iter ); + myPrintf( myPrintfString ); + + if (tabularOutput.idxAddB >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d%c ",(int)(tabularOutput.idxAddB), excStr[tabularOutput.excAddB]); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + if (tabularOutput.idxRemB >= 0) + { + snprintf( myPrintfString,MAX_STRING_LENGTH, "%5d%c ",(int)(tabularOutput.idxRemB), excStr[tabularOutput.excRemB]); + myPrintf( myPrintfString ); + } + else + { + myPrintf( " " ); + } + + snprintf( myPrintfString,MAX_STRING_LENGTH, "%9.2e %9.2e\n", homotopyLength, tau); + myPrintf( myPrintfString ); + break; + + case PL_MEDIUM: + /* 1) Print header at first iteration. */ + if ( ( iter == 0 ) && ( isFirstCall == BT_TRUE ) ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH,"\n\n################# qpOASES -- QP NO. %3.0d ##################\n\n",(int)count ); + myPrintf( myPrintfString ); + + myPrintf( " Iter | StepLength | Info | nFX \n" ); + myPrintf( " ----------+------------------+------------------+--------- \n" ); + } + + /* 2) Print iteration line. */ + if ( BC_status == ST_UNDEFINED ) + { + if ( hessianType == HST_ZERO ) + snprintf( info,3,"LP" ); + else + snprintf( info,3,"QP" ); + + if ( isFirstCall == BT_TRUE ) + snprintf( myPrintfString,MAX_STRING_LENGTH," %5.1d | %1.6e | %s SOLVED | %4.1d \n", (int)iter,tau,info,(int)getNFX( ) ); + else + snprintf( myPrintfString,MAX_STRING_LENGTH," %5.1d* | %1.6e | %s SOLVED | %4.1d \n", (int)iter,tau,info,(int)getNFX( ) ); + myPrintf( myPrintfString ); + } + else + { + if ( BC_status == ST_INACTIVE ) + snprintf( info,8,"REM BND" ); + else + snprintf( info,8,"ADD BND" ); + + snprintf( myPrintfString,MAX_STRING_LENGTH," %5.1d | %1.6e | %s %4.1d | %4.1d \n", (int)iter,tau,info,(int)BC_idx,(int)getNFX( ) ); + myPrintf( myPrintfString ); + } + break; + + default: + /* nothing to display */ + break; + } + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/SQProblem.cpp b/locomotion/src/third_party/qpOASES/src/SQProblem.cpp new file mode 100644 index 0000000..95dde53 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/SQProblem.cpp @@ -0,0 +1,559 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/SQProblem.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the SQProblem class which is able to use the newly + * developed online active set strategy for parametric quadratic programming + * with varying matrices. + */ + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * S Q P r o b l e m + */ +SQProblem::SQProblem( ) : QProblem( ) +{ +} + + +/* + * S Q P r o b l e m + */ +SQProblem::SQProblem( int_t _nV, int_t _nC, HessianType _hessianType, BooleanType allocDenseMats ) + : QProblem( _nV,_nC,_hessianType,allocDenseMats ) +{ +} + + +/* + * S Q P r o b l e m + */ +SQProblem::SQProblem( const SQProblem& rhs ) : QProblem( rhs ) +{ +} + + +/* + * ~ S Q P r o b l e m + */ +SQProblem::~SQProblem( ) +{ +} + + +/* + * o p e r a t o r = + */ +SQProblem& SQProblem::operator=( const SQProblem& rhs ) +{ + if ( this != &rhs ) + { + QProblem::operator=( rhs ); + } + + return *this; +} + + + +/* + * h o t s t a r t + */ +returnValue SQProblem::hotstart( SymmetricMatrix *H_new, const real_t* const g_new, Matrix *A_new, + const real_t* const lb_new, const real_t* const ub_new, + const real_t* const lbA_new, const real_t* const ubA_new, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints + ) +{ + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_PREPARINGAUXILIARYQP ) || + ( getStatus( ) == QPS_PERFORMINGHOMOTOPY ) ) + { + return THROWERROR( RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED ); + } + + + real_t starttime = 0.0; + real_t auxTime = 0.0; + + if ( cputime != 0 ) { + starttime = getCPUtime( ); + } + + + /* I) UPDATE QP MATRICES AND VECTORS */ + if ( setupNewAuxiliaryQP( H_new,A_new,lb_new,ub_new,lbA_new,ubA_new ) != SUCCESSFUL_RETURN ) { + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + } + + + /* II) PERFORM USUAL HOMOTOPY */ + + /* Allow only remaining CPU time for usual hotstart. */ + if ( cputime != 0 ) + { + auxTime = getCPUtime( ) - starttime; + *cputime -= auxTime; + } + + returnValue returnvalue = QProblem::hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, + nWSR,cputime, + guessedBounds,guessedConstraints + ); + + if ( cputime != 0 ) { + *cputime += auxTime; + } + + return returnvalue; +} + + +/* + * h o t s t a r t + */ +returnValue SQProblem::hotstart( const real_t* const H_new, const real_t* const g_new, const real_t* const A_new, + const real_t* const lb_new, const real_t* const ub_new, + const real_t* const lbA_new, const real_t* const ubA_new, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints + ) +{ + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_PREPARINGAUXILIARYQP ) || + ( getStatus( ) == QPS_PERFORMINGHOMOTOPY ) ) + { + return THROWERROR( RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED ); + } + + /* start runtime measurement */ + real_t starttime = 0.0; + if ( cputime != 0 ) { + starttime = getCPUtime( ); + } + + + /* I) UPDATE QP MATRICES AND VECTORS */ + if ( setupNewAuxiliaryQP( H_new,A_new,lb_new,ub_new,lbA_new,ubA_new ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + + + /* II) PERFORM USUAL HOMOTOPY */ + + /* Allow only remaining CPU time for usual hotstart. */ + if ( cputime != 0 ) { + *cputime -= getCPUtime( ) - starttime; + } + + returnValue returnvalue = QProblem::hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, + nWSR,cputime, + guessedBounds,guessedConstraints + ); + + + /* stop runtime measurement */ + if ( cputime != 0 ) + *cputime = getCPUtime( ) - starttime; + + return returnvalue; +} + + +/* + * h o t s t a r t + */ +returnValue SQProblem::hotstart( const char* const H_file, const char* const g_file, const char* const A_file, + const char* const lb_file, const char* const ub_file, + const char* const lbA_file, const char* const ubA_file, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints + ) +{ + int_t nV = getNV( ); + int_t nC = getNC( ); + + returnValue returnvalue; + + /* consistency checks */ + if ( ( H_file == 0 ) || ( g_file == 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( ( nC > 0 ) && ( A_file == 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + + /* 1) Load new QP matrices from files. */ + real_t* H_new = new real_t[nV*nV]; + real_t* A_new = new real_t[nC*nV]; + + if ( readFromFile( H_new, nV,nV, H_file ) != SUCCESSFUL_RETURN ) + { + delete[] A_new; + delete[] H_new; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + if ( readFromFile( A_new, nC,nV, A_file ) != SUCCESSFUL_RETURN ) + { + delete[] A_new; + delete[] H_new; + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + /* 2) Load new QP vectors from files. */ + real_t* g_new = new real_t[nV]; + real_t* lb_new = ( lb_file != 0 ) ? new real_t[nV] : 0; + real_t* ub_new = ( ub_file != 0 ) ? new real_t[nV] : 0; + real_t* lbA_new = ( lbA_file != 0 ) ? new real_t[nC] : 0; + real_t* ubA_new = ( ubA_file != 0 ) ? new real_t[nC] : 0; + + returnvalue = loadQPvectorsFromFile( g_file,lb_file,ub_file,lbA_file,ubA_file, + g_new,lb_new,ub_new,lbA_new,ubA_new + ); + if ( returnvalue != SUCCESSFUL_RETURN ) + { + if ( ubA_file != 0 ) + delete[] ubA_new; + if ( lbA_file != 0 ) + delete[] lbA_new; + if ( ub_file != 0 ) + delete[] ub_new; + if ( lb_file != 0 ) + delete[] lb_new; + delete[] g_new; + delete[] A_new; + delete[] H_new; + + return THROWERROR( RET_UNABLE_TO_READ_FILE ); + } + + /* 3) Actually perform hotstart. */ + returnvalue = hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, + nWSR,cputime, + guessedBounds,guessedConstraints + ); + + if ( ubA_file != 0 ) + delete[] ubA_new; + if ( lbA_file != 0 ) + delete[] lbA_new; + if ( ub_file != 0 ) + delete[] ub_new; + if ( lb_file != 0 ) + delete[] lb_new; + delete[] g_new; + delete[] A_new; + delete[] H_new; + + return returnvalue; +} + + +/* + * h o t s t a r t + */ +returnValue SQProblem::hotstart( const real_t* const g_new, + const real_t* const lb_new, const real_t* const ub_new, + const real_t* const lbA_new, const real_t* const ubA_new, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints + ) +{ + /* Call to hotstart function for fixed QP matrices. */ + return QProblem::hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,cputime, guessedBounds,guessedConstraints ); +} + + +/* + * h o t s t a r t + */ +returnValue SQProblem::hotstart( const char* const g_file, + const char* const lb_file, const char* const ub_file, + const char* const lbA_file, const char* const ubA_file, + int_t& nWSR, real_t* const cputime, + const Bounds* const guessedBounds, const Constraints* const guessedConstraints + ) +{ + /* Call to hotstart function for fixed QP matrices. */ + return QProblem::hotstart( g_file,lb_file,ub_file,lbA_file,ubA_file, nWSR,cputime, guessedBounds,guessedConstraints ); +} + + + +#ifdef __MATLAB__ +returnValue SQProblem::resetMatrixPointers( ) +{ + H = 0; + A = 0; + + return SUCCESSFUL_RETURN; +} +#endif + + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * s e t u p N e w A u x i l i a r y Q P + */ +returnValue SQProblem::setupNewAuxiliaryQP( SymmetricMatrix *H_new, Matrix *A_new, + const real_t *lb_new, const real_t *ub_new, const real_t *lbA_new, const real_t *ubA_new + ) +{ + int_t i; + int_t nV = getNV( ); + int_t nC = getNC( ); + returnValue returnvalue; + + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_PREPARINGAUXILIARYQP ) || + ( getStatus( ) == QPS_PERFORMINGHOMOTOPY ) ) + { + return THROWERROR( RET_UPDATEMATRICES_FAILED_AS_QP_NOT_SOLVED ); + } + + status = QPS_PREPARINGAUXILIARYQP; + + + /* I) SETUP NEW QP MATRICES AND VECTORS: */ + /* 1) Shift constraints' bounds vectors by (A_new - A)'*x_opt to ensure + * that old optimal solution remains feasible for new QP data. */ + /* Firstly, shift by -A'*x_opt and ... */ + if ( nC > 0 ) + { + if ( A_new == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + for ( i=0; i 0) { + // the current active set leaves an indefinite null space Hessian + // move all inactive variables to a bound, creating an empty null space + for (int_t ii = 0; ii < nV; ++ii) + if (oldBounds.getStatus (ii) == ST_INACTIVE) + oldBounds.setStatus (ii, options.initialStatusBounds); + } + + /* ... reset them ... */ + bounds.init( nV ); + constraints.init( nC ); + + /* ... and set them up afresh. */ + if ( setupSubjectToType(lb_new,ub_new,lbA_new,ubA_new ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + + if ( bounds.setupAllFree( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + + if ( constraints.setupAllInactive( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + + /* 2) Setup TQ factorisation. */ + if ( setupTQfactorisation( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + + // check for equalities that have become bounds ... + for (int_t ii = 0; ii < nC; ++ii) { + if (oldConstraints.getType (ii) == ST_EQUALITY && constraints.getType (ii) == ST_BOUNDED) { + if (oldConstraints.getStatus (ii) == ST_LOWER && y[nV+ii] < 0.0) + oldConstraints.setStatus (ii, ST_UPPER); + else if (oldConstraints.getStatus (ii) == ST_UPPER && y[nV+ii] > 0.0) + oldConstraints.setStatus (ii, ST_LOWER); + } + } + + // ... and do the same also for the bounds! + for (int_t ii = 0; ii < nV; ++ii) { + if (oldBounds.getType(ii) == ST_EQUALITY + && bounds.getType(ii) == ST_BOUNDED) { + if (oldBounds.getStatus(ii) == ST_LOWER && y[ii] < 0.0) + oldBounds.setStatus(ii, ST_UPPER); + else if (oldBounds.getStatus(ii) == ST_UPPER && y[ii] > 0.0) + oldBounds.setStatus(ii, ST_LOWER); + } + } + + /* 3) Setup old working sets afresh (updating TQ factorisation). */ + if ( setupAuxiliaryWorkingSet( &oldBounds,&oldConstraints,BT_TRUE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + + /* Factorise projected Hessian + * this now handles all special cases (no active bounds/constraints, no nullspace) */ + returnvalue = computeProjectedCholesky( ); + + /* leave the loop if decomposition was successful, i.e. we have + * found an active set with positive definite null space Hessian */ + if ( returnvalue == SUCCESSFUL_RETURN ) + break; + } + + /* adjust lb/ub if we changed the old active set in the second try + */ + if (n_try > 0) { + // as per setupAuxiliaryQPbounds assumptions ... oh the troubles + for (int_t ii = 0; ii < nC; ++ii) + Ax_l[ii] = Ax_u[ii] = Ax[ii]; + setupAuxiliaryQPbounds( &bounds, &constraints, BT_FALSE ); + } + + status = QPS_AUXILIARYQPSOLVED; + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p N e w A u x i l i a r y Q P + */ +returnValue SQProblem::setupNewAuxiliaryQP( const real_t* const H_new, const real_t* const A_new, + const real_t *lb_new, const real_t *ub_new, const real_t *lbA_new, const real_t *ubA_new + ) +{ + int_t nV = getNV( ); + int_t nC = getNC( ); + + DenseMatrix *dA = 0; + SymDenseMat *sH = 0; + + if ( A_new != 0 ) + { + dA = new DenseMatrix(nC, nV, nV, (real_t*) A_new); + } + else + { + if ( nC > 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + if ( H_new != 0 ) + sH = new SymDenseMat(nV, nV, nV, (real_t*) H_new); + + returnValue returnvalue = setupNewAuxiliaryQP( sH,dA, lb_new,ub_new,lbA_new,ubA_new ); + + if ( H_new != 0 ) + freeHessian = BT_TRUE; + freeConstraintMatrix = BT_TRUE; + + return returnvalue; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/SQProblemSchur.cpp b/locomotion/src/third_party/qpOASES/src/SQProblemSchur.cpp new file mode 100644 index 0000000..ba3b843 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/SQProblemSchur.cpp @@ -0,0 +1,3634 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2014 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/SQProblemSchur.cpp + * \author Andreas Waechter and Dennis Janka, based on QProblem.cpp by Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2012-2017 + * + * Implementation of the SQProblemSchur class which is able to use the newly + * developed online active set strategy for parametric quadratic programming. + * This implementation uses a Schur complement approach to solve the linear + * systems. + */ + +#include +#include + + +#ifndef __MATLAB__ +# include +void MyPrintf(const char* pformat, ... ) +{ + va_list ap; + va_start(ap, pformat); + + vfprintf(stdout, pformat, ap); + + va_end(ap); +} +#else +# include +# define MyPrintf mexPrintf +#endif + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * Q P r o b l e m + */ +SQProblemSchur::SQProblemSchur( ) : SQProblem( ) +{ +#ifdef SOLVER_MA57 + sparseSolver = new Ma57SparseSolver(); +#elif defined SOLVER_MA27 + sparseSolver = new Ma27SparseSolver(); +#elif defined SOLVER_MUMPS + sparseSolver = new MumpsSparseSolver(); +#elif defined SOLVER_NONE + sparseSolver = new DummySparseSolver(); +#endif + + nSmax = 0; + nS = -1; + S = 0; + Q_ = 0; + R_ = 0; + detS = 0.0; + rcondS = 0.0; + schurUpdateIndex = 0; + schurUpdate = 0; + numFactorizations = 0; + + M_physicallength = 0; + M_vals = 0; + M_ir = 0; + M_jc = 0; +} + + +/* + * Q P r o b l e m + */ +SQProblemSchur::SQProblemSchur( int_t _nV, int_t _nC, HessianType _hessianType, int_t maxSchurUpdates ) + : SQProblem( _nV,_nC,_hessianType, BT_FALSE ) +{ + /* The interface to the sparse linear solver. In the long run, + different linear solvers might be optionally chosen. */ +#ifdef SOLVER_MA57 + sparseSolver = new Ma57SparseSolver(); +#elif defined SOLVER_MA27 + sparseSolver = new Ma27SparseSolver(); +#elif defined SOLVER_MUMPS + sparseSolver = new MumpsSparseSolver(); +#elif defined SOLVER_NONE + sparseSolver = new DummySparseSolver(); +#endif + + nSmax = maxSchurUpdates; + nS = -1; + if ( nSmax > 0 ) + { + S = new real_t[nSmax*nSmax]; + schurUpdateIndex = new int_t[nSmax]; + schurUpdate = new SchurUpdateType[nSmax]; + Q_ = new real_t[nSmax*nSmax]; + R_ = new real_t[nSmax*nSmax]; + M_physicallength = 10*nSmax; /* TODO: Decide good default. */ + M_vals = new real_t[M_physicallength]; + M_ir = new sparse_int_t[M_physicallength]; + M_jc = new sparse_int_t[nSmax+1]; + detS = 1.0; + rcondS = 1.0; + } + else + { + S = 0; + Q_ = 0; + R_ = 0; + detS = 0.0; + rcondS = 0.0; + schurUpdateIndex = 0; + schurUpdate = 0; + M_physicallength = 0; + M_vals = 0; + M_ir = 0; + M_jc = 0; + } + numFactorizations = 0; +} + + +/* + * Q P r o b l e m + */ +SQProblemSchur::SQProblemSchur( const SQProblemSchur& rhs ) : SQProblem( rhs ) +{ +#ifdef SOLVER_MA57 + sparseSolver = new Ma57SparseSolver(); +#elif defined SOLVER_MA27 + sparseSolver = new Ma27SparseSolver(); +#elif defined SOLVER_MUMPS + sparseSolver = new MumpsSparseSolver(); +#elif defined SOLVER_NONE + sparseSolver = new DummySparseSolver(); +#endif + copy( rhs ); +} + + +/* + * ~ Q P r o b l e m + */ +SQProblemSchur::~SQProblemSchur( ) +{ + delete sparseSolver; + + clear( ); +} + + +/* + * o p e r a t o r = + */ +SQProblemSchur& SQProblemSchur::operator=( const SQProblemSchur& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + SQProblem::operator=( rhs ); + copy( rhs ); + } + return *this; +} + + +/* + * r e s e t + */ +returnValue SQProblemSchur::reset( ) +{ + /* AW: We probably want to avoid resetting factorization in QProblem */ + if ( SQProblem::reset( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_RESET_FAILED ); + + sparseSolver->reset(); + nS = -1; + + return SUCCESSFUL_RETURN; +} + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * c l e a r + */ +returnValue SQProblemSchur::clear( ) +{ + nSmax = 0; + nS = -1; + detS = 0.0; + rcondS = 0.0; + numFactorizations = 0; + delete [] S; S=0; + delete [] Q_; Q_=0; + delete [] R_; R_=0; + delete [] schurUpdateIndex; schurUpdateIndex=0; + delete [] schurUpdate; schurUpdate=0; + M_physicallength = 0; + delete [] M_vals; M_vals=0; + delete [] M_ir; M_ir=0; + delete [] M_jc; M_jc=0; + + return SUCCESSFUL_RETURN; +} + + +/* + * c o p y + */ +returnValue SQProblemSchur::copy( const SQProblemSchur& rhs + ) +{ + int_t i, j, length; + + *sparseSolver = *(rhs.sparseSolver); + + nS = rhs.nS; + nSmax = rhs.nSmax; + if ( nSmax > 0 ) + { + detS = rhs.detS; + rcondS = rhs.rcondS; + S = new real_t[nSmax*nSmax]; + Q_ = new real_t[nSmax*nSmax]; + R_ = new real_t[nSmax*nSmax]; + schurUpdateIndex = new int_t[nSmax]; + schurUpdate = new SchurUpdateType[nSmax]; + + if ( nS>0 ) + { + for ( i=0; i0 ) + { + M_vals = new real_t[M_physicallength]; + M_ir = new sparse_int_t[M_physicallength]; + M_jc = new sparse_int_t[nSmax+1]; + + if ( nS>0 ) + { + memcpy(M_jc, rhs.M_jc, ((unsigned int)(nS+1))*sizeof(sparse_int_t)); + length = M_jc[nS]; + memcpy(M_vals, rhs.M_vals, ((unsigned int)length)*sizeof(real_t)); + memcpy(M_ir, rhs.M_ir, ((unsigned int)length)*sizeof(sparse_int_t)); + } + else if ( nS==0 ) + M_jc[0] = rhs.M_jc[0]; + } + } + else + { + S = 0; + Q_ = 0; + R_ = 0; + detS = 0.0; + rcondS = 0.0; + schurUpdateIndex = 0; + schurUpdate = 0; + M_physicallength = 0; + M_vals = 0; + M_ir = 0; + M_jc = 0; + } + numFactorizations = rhs.numFactorizations; + + boundsFreeStart = rhs.boundsFreeStart; + constraintsActiveStart = rhs.constraintsActiveStart; + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p A u x i l i a r y Q P + */ +returnValue SQProblemSchur::setupAuxiliaryQP( SymmetricMatrix *H_new, + Matrix *A_new, + const real_t *lb_new, + const real_t *ub_new, + const real_t *lbA_new, + const real_t *ubA_new + ) +{ + int_t i; + int_t nV = getNV( ); + int_t nC = getNC( ); + returnValue returnvalue; + + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_PREPARINGAUXILIARYQP ) || + ( getStatus( ) == QPS_PERFORMINGHOMOTOPY ) ) + { + return THROWERROR( RET_UPDATEMATRICES_FAILED_AS_QP_NOT_SOLVED ); + } + + status = QPS_PREPARINGAUXILIARYQP; + + + /* I) SETUP NEW QP MATRICES AND VECTORS: */ + /* 1) Shift constraints' bounds vectors by (A_new - A)'*x_opt to ensure + * that old optimal solution remains feasible for new QP data. */ + /* Firstly, shift by -A'*x_opt and ... */ + if ( nC > 0 ) + { + if ( A_new == 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + for ( i=0; igetNegativeEigenvalues( ); + + if ( returnvalue == SUCCESSFUL_RETURN && neig == getNAC( ) ) + { + /* a) This means the proposed working set is linearly independent and + * leaves no zero curvature exposed in the nullspace and can be used to start QP solve. */ + if ( options.printLevel == PL_HIGH ) + MyPrintf( "In hotstart for new matrices, old working set is linearly independent and has correct inertia.\n"); + + status = QPS_AUXILIARYQPSOLVED; + return SUCCESSFUL_RETURN; + } + else if ( returnvalue == SUCCESSFUL_RETURN && neig > getNAC( ) ) + { + /* b) KKT matrix has too many negative eigenvalues. Try to correct the inertia by adding bounds (reduce nullspace dimension). */ + if ( options.printLevel == PL_HIGH ) + MyPrintf( "WARNING: In hotstart for new matrices, reduced Hessian for initial working set has %i negative eigenvalues, should be %i.\n", neig, getNAC( ) ); + + /* If enabling inertia correction is disabled, exit here */ + if ( options.enableInertiaCorrection ) + { + returnvalue = correctInertia(); + if ( returnvalue == SUCCESSFUL_RETURN ) + { + status = QPS_AUXILIARYQPSOLVED; + return SUCCESSFUL_RETURN; + } + } + else + return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); + } + + /* 2) If inertia correction has failed or factorization yielded some other error, + * try to rebuild the active set with all simple bounds set according to initialStatusBounds + * (Note: in exact arithmetic, this cannot happen) */ + if ( options.printLevel == PL_HIGH ) + MyPrintf( "WARNING: hotstart for old active set failed. Trying to rebuild a working set.\n"); + + Bounds oldBounds = bounds; + Constraints oldConstraints = constraints; + + /* Move all inactive variables to a bound */ + for ( i=0; igetStatus( i ) == ST_UNDEFINED ) ) + return THROWERROR( RET_UNKNOWN_BUG ); + } + else + { + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + if ( auxiliaryConstraints != 0 ) + { + for( i=0; igetStatus( i ) == ST_UNDEFINED ) ) + return THROWERROR( RET_UNKNOWN_BUG ); + } + else + { + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + /* I.) REMOVE INEQUALITY BOUNDS/CONSTRAINTS */ + + /* I.1) Remove inequality bounds that are active now but shall be + * inactive or active at the other bound according to auxiliaryBounds */ + for( i=0; igetStatus( i ) != ST_LOWER ) ) + if ( bounds.moveFixedToFree( i ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + + if ( ( bounds.getStatus( i ) == ST_UPPER ) && ( auxiliaryBounds->getStatus( i ) != ST_UPPER ) ) + if ( bounds.moveFixedToFree( i ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + + /* I.2.) Remove inequality constraints that are active now but shall be + * inactive or active at the other bound according to auxiliaryConstraints */ + for( i=0; igetStatus( i ) != ST_LOWER ) ) + if ( constraints.moveActiveToInactive( i ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + + if ( ( constraints.getStatus( i ) == ST_UPPER ) && ( auxiliaryConstraints->getStatus( i ) != ST_UPPER ) ) + if ( constraints.moveActiveToInactive( i ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + + /* II.) ADD BOUNDS/CONSTRAINTS */ + + /* II.1.) Add bounds according to auxiliaryBounds */ + for( i=0; igetStatus( i ) != ST_INACTIVE ) ) + if ( bounds.moveFreeToFixed( i, auxiliaryBounds->getStatus( i ) ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + + /* II.2.) Add constraints according to auxiliaryConstraints */ + for( i=0; igetStatus( i ) != ST_INACTIVE ) ) + if ( constraints.moveInactiveToActive( i,auxiliaryConstraints->getStatus( i ) ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + } + + /* III) FACTORIZATION */ + + /* III.1.) Factorize (resolves linear dependency) */ + if( resetSchurComplement( BT_FALSE ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); + + /* III.2.) Check if inertia is correct. If so, we now have a linearly independent working set with a pos def reduced Hessian */ + int_t neig = sparseSolver->getNegativeEigenvalues( ); + if ( neig == getNAC( ) ) + { + /* We now have a linearly independent working set with a pos def reduced Hessian. + * We need to correct the QP bounds and gradient after this. */ + return SUCCESSFUL_RETURN; + } + + /* IV.) INERTIA CORRECTION IF NECESSARY */ + + /* We now have a fresh factorization and can start the usual inertia correction routine */ + if ( options.printLevel == PL_HIGH ) + MyPrintf( "WARNING: In setupAuxiliaryWorkingSet: Initial working set reduced Hessian has %i negative eigenvalues, should be %i.\n", neig, getNAC( ) ); + + if ( options.enableInertiaCorrection == BT_TRUE ) + return correctInertia( ); + else + return THROWERROR( RET_SETUP_WORKINGSET_FAILED ); +} + + +/* + * c h o l e s k y D e c o m p o s i t i o n P r o j e c t e d + */ +returnValue SQProblemSchur::computeProjectedCholesky( ) +{ + return SUCCESSFUL_RETURN; +} + + +/* + * c o m p u t e I n i t i a l C h o l e s k y + */ +returnValue SQProblemSchur::computeInitialCholesky( ) +{ + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p T Q f a c t o r i s a t i o n + */ +returnValue SQProblemSchur::setupTQfactorisation( ) +{ + return SUCCESSFUL_RETURN; +} + + +/* + * a d d C o n s t r a i n t + */ +returnValue SQProblemSchur::addConstraint( int_t number, + SubjectToStatus C_status, + BooleanType updateCholesky, + BooleanType ensureLI + ) +{ + int_t idxDeleted = -1; + + /* consistency checks */ + if ( constraints.getStatus( number ) != ST_INACTIVE ) + return THROWERROR( RET_CONSTRAINT_ALREADY_ACTIVE ); + + if ( ( constraints.getNC( ) - getNAC( ) ) == constraints.getNUC( ) ) + return THROWERROR( RET_ALL_CONSTRAINTS_ACTIVE ); + + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + + /* I) ENSURE LINEAR INDEPENDENCE OF THE WORKING SET, + * i.e. remove a constraint or bound if linear dependence occurs. */ + if ( ensureLI == BT_TRUE ) + { + returnValue ensureLIreturnvalue = addConstraint_ensureLI( number,C_status ); + + switch ( ensureLIreturnvalue ) + { + case SUCCESSFUL_RETURN: + break; + + case RET_LI_RESOLVED: + break; + + case RET_ENSURELI_FAILED_NOINDEX: + return RET_ADDCONSTRAINT_FAILED_INFEASIBILITY; + + case RET_ENSURELI_FAILED_CYCLING: + return RET_ADDCONSTRAINT_FAILED_INFEASIBILITY; + + case RET_ENSURELI_DROPPED: + return SUCCESSFUL_RETURN; + + default: + return THROWERROR( RET_ENSURELI_FAILED ); + } + } + + /* IV) UPDATE INDICES */ + tabularOutput.idxAddC = number; + if ( constraints.moveInactiveToActive( number,C_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_ADDCONSTRAINT_FAILED ); + + /* Also update the Schur complement. */ + + /* First check if this constraint had been removed before. In that + case delete this constraint from the Schur complement. */ + bool found = false; + for ( int_t i=0; igetSparseSubmatrix( 1, &number, icolsLength, icolsNumber, 0, 0, numNonzerosA, irn, jcn, vals ); + delete [] irn; + + int_t numNonzerosM = 0; + int_t numNonzerosN = 0; + for ( int_t i=0; igetNumberArray( &FR_idx ); + + /* For the Schur complement version we only use options.enableFullLITests = TRUE */ + { + /* + * expensive LI test. Backsolve with refinement using special right + * hand side. This gives an estimate for what should be considered + * "zero". We then check linear independence relative to this estimate. + */ + + int_t *FX_idx, *AC_idx, *IAC_idx; + + real_t *delta_g = new real_t[nV]; + real_t *delta_xFX = new real_t[nFX]; + real_t *delta_xFR = new real_t[nFR]; + real_t *delta_yAC = xiC; + real_t *delta_yFX = xiB; + + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + constraints.getInactive( )->getNumberArray( &IAC_idx ); + + int_t dim = (nC>nV)?nC:nV; + real_t *nul = new real_t[dim]; + for (ii = 0; ii < dim; ++ii) + nul[ii]=0.0; + + A->getRow (number, 0, 1.0, delta_g); + + returnValue dsdreturnvalue = determineStepDirection ( delta_g, + nul, nul, nul, nul, + BT_FALSE, BT_FALSE, + delta_xFX, delta_xFR, delta_yAC, delta_yFX); + if (dsdreturnvalue!=SUCCESSFUL_RETURN) + returnvalue = dsdreturnvalue; + + delete[] nul; + + /* compute the weight in inf-norm */ + real_t weight = 0.0; + for (ii = 0; ii < nAC; ++ii) + { + real_t a = getAbs (delta_yAC[ii]); + if (weight < a) weight = a; + } + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_yFX[ii]); + if (weight < a) weight = a; + } + + /* look at the "zero" in a relative inf-norm */ + real_t zero = 0.0; + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_xFX[ii]); + if (zero < a) zero = a; + } + for (ii = 0; ii < nFR; ++ii) + { + real_t a = getAbs (delta_xFR[ii]); + if (zero < a) zero = a; + } + + /* relative test against zero in inf-norm */ + if (zero > options.epsLITests * weight) + returnvalue = RET_LINEARLY_INDEPENDENT; + + delete[] delta_xFR; + delete[] delta_xFX; + delete[] delta_g; + + } + return THROWINFO( returnvalue ); +} + + +/* + * a d d C o n s t r a i n t _ e n s u r e L I + */ +returnValue SQProblemSchur::addConstraint_ensureLI( int_t number, SubjectToStatus C_status ) +{ + /* Get space for the multipliers xi in linear independence test */ + int_t nAC = getNAC(); + int_t nFX = getNFX(); + real_t *xiC = new real_t[nAC]; + real_t *xiB = new real_t[nFX]; + + /* I) Check if new constraint is linearly independent from the active ones. */ + returnValue returnvalueCheckLI = addConstraint_checkLISchur( number, xiC, xiB ); + + if ( returnvalueCheckLI == RET_INDEXLIST_CORRUPTED ) + { + delete [] xiB; + delete [] xiC; + return THROWERROR( RET_ENSURELI_FAILED ); + } + + if ( returnvalueCheckLI == RET_LINEARLY_INDEPENDENT ) + { + delete [] xiB; + delete [] xiC; + return SUCCESSFUL_RETURN; + } + + /* II) NEW BOUND IS LINEARLY DEPENDENT: */ + /* 1) Coefficients of linear combination, have already been computed, but we need to correct the sign. */ + int_t i, ii; + + if ( C_status != ST_LOWER ) + { + for( i=0; igetNumberArray( &FX_idx ); + + int_t* AC_idx; + constraints.getActive( )->getNumberArray( &AC_idx ); + + real_t* num = new real_t[nV]; + + real_t y_min = options.maxDualJump; + int_t y_min_number = -1; + int_t y_min_number_bound = -1; + BooleanType y_min_isBound = BT_FALSE; + + returnValue returnvalue = SUCCESSFUL_RETURN; + + /* III) DETERMINE CONSTRAINT/BOUND TO BE REMOVED. */ + + /* 1) Constraints. */ + for( i=0; i= 0 ) + { + y_min_number = y_min_number_bound; + y_min_isBound = BT_TRUE; + } + + #ifndef __XPCTARGET__ + /* setup output preferences */ + char messageString[80]; + #endif + + /* IV) REMOVE CONSTRAINT/BOUND FOR RESOLVING LINEAR DEPENDENCE: */ + if ( y_min_number >= 0 ) + { + /* Update Lagrange multiplier... */ + for( i=0; ithrowInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeBound( y_min_number,BT_TRUE,BT_FALSE,BT_FALSE ) != SUCCESSFUL_RETURN ) + { + returnvalue = RET_REMOVE_FROM_ACTIVESET_FAILED; + goto farewell; + } + tabularOutput.excRemB = 1; + + y[y_min_number] = 0.0; + } + else + { + #ifndef __XPCTARGET__ + snprintf( messageString,80,"constraint no. %d.",(int)y_min_number ); + getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeConstraint( y_min_number,BT_TRUE,BT_FALSE,BT_FALSE ) != SUCCESSFUL_RETURN ) + { + returnvalue = RET_REMOVE_FROM_ACTIVESET_FAILED; + goto farewell; + } + tabularOutput.excRemC = 1; + + y[nV+y_min_number] = 0.0; + } + } + else + { + if (options.enableDropInfeasibles == BT_TRUE) { + /* dropping of infeasible constraints according to drop priorities */ + returnvalue = dropInfeasibles (number, C_status, BT_FALSE, xiB, xiC); + } + else + { + /* no constraint/bound can be removed => QP is infeasible! */ + returnvalue = RET_ENSURELI_FAILED_NOINDEX; + setInfeasibilityFlag( returnvalue ); + } + } + +farewell: + delete[] num; + delete [] xiB; + delete [] xiC; + + getGlobalMessageHandler( )->throwInfo( RET_LI_RESOLVED,0,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE ); + + return (returnvalue != SUCCESSFUL_RETURN) ? THROWERROR (returnvalue) : returnvalue; +} + + +/* + * a d d B o u n d + */ +returnValue SQProblemSchur::addBound( int_t number, + SubjectToStatus B_status, + BooleanType updateCholesky, + BooleanType ensureLI + ) +{ + int_t idxDeleted = -1; + + /* consistency checks */ + if ( bounds.getStatus( number ) != ST_INACTIVE ) + return THROWERROR( RET_BOUND_ALREADY_ACTIVE ); + + if ( getNFR( ) == bounds.getNUV( ) ) + return THROWERROR( RET_ALL_BOUNDS_ACTIVE ); + + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + + /* I) ENSURE LINEAR INDEPENDENCE OF THE WORKING SET, + * i.e. remove a constraint or bound if linear dependence occurs. */ + if ( ensureLI == BT_TRUE ) + { + returnValue ensureLIreturnvalue = addBound_ensureLI( number,B_status ); + + switch ( ensureLIreturnvalue ) + { + case SUCCESSFUL_RETURN: + break; + + case RET_LI_RESOLVED: + break; + + case RET_ENSURELI_FAILED_NOINDEX: + return RET_ADDBOUND_FAILED_INFEASIBILITY; + + case RET_ENSURELI_FAILED_CYCLING: + return RET_ADDBOUND_FAILED_INFEASIBILITY; + + case RET_ENSURELI_DROPPED: + return SUCCESSFUL_RETURN; + + default: + return THROWERROR( RET_ENSURELI_FAILED ); + } + } + + /* II) UPDATE INDICES */ + tabularOutput.idxAddB = number; + if ( bounds.moveFreeToFixed( number,B_status ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_ADDBOUND_FAILED ); + + /* Also update the Schur complement. */ + + /* First check if this variable had been freed before. In that + case delete this variable from the Schur complement. */ + bool found = false; + for ( int_t i=0; igetNumberArray( &FR_idx ); + + /* For the Schur complement version we only use options.enableFullLITests = TRUE */ + { + /* + * expensive LI test. Backsolve with refinement using special right + * hand side. This gives an estimate for what should be considered + * "zero". We then check linear independence relative to this estimate. + */ + + real_t *delta_g = new real_t[nV]; + real_t *delta_xFX = new real_t[nFX]; + real_t *delta_xFR = new real_t[nFR]; + real_t *delta_yAC = xiC; + real_t *delta_yFX = xiB; + + for (ii = 0; ii < nV; ++ii) + delta_g[ii] = 0.0; + delta_g[number] = 1.0; + + int_t dim = (nC>nV)?nC:nV; + real_t *nul = new real_t[dim]; + for (ii = 0; ii < dim; ++ii) + nul[ii]=0.0; + + returnValue dsdReturnValue = determineStepDirection ( + delta_g, nul, nul, nul, nul, BT_FALSE, BT_FALSE, + delta_xFX, delta_xFR, delta_yAC, delta_yFX); + if (dsdReturnValue != SUCCESSFUL_RETURN) + returnvalue = dsdReturnValue; + + /* compute the weight in inf-norm */ + real_t weight = 0.0; + for (ii = 0; ii < nAC; ++ii) + { + real_t a = getAbs (delta_yAC[ii]); + if (weight < a) weight = a; + } + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_yFX[ii]); + if (weight < a) weight = a; + } + + /* look at the "zero" in a relative inf-norm */ + real_t zero = 0.0; + for (ii = 0; ii < nFX; ++ii) + { + real_t a = getAbs (delta_xFX[ii]); + if (zero < a) zero = a; + } + for (ii = 0; ii < nFR; ++ii) + { + real_t a = getAbs (delta_xFR[ii]); + if (zero < a) zero = a; + } + + /* relative test against zero in inf-norm */ + if (zero > options.epsLITests * weight) + returnvalue = RET_LINEARLY_INDEPENDENT; + + delete[] nul; + delete[] delta_xFR; + delete[] delta_xFX; + delete[] delta_g; + + } + return THROWINFO( returnvalue ); +} + + +/* + * a d d B o u n d _ e n s u r e L I + */ +returnValue SQProblemSchur::addBound_ensureLI( int_t number, SubjectToStatus B_status ) +{ + /* Get space for the multipliers xi in linear independence test */ + int_t nAC = getNAC(); + int_t nFX = getNFX(); + real_t *xiC = new real_t[nAC]; + real_t *xiB = new real_t[nFX]; + + /* I) Check if new constraint is linearly independent from the active ones. */ + returnValue returnvalueCheckLI = addBound_checkLISchur( number, xiC, xiB ); + + if ( returnvalueCheckLI == RET_INDEXLIST_CORRUPTED ) + { + delete [] xiB; + delete [] xiC; + return THROWERROR( RET_ENSURELI_FAILED ); + } + + if ( returnvalueCheckLI == RET_LINEARLY_INDEPENDENT ) + { + delete [] xiB; + delete [] xiC; + return SUCCESSFUL_RETURN; + } + + /* II) NEW BOUND IS LINEARLY DEPENDENT: */ + /* 1) Coefficients of linear combination, have already been computed, but we need to correct the sign. */ + int_t i, ii; + + if ( B_status != ST_LOWER ) + { + for( i=0; igetNumberArray( &FX_idx ); + + int_t* AC_idx; + constraints.getActive( )->getNumberArray( &AC_idx ); + + real_t* num = new real_t[nV]; + + real_t y_min = options.maxDualJump; + int_t y_min_number = -1; + int_t y_min_number_bound = -1; + BooleanType y_min_isBound = BT_FALSE; + + returnValue returnvalue = SUCCESSFUL_RETURN; + + /* III) DETERMINE CONSTRAINT/BOUND TO BE REMOVED. */ + + /* 1) Constraints. */ + for( i=0; i= 0 ) + { + y_min_number = y_min_number_bound; + y_min_isBound = BT_TRUE; + } + + /* IV) REMOVE CONSTRAINT/BOUND FOR RESOLVING LINEAR DEPENDENCE: */ + char messageString[80]; + + if ( y_min_number >= 0 ) + { + /* Update Lagrange multiplier... */ + for( i=0; ithrowInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeBound( y_min_number,BT_TRUE,BT_FALSE,BT_FALSE ) != SUCCESSFUL_RETURN ) + { + returnvalue = RET_REMOVE_FROM_ACTIVESET_FAILED; + goto farewell; + } + tabularOutput.excRemB = 1; + + y[y_min_number] = 0.0; + } + else + { + #ifndef __XPCTARGET__ + snprintf( messageString,80,"constraint no. %d.",(int)y_min_number ); + getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE ); + #endif + + if ( removeConstraint( y_min_number,BT_TRUE,BT_FALSE,BT_FALSE ) != SUCCESSFUL_RETURN ) + { + returnvalue = RET_REMOVE_FROM_ACTIVESET_FAILED; + goto farewell; + } + tabularOutput.excRemC = 1; + + y[nV+y_min_number] = 0.0; + } + } + else + { + if (options.enableDropInfeasibles == BT_TRUE) { + /* dropping of infeasible constraints according to drop priorities */ + returnvalue = dropInfeasibles (number, B_status, BT_TRUE, xiB, xiC); + } + else + { + /* no constraint/bound can be removed => QP is infeasible! */ + returnvalue = RET_ENSURELI_FAILED_NOINDEX; + setInfeasibilityFlag( returnvalue ); + } + } + +farewell: + delete[] num; + delete[] xiB; + delete[] xiC; + + getGlobalMessageHandler( )->throwInfo( RET_LI_RESOLVED,0,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE ); + + return (returnvalue != SUCCESSFUL_RETURN) ? THROWERROR (returnvalue) : returnvalue; +} + + + +/* + * r e m o v e C o n s t r a i n t + */ +returnValue SQProblemSchur::removeConstraint( int_t number, + BooleanType updateCholesky, + BooleanType allowFlipping, + BooleanType ensureNZC + ) +{ + returnValue returnvalue = SUCCESSFUL_RETURN; + + int_t sModType = 0; + int_t idxDeleted = -1; + SubjectToStatus oldStatus; + real_t oldDet, newDet; + + /* consistency check */ + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + /* some definitions */ + int_t nAC = getNAC( ); + int_t number_idx = constraints.getActive( )->getIndex( number ); + + int_t addIdx; + BooleanType addBoundNotConstraint; + SubjectToStatus addStatus; + BooleanType exchangeHappened = BT_FALSE; + + + /* consistency checks */ + if ( constraints.getStatus( number ) == ST_INACTIVE ) + return THROWERROR( RET_CONSTRAINT_NOT_ACTIVE ); + + if ( ( number_idx < 0 ) || ( number_idx >= nAC ) ) + return THROWERROR( RET_CONSTRAINT_NOT_ACTIVE ); + + /* N) PERFORM ZERO CURVATURE TEST. */ + if (ensureNZC == BT_TRUE) + { + returnvalue = ensureNonzeroCurvature(BT_FALSE, number, exchangeHappened, addBoundNotConstraint, addIdx, addStatus); + + if (returnvalue != SUCCESSFUL_RETURN) + return returnvalue; + } + + /* save old constraint status and determinant of old S for flipping strategy */ + oldStatus = constraints.getStatus( number ); + oldDet = detS; + + /* I) UPDATE INDICES */ + tabularOutput.idxRemC = number; + if ( constraints.moveActiveToInactive( number ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVECONSTRAINT_FAILED ); + + /* Also update the Schur complement. */ + + /* First check if this constraint had been added before. In that + case delete this constraint from the Schur complement. */ + bool found = false; + for ( int_t i=0; i 0 ) + { + hessianType = HST_SEMIDEF; + + /* Restore old S */ + nS--; + + /* Flip bounds */ + tabularOutput.idxAddC = number; + tabularOutput.excAddC = 2; + switch ( oldStatus ) + { + case ST_LOWER: + constraints.moveInactiveToActive( number, ST_UPPER ); + ubA[number] = lbA[number]; + Ax_l[number] = -Ax_u[number]; + break; + case ST_UPPER: + constraints.moveInactiveToActive( number, ST_LOWER ); + lbA[number] = ubA[number]; + Ax_u[number] = -Ax_l[number]; + break; + default: + return THROWERROR( RET_REMOVECONSTRAINT_FAILED ); + } + } + else + {/* Determinants have the correct sign, compute QR of new (larger) S */ + updateSchurQR( idxDeleted ); + } + } + else if ( sModType == 2 ) + {/* Case 2: We deleted a row and column of S. */ + + /* Check if a direction of negative curvature showed up, i.e. determinants have DIFFERENT signs */ + newDet = calcDetSchur( idxDeleted ); + + if ( oldDet * newDet < 0.0 ) + { + hessianType = HST_SEMIDEF; + + /* Restore old S */ + undoDeleteFromSchurComplement( idxDeleted ); + + /* Flip bounds */ + tabularOutput.idxAddC = number; + tabularOutput.excAddC = 2; + switch ( oldStatus ) + { + case ST_LOWER: + constraints.moveInactiveToActive( number, ST_UPPER ); + ubA[number] = lbA[number]; + Ax_l[number] = -Ax_u[number]; + break; + case ST_UPPER: + constraints.moveInactiveToActive( number, ST_LOWER ); + lbA[number] = ubA[number]; + Ax_u[number] = -Ax_l[number]; + break; + default: + return THROWERROR( RET_REMOVECONSTRAINT_FAILED ); + } + } + else + {/* Determinants have the correct sign, compute QR of new (smaller) S */ + updateSchurQR( idxDeleted ); + } + } + else if ( sModType == 3 ) + {/* Case 3: S was reset. */ + + /* Check inertia of new factorization given by the sparse solver: must be ( nFR, nAC, 0 ) */ + int_t neig = sparseSolver->getNegativeEigenvalues( ); + if( neig > getNAC( ) ) // Wrong inertia! + { + /* Flip bounds and update Schur complement */ + tabularOutput.idxAddC = number; + tabularOutput.excAddC = 2; + switch ( oldStatus ) + { + case ST_LOWER: + ubA[number] = lbA[number]; + Ax_l[number] = -Ax_u[number]; + addConstraint( number, ST_UPPER, BT_TRUE, BT_FALSE ); + break; + case ST_UPPER: + lbA[number] = ubA[number]; + Ax_u[number] = -Ax_l[number]; + addConstraint( number, ST_LOWER, BT_TRUE, BT_FALSE ); + break; + default: + return THROWERROR( RET_REMOVECONSTRAINT_FAILED ); + } + } + + /* Check if flipping deleted the negative eigenvalue */ + if( correctInertia( ) ) + return THROWERROR( RET_REMOVECONSTRAINT_FAILED ); + } + else + {/* None of the three cases happened */ + return THROWERROR( RET_REMOVECONSTRAINT_FAILED ); + } + } + else + {/* No flipping strategy, update QR factorization of S */ + updateSchurQR( idxDeleted ); + } + + /* If reciprocal of condition number becomes to small, refactorize KKT matrix */ + if( rcondS < options.rcondSMin ) + { + returnValue retval = resetSchurComplement( BT_TRUE ); + if ( retval != SUCCESSFUL_RETURN ) + { + if ( retval == RET_KKT_MATRIX_SINGULAR && options.printLevel == PL_HIGH ) + MyPrintf( "In removeConstraint: KKT matrix singular when resetting Schur complement\n" ); + else if ( options.printLevel == PL_HIGH ) + MyPrintf( "In removeConstraint, resetSchurComplement failed with retval = %d\n", retval); + return THROWERROR( RET_ADDCONSTRAINT_FAILED ); + } + } + + if ( exchangeHappened == BT_TRUE ) + { + /* add bound or constraint */ + + if ( addBoundNotConstraint ) + { + addBound(addIdx, addStatus, BT_TRUE, BT_FALSE); + tabularOutput.excAddB = 1; + } + else + { + addConstraint(addIdx, addStatus, BT_TRUE, BT_FALSE); + tabularOutput.excAddC = 1; + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * r e m o v e B o u n d + */ +returnValue SQProblemSchur::removeBound( int_t number, + BooleanType updateCholesky, + BooleanType allowFlipping, + BooleanType ensureNZC + ) +{ + returnValue returnvalue = SUCCESSFUL_RETURN; + int_t addIdx; + BooleanType addBoundNotConstraint; + SubjectToStatus addStatus; + BooleanType exchangeHappened = BT_FALSE; + + int_t sModType = 0; + int_t idxDeleted = -1; + SubjectToStatus oldStatus; + real_t oldDet, newDet; + + /* consistency checks */ + if ( bounds.getStatus( number ) == ST_INACTIVE ) + return THROWERROR( RET_BOUND_NOT_ACTIVE ); + + if ( ( getStatus( ) == QPS_NOTINITIALISED ) || + ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) || + ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) || + ( getStatus( ) == QPS_SOLVED ) ) + { + return THROWERROR( RET_UNKNOWN_BUG ); + } + + /* N) PERFORM ZERO CURVATURE TEST. */ + if (ensureNZC == BT_TRUE) + { + returnvalue = ensureNonzeroCurvature(BT_TRUE, number, exchangeHappened, addBoundNotConstraint, addIdx, addStatus); + + if (returnvalue != SUCCESSFUL_RETURN) + return returnvalue; + } + + /* save old bound status and determinant of old S for flipping strategy */ + oldStatus = bounds.getStatus( number ); + oldDet = detS; + + /* I) UPDATE INDICES */ + tabularOutput.idxRemB = number; + if ( bounds.moveFixedToFree( number ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVEBOUND_FAILED ); + + /* Also update the Schur complement. */ + + /* First check if this variable had been fixed before. In that + case delete this variable from the Schur complement. */ + bool found = false; + for ( int_t i=0; igetSparseSubmatrix( iLength, iNumber, 1, &number, 0, 0, numNonzeros, irn, jcn, vals ); + + for ( int_t i=0; igetSparseSubmatrix( iLength, iNumber, 1, &number, 0, 0, numNonzeros, irn, jcn, vals ); + + for ( int_t i=0; i 0.0 ) + { + hessianType = HST_SEMIDEF; + + /* Restore old S */ + nS--; + + /* Flip bounds */ + tabularOutput.idxAddB = number; + tabularOutput.excAddB = 2; + switch ( oldStatus ) + { + case ST_LOWER: + bounds.moveFreeToFixed( number, ST_UPPER ); + ub[number] = lb[number]; + break; + case ST_UPPER: + bounds.moveFreeToFixed( number, ST_LOWER ); + lb[number] = ub[number]; + break; + default: + return THROWERROR( RET_MOVING_BOUND_FAILED ); + } + } + else + {/* Determinants have the correct sign, compute QR of new (larger) S */ + updateSchurQR( idxDeleted ); + } + } + else if ( sModType == 2 ) + {/* Case 2: We deleted a row and column of S. */ + + /* Check if a direction of negative curvature showed up, i.e. determinants have DIFFERENT signs */ + newDet = calcDetSchur( idxDeleted ); + + if ( oldDet * newDet < 0.0 ) + { + hessianType = HST_SEMIDEF; + + /* Restore old S */ + undoDeleteFromSchurComplement( idxDeleted ); + + /* Flip bounds */ + tabularOutput.idxAddB = number; + tabularOutput.excAddB = 2; + switch ( oldStatus ) + { + case ST_LOWER: + bounds.moveFreeToFixed( number, ST_UPPER ); + ub[number] = lb[number]; + break; + case ST_UPPER: + bounds.moveFreeToFixed( number, ST_LOWER ); + lb[number] = ub[number]; + break; + default: + return THROWERROR( RET_MOVING_BOUND_FAILED ); + } + } + else + {/* Determinants have the correct sign, compute QR of new (smaller) S */ + updateSchurQR( idxDeleted ); + } + } + else if ( sModType == 3 ) + {/* Case 3: S was reset. */ + + /* Check inertia of new factorization given by the sparse solver: must be ( nFR, nAC, 0 ) */ + int_t neig = sparseSolver->getNegativeEigenvalues( ); + if( neig > getNAC( ) ) // Wrong inertia, flip bounds! + { + /* Flip bounds and update Schur complement */ + tabularOutput.idxAddB = number; + tabularOutput.excAddB = 2; + switch ( oldStatus ) + { + case ST_LOWER: + ub[number] = lb[number]; + addBound( number, ST_UPPER, BT_TRUE, BT_FALSE ); + break; + case ST_UPPER: + lb[number] = ub[number]; + addBound( number, ST_LOWER, BT_TRUE, BT_FALSE ); + break; + default: + return THROWERROR( RET_MOVING_BOUND_FAILED ); + } + } + + /* Check if flipping deleted the negative eigenvalue */ + if( correctInertia( ) ) + return THROWERROR( RET_REMOVEBOUND_FAILED ); + } + else + {/* None of the three cases happened */ + return THROWERROR( RET_REMOVEBOUND_FAILED ); + } + } + else + {/* No flipping strategy, update QR factorization of S */ + updateSchurQR( idxDeleted ); + } + + /* If reciprocal of condition number becomes to small, refactorize KKT matrix */ + if( rcondS < options.rcondSMin ) + { + returnValue retval = resetSchurComplement( BT_TRUE ); + if ( retval != SUCCESSFUL_RETURN ) + { + if ( retval == RET_KKT_MATRIX_SINGULAR && options.printLevel == PL_HIGH ) + MyPrintf( "In removeBound: KKT matrix singular when resetting Schur complement\n" ); + else if ( options.printLevel == PL_HIGH ) + MyPrintf( "In removeBound, resetSchurComplement failed with retval = %d\n", retval); + return THROWERROR( RET_ADDCONSTRAINT_FAILED ); + } + } + + if ( exchangeHappened == BT_TRUE ) + { + /* add bound or constraint */ + + if ( addBoundNotConstraint ) + { + addBound(addIdx, addStatus, BT_TRUE, BT_FALSE); + tabularOutput.excAddB = 1; + } + else + { + addConstraint(addIdx, addStatus, BT_TRUE, BT_FALSE); + tabularOutput.excAddC = 1; + } + } + + return SUCCESSFUL_RETURN; +} + + +/* + * s e t u p T Q f a c t o r i s a t i o n + */ +returnValue SQProblemSchur::backsolveT( const real_t* const b, BooleanType transposed, real_t* const a ) const +{ + return THROWERROR( RET_UNKNOWN_BUG ); +} + + +/* + * b a c k s o l v e R + */ +returnValue SQProblemSchur::backsolveR( const real_t* const b, BooleanType transposed, real_t* const a ) const +{ + return THROWERROR( RET_UNKNOWN_BUG ); +} + + +/* + * b a c k s o l v e R + */ +returnValue SQProblemSchur::backsolveR( const real_t* const b, BooleanType transposed, BooleanType removingBound, real_t* const a ) const +{ + return THROWERROR( RET_UNKNOWN_BUG ); +} + + +/* + * c a l c D e t S c h u r + */ +real_t SQProblemSchur::calcDetSchur( int_t idxDel ) +{ + if ( nS <= 0 ) + return 1.0; + + real_t newDet; + int_t i, j; + real_t c, s, nu; + + /* Case 1: S has been bordered by one row and column */ + if( idxDel < 0 ) + { + /* Do a solve with the old S to check determinant of new (bordered) S */ + real_t *temp1 = new real_t[nS-1]; + real_t *temp2 = new real_t[nS-1]; + for( i=0; i0; i-- ) + { + computeGivens( tempColQ[nS], tempColQ[i-1], tempColQ[nS], tempColQ[i-1], c, s ); + nu = s/(1.0+c); + + /* Simultaneously transform diagonal elements of R (coldim is already one less than Q) */ + applyGivens( c, s, nu, tempR[nS+(i-1)*dim], tempR[(i-1)+(i-1)*dim], tempR[nS+(i-1)*dim], tempR[(i-1)+(i-1)*dim] ); + } + + /* Note that we implicitly did a row permutation of Q. + * If we did an odd permutation AND deleted a positive unity vector or + * if we did an even permutation AND deleted a negative unity vector, then det(Q)=-1 + * ->Change signs of first column of Q and first row of R */ + if ( (( (nS - idxDel) % 2 == 1 ) && ( tempColQ[nS] > 0.0 )) || + (( (nS - idxDel) % 2 == 0 ) && ( tempColQ[nS] < 0.0 )) ) + { + tempR[0] = -tempR[0]; + } + + newDet = 1.0; + //for( i=0; i0; i-- ) + { + computeGivens( Q_[nS+nS*nSmax], Q_[nS+(i-1)*nSmax], Q_[nS+nS*nSmax], Q_[nS+(i-1)*nSmax], c, s ); + nu = s/(1.0+c); + for ( j=0; jChange signs of first column of Q and first row of R s.t. we always maintain det(Q)=1 */ + if ( (( (nS - idxDel) % 2 == 1 ) && ( Q_[nS+nS*nSmax] > 0.0 )) || + (( (nS - idxDel) % 2 == 0 ) && ( Q_[nS+nS*nSmax] < 0.0 )) ) + { + for ( i=0; i 1 ) + { + MyPrintf("backsolve not implemented for dimRhs = %d\n", dimRhs); + return RET_QR_FACTORISATION_FAILED; + } + + int_t i, j; + long INFO = 0; + unsigned long NRHS = 1; + unsigned long M = (unsigned long)dimS; + unsigned long LDA = (unsigned long)nSmax; + unsigned long LDC = (unsigned long)dimS; + + for( i=0; itimes(bounds.getFree(), bounds.getFixed(), 1, 1.0, delta_xFX, nFX, 1.0, tempA, nFR); + } + /* tempB becomes RHS for reduced augmented system, bA-A_CX*delta_xFR */ + A->times(constraints.getActive(), bounds.getFixed(), 1, -1.0, delta_xFX, nFX, 1.0, tempB, nAC); + + /* If iterative refinement is requested, compute max-norm of RHS for termination test. */ + rhs_max = 0.0; + if ( options.numRefinementSteps > 0 ) + { + for ( i=0; isolve(dim, rhs, sol); + + // for (int i = 0; i < dim; i++) + // printf("sol[%i] = %f\n", i, sol[i]); + + if (retval != SUCCESSFUL_RETURN) + { + MyPrintf( "sparseSolver->solve (second time) failed.\n"); + return THROWERROR(RET_MATRIX_FACTORISATION_FAILED); // TODO: Different return code + } + + /* Transfer extra compoments of the Schur complement solution to the correct place. */ + for ( ii=0; iitimes(bounds.getFree(), bounds.getFree(), 1, 1.0, delta_xFR, nFR, 1.0, tempA, nFR); + H->times(bounds.getFree(), bounds.getFixed(), 1, 1.0, delta_xFX, nFX, 1.0, tempA, nFR); + break; + } + + for ( i=0; itransTimes(constraints.getActive(), bounds.getFree(), 1, -1.0, delta_yAC, nAC, 1.0, tempA, nFR); + rnrm = 0.0; + for ( i=0; itimes(constraints.getActive(), bounds.getFree(), 1, -1.0, delta_xFR, nFR, 1.0, tempB, nAC); + + A->times(constraints.getActive(), bounds.getFixed(), 1, -1.0, delta_xFX, nFX, 1.0, tempB, nAC); + for ( i=0; itransTimes(constraints.getActive(), bounds.getFixed(), 1, -1.0, delta_yAC, nAC, 1.0, delta_yFX, nFX); + + if ( hessianType == HST_ZERO ) + { + // TODO: if ( usingRegularisation( ) == BT_TRUE ) + for( i=0; itimes(bounds.getFixed(), bounds.getFree(), 1, 1.0, delta_xFR, nFR, 1.0, delta_yFX, nFX); + H->times(bounds.getFixed(), bounds.getFixed(), 1, 1.0, delta_xFX, nFX, 1.0, delta_yFX, nFX); + } + return SUCCESSFUL_RETURN; +} + +returnValue SQProblemSchur::determineStepDirection( const real_t* const delta_g, const real_t* const delta_lbA, const real_t* const delta_ubA, + const real_t* const delta_lb, const real_t* const delta_ub, + BooleanType Delta_bC_isZero, BooleanType Delta_bB_isZero, + real_t* const delta_xFX, real_t* const delta_xFR, + real_t* const delta_yAC, real_t* const delta_yFX + ) +{ + returnValue retval = determineStepDirection2( delta_g, delta_lbA, delta_ubA, delta_lb, delta_ub, + Delta_bC_isZero, Delta_bB_isZero, delta_xFX, delta_xFR, + delta_yAC, delta_yFX + ); + + if ( retval == RET_QR_FACTORISATION_FAILED ) + { + retval = resetSchurComplement( BT_FALSE ); + if (retval != SUCCESSFUL_RETURN) + { + MyPrintf( "In SQProblem::determineStepDirection, resetSchurComplement returns %d\n", retval); + return THROWERROR( retval ); + } + retval = determineStepDirection2( delta_g, delta_lbA, delta_ubA, delta_lb, delta_ub, + Delta_bC_isZero, Delta_bB_isZero, delta_xFX, delta_xFR, + delta_yAC, delta_yFX + ); + } + return retval; +} + +/* + * d e t e r m i n e S t e p D i r e c t i o n + */ +returnValue SQProblemSchur::determineStepDirection2( const real_t* const delta_g, const real_t* const delta_lbA, const real_t* const delta_ubA, + const real_t* const delta_lb, const real_t* const delta_ub, + BooleanType Delta_bC_isZero, BooleanType Delta_bB_isZero, + real_t* const delta_xFX, real_t* const delta_xFR, + real_t* const delta_yAC, real_t* const delta_yFX + ) +{ + /* The linear system to be solved here is this: + + / H_FF H_FX A_CF^T 0 \ / delta_xFR \ / -delta_g_F \ + | H_XF H_XX A_CX^T I | | delta_xFX | | -delta_g_X | + | A_CF A_CX 0 0 | | -delta_yAC | = | delta_bA | <-- active entries of delta_lbA and delta_ubA with corresponding sign + \ 0 I 0 0 / \ -delta_yFX / \ delta_bX / <-- fixed entries of delta_lb and delta_ub with corresponding sign + + */ + + + int_t i, ii, r; + + returnValue retval; + + //int_t nV = getNV( ); + int_t nFR = getNFR( ); + int_t nFX = getNFX( ); + int_t nAC = getNAC( ); + + int_t* FR_idx; + int_t* FX_idx; + int_t* AC_idx; + + bounds.getFree( )->getNumberArray( &FR_idx ); + bounds.getFixed( )->getNumberArray( &FX_idx ); + constraints.getActive( )->getNumberArray( &AC_idx ); + + + /* I) DETERMINE delta_xFX (this is exact, does not need refinement) */ + if ( Delta_bB_isZero == BT_FALSE ) + { + for( i=0; i0 ) { + real_t rhs_max = 0.0; + retval = stepCalcRhs( nFR, nFX, nAC, FR_idx, FX_idx, AC_idx, rhs_max, delta_g, delta_lbA, delta_ubA, + delta_lb, delta_ub, Delta_bC_isZero, Delta_bB_isZero, delta_xFX, delta_xFR, + delta_yAC, delta_yFX ); + + if (retval != SUCCESSFUL_RETURN) + return retval; + int_t nFRStart = boundsFreeStart.getLength(); + int_t nACStart = constraintsActiveStart.getLength(); + + int_t* FR_iSort; + int_t* AC_iSort; + bounds.getFree( )->getISortArray( &FR_iSort ); + constraints.getActive( )->getISortArray( &AC_iSort ); + + int_t* FR_idxStart; + int_t* AC_idxStart; + boundsFreeStart.getNumberArray( &FR_idxStart ); + constraintsActiveStart.getNumberArray( &AC_idxStart ); + + int_t* FR_iSortStart; + int_t* AC_iSortStart; + boundsFreeStart.getISortArray( &FR_iSortStart ); + constraintsActiveStart.getISortArray( &AC_iSortStart ); + + int_t dim = nFRStart + nACStart; + real_t* rhs = new real_t[dim]; + real_t* sol = new real_t[dim]; + + /* Iterative refinement loop for delta_xFR, delta_yAC */ + for ( r=0; r<=options.numRefinementSteps; ++r ) + { + retval = stepCalcReorder(nFR, nAC, FR_idx, AC_idx, nFRStart, nACStart, FR_idxStart, AC_idxStart, FR_iSort, FR_iSortStart, AC_iSort, AC_iSortStart, rhs); + if (retval != SUCCESSFUL_RETURN) + return retval; + + retval = sparseSolver->solve(dim, rhs, sol); + + if (retval != SUCCESSFUL_RETURN) + { + MyPrintf( "sparseSolver->solve (first time) failed.\n"); + return THROWERROR(RET_MATRIX_FACTORISATION_FAILED); // TODO: Different return code + } + + if ( nS > 0 ) + { + retval = stepCalcBacksolveSchur( nFR, nFX, nAC, FR_idx, FX_idx, AC_idx, dim, rhs, sol ); + if (retval != SUCCESSFUL_RETURN) + return retval; + } + + /* Transfer Schur complement solution for the free variables to the correct places */ + retval = stepCalcReorder2(nFR, nAC, FR_idx, AC_idx, nFRStart, nACStart, FR_idxStart, AC_idxStart, FR_iSort, FR_iSortStart, AC_iSort, AC_iSortStart, sol, delta_xFR, delta_yAC); + if (retval != SUCCESSFUL_RETURN) + return retval; + + if ( r < options.numRefinementSteps ) // TODO: use "<" to avoid computation in last round + { + real_t rnrm; + retval = stepCalcResid(nFR, nFX, nAC, FR_idx, FX_idx, AC_idx, Delta_bC_isZero, delta_xFX, delta_xFR, delta_yAC, delta_g, delta_lbA, delta_ubA, rnrm); + if (retval != SUCCESSFUL_RETURN) + return retval; + + /* early termination of residual norm small enough */ + if ( options.printLevel == PL_HIGH ) + MyPrintf( "In iterative refinement (iter %d) rnrm = %e and epsIterRef*rhs_max = %e.\n", r, rnrm, options.epsIterRef*rhs_max); + + if ( rnrm <= options.epsIterRef*rhs_max ) + break; + } + + } + + delete [] sol; + delete [] rhs; + } + + /* IV) DETERMINE delta_yFX */ + if ( nFX > 0 ) + { + retval = stepCalcDeltayFx(nFR, nFX, nAC, FX_idx, delta_g, delta_xFX, delta_xFR, delta_yAC, delta_yFX); + if (retval != SUCCESSFUL_RETURN) + return retval; + } + + return SUCCESSFUL_RETURN; +} + +returnValue SQProblemSchur::resetSchurComplement( BooleanType allowInertiaCorrection ) +{ + int_t j; + int_t nFR = getNFR( ); + int_t nAC = getNAC( ); + + if ( options.printLevel == PL_HIGH ) + MyPrintf( "Resetting Schur complement.\n"); + + nS = 0; + detS = 1.0; + rcondS = 1.0; + boundsFreeStart = *bounds.getFree(); + constraintsActiveStart = *constraints.getActive(); + + if ( nSmax > 0 ) + M_jc[0] = 0; + + int_t dim = nFR+nAC; + // Count the number of nonzeros + int_t numNonzeros; + switch ( hessianType ) + { + case HST_ZERO: + numNonzeros = 0; + break; + + case HST_IDENTITY: + numNonzeros = nFR; + break; + + default: + H->getSparseSubmatrix( bounds.getFree(), bounds.getFree(), 1, 1, numNonzeros, 0, 0, 0, BT_TRUE); + break; + } + // TODO: For now, we regularize every time + if (options.epsRegularisation > 0.0) + numNonzeros += nFR; + + int_t numNonzerosA; + + if ( constraintProduct != 0 ) + { + MyPrintf( "In SQProblemSchur::determineStepDirection, constraintProduct not yet implemented.\n"); + return THROWERROR(RET_NOT_YET_IMPLEMENTED); + } + A->getSparseSubmatrix( constraints.getActive(), bounds.getFree(), nFR+1, 1, numNonzerosA, 0, 0, 0, BT_FALSE); + numNonzeros += numNonzerosA; + + // Get the values + real_t* avals = new real_t[numNonzeros]; + int_t* irn = new int_t[numNonzeros]; + int_t* jcn = new int_t[numNonzeros]; + numNonzeros = 0; + switch ( hessianType ) + { + case HST_ZERO: + break; + + case HST_IDENTITY: + numNonzeros += nFR; + for (j = 0; jgetSparseSubmatrix( bounds.getFree(), bounds.getFree(), 1, 1, numNonzeros, irn, jcn, avals, BT_TRUE); + break; + } + + // For now, we regularize every time + if (options.epsRegularisation > 0.0) + { + for (j = 0; jgetSparseSubmatrix( constraints.getActive(), bounds.getFree(), nFR+1, 1, numNonzerosA, irn+numNonzeros, jcn+numNonzeros, avals+numNonzeros, BT_FALSE); + numNonzeros += numNonzerosA; + + // Call the linear solver + sparseSolver->reset(); + returnValue retval = sparseSolver->setMatrixData(dim, numNonzeros, irn, jcn, avals); + delete [] jcn; + delete [] irn; + delete [] avals; + + if (retval != SUCCESSFUL_RETURN) + return THROWERROR(RET_NO_SPARSE_SOLVER); + + // Factorize the matrix for later backsolves + retval = sparseSolver->factorize(); + numFactorizations++; + + // If matrix is singular, add bounds/remove constraints according to zero pivots + if (retval == RET_KKT_MATRIX_SINGULAR) + { + if( repairSingularWorkingSet( ) == SUCCESSFUL_RETURN ) + return resetSchurComplement( allowInertiaCorrection ); + else + return RET_KKT_MATRIX_SINGULAR; + } + + // If matrix has wrong inertia, add bounds until inertia is correct + if (retval == SUCCESSFUL_RETURN && allowInertiaCorrection) + { + int_t neig = sparseSolver->getNegativeEigenvalues( ); + if( neig > getNAC( ) ) + { + if ( options.printLevel == PL_HIGH ) + MyPrintf( "WARNING: After new factorization, reduced Hessian has %i negative eigenvalues, should be %i.\n", neig, getNAC( ) ); + + retval = correctInertia(); + } + } + + if (retval != SUCCESSFUL_RETURN) + return THROWERROR(RET_MATRIX_FACTORISATION_FAILED); + + nS = 0; + + return SUCCESSFUL_RETURN; +} + +returnValue SQProblemSchur::computeMTimes( real_t alpha, const real_t* const x_, real_t beta, real_t* const y_ ) +{ + if ( isEqual( alpha, -1.0 ) == BT_FALSE || isEqual( beta, 1.0 ) == BT_FALSE ) + return THROWERROR(RET_NOT_YET_IMPLEMENTED); + + int_t i, j; + + for ( j=0; jsolve(dim, rhs, sol); + if (retval != SUCCESSFUL_RETURN) + { + MyPrintf( "sparseSolver->solve in SQProblemSchur::addToSchurComplement failed.\n"); + return THROWERROR(RET_MATRIX_FACTORISATION_FAILED); // TODO: Different return code + } + + computeMTransTimes(1.0, sol, 0.0, new_Scol); + + /* Take care of off-diagonal elements in N. */ + for ( i=0; iidx of S by one to the upper left */ + for ( int_t i=0; iidx one to the left */ + for ( int_t i=M_jc[idx+1]; iidx of S by one to the lower right */ + for ( int_t i=idx-1; i>-1; i-- ) + for ( int_t j=nS-1; j>idx-1; j-- ) + S[(j+1)+i*nSmax] = S[j+i*nSmax]; + for ( int_t i=nS-1; i>idx-1; i-- ) + { + for ( int_t j=idx-1; j>-1; j-- ) + S[j+(i+1)*nSmax] = S[j+i*nSmax]; + for ( int_t j=nS-1; j>idx-1; j-- ) + S[(j+1)+(i+1)*nSmax] = S[j+i*nSmax]; + } + for ( int_t i=nS-1; i>idx-1; i-- ) + { + schurUpdateIndex[i+1] = schurUpdateIndex[i]; + schurUpdate[i+1] = schurUpdate[i]; + } + + /* Insert stored row/column of S at position idx */ + for ( int_t i=0; iidx one to the right */ + for ( int_t i=M_jc[nS]-1; i>M_jc[idx]-1; i-- ) + { + M_ir[i+numEntries] = M_ir[i]; + M_vals[i+numEntries] = M_vals[i]; + } + for ( int_t i=nS; i>idx-1; i-- ) + M_jc[i+1] = M_jc[i] + numEntries; + + /* Insert stored column of M at position idx */ + for ( int_t i=M_jc[idx]; igetNegativeEigenvalues( ); + + /* if a bound flipped, check if it did in fact remove a negative eigenvalue */ + if( nS == 1 && detS < 0 ) + neig--; + + /* if this method is triggered after flipping bounds, inertia is now probably correct */ + if( neig == getNAC( ) ) + return SUCCESSFUL_RETURN; + + /* get bound numbers in the order in which they are in the non-basis */ + bounds.getFree()->getNumberArray( &numberarray ); + for( k=0; k getNAC( ) && k < nFR ) + { + oldDetS = detS; + + /* If it's linearly independent, fix the next free variable at the nearest bound */ + number = freeBoundIdx[k]; + if( addBound_checkLI( number ) == RET_LINEARLY_INDEPENDENT ) + { + /* This is just heuristics: we need the bound which gives correct multiplier sign */ + if ( x[number] - lb[number] < ub[number] - x[number] ) + B_status = ST_LOWER; + else + B_status = ST_UPPER; + + /* Update Schur complement */ + if( addBound( number, B_status, BT_TRUE, BT_FALSE ) != SUCCESSFUL_RETURN ) + { + if ( options.printLevel == PL_HIGH ) + MyPrintf("In correctInertia: Adding bound[%i] = %i failed!\n", k, number ); + return THROWERROR( RET_INERTIA_CORRECTION_FAILED ); + } + + /* Adjust bounds */ + if ( B_status == ST_LOWER ) + lb[number] = x[number]; + else + ub[number] = x[number]; + } + else + { + if ( options.printLevel == PL_HIGH ) + MyPrintf("bound[%i] = %i is linearly dependent. Do not add.\n", k, number ); + k++; + continue; + } + + /* Case 1: Schur complement has been reset, check inertia of new factorization */ + if( nS == 0 ) + neig = sparseSolver->getNegativeEigenvalues( ); + /* Case 2: Schur complement has grown, check if determinant changed sign */ + else if( oldDetS * detS < 0 ) + neig--; + /* NB: Case 3: (Schur complement has shrunk) cannot happen here: + * This method is called after a factorization reset or after ONE bound has been added */ + + k++; + } + nAdded -= getNFR( ); + + delete[] freeBoundIdx; + + /* if there are still too many negative eigenvalues, exit */ + if( neig > getNAC( ) ) + { + if ( options.printLevel == PL_HIGH ) + MyPrintf( "Added %i bounds but KKT matrix still has %i negative eigenvalues, should be %i.\n", nAdded, neig, getNAC( ) ); + return THROWERROR( RET_INERTIA_CORRECTION_FAILED ); + } + else + { + if ( options.printLevel == PL_HIGH ) + MyPrintf( "After adding %i bounds, reduced Hessian has correct inertia.\n", nAdded, neig ); + return SUCCESSFUL_RETURN; + } +} + + +returnValue SQProblemSchur::repairSingularWorkingSet( ) +{ + int_t k, number; + SubjectToStatus B_status; + int_t rank = sparseSolver->getRank( ); + int_t nFR = getNFR( ); + int_t defect = nFR + getNAC( ) - rank; + + /* Rank detection not supported by linear solver */ + if ( rank < 0 ) + return RET_KKT_MATRIX_SINGULAR; + + /* Consistency check */ + if ( defect <= 0 ) + return RET_UNKNOWN_BUG; + + /* Determine zero pivots */ + int_t *zeroPivots = new int_t[defect]; + sparseSolver->getZeroPivots( zeroPivots ); + + /* Determination of zero pivots not supported by linear solver */ + if ( zeroPivots == 0 ) + return RET_KKT_MATRIX_SINGULAR; + + /* We assume implicitly that pivots are sorted in ascending order */ + /// \todo make sure that this is so. + /* Remove the one with the highest index first so not to mess up index lists */ + int_t bndsAdded = 0; + for ( k=defect-1; k>-1; k-- ) + { + /* Zero curvature in the Hessian: add a bound */ + if ( zeroPivots[k] < nFR ) + { + number = bounds.getFree()->getNumber( zeroPivots[k] ); + + if ( options.printLevel == PL_HIGH ) + MyPrintf( "WARNING: KKT matrix singular! Add bound %i before refactorization.\n", number); + + /* This is just heuristics: we need the bound which gives correct multiplier sign */ + if ( x[number] - lb[number] < ub[number] - x[number] ) + B_status = ST_LOWER; + else + B_status = ST_UPPER; + + /* Here we do not need to update the Schur complement because KKT matrix is factorized afterwards */ + if ( bounds.moveFreeToFixed( number, B_status ) != SUCCESSFUL_RETURN ) + return RET_ADDBOUND_FAILED; + + /* Adjust bounds */ + if ( B_status == ST_LOWER ) + lb[number] = x[number]; + else + ub[number] = x[number]; + + bndsAdded++; + } + /* Linearly dependent row in the Jacobian: remove a constraint */ + else + { + number = constraints.getActive()->getNumber( zeroPivots[k]-nFR ); + if ( options.printLevel == PL_HIGH ) + MyPrintf( "WARNING: KKT matrix singular! Removing constraint %i before refactorization.\n", number); + + if ( constraints.moveActiveToInactive( number ) != SUCCESSFUL_RETURN ) + return RET_REMOVECONSTRAINT_FAILED; + + // AW: If this is an equality constraint, it is now inactive and + // will not be considered in the step computation which leads to + // violation of that constraint in the future. Here, I try to + // fix this by simply making this constraint no longer an + // equality. + // TODO: This is probably also necessary for bound constraints + if ( constraints.getType(number) == ST_EQUALITY ) + { + if ( options.printLevel == PL_HIGH ) + MyPrintf( "WARNING: Making this constraint no longer an equality.\n"); + constraints.setType( number, ST_BOUNDED ); + } + + /* Adjust dual variable */ + y[number] = 0.0; + } + } + + if ( options.printLevel == PL_HIGH ) + MyPrintf( "WARNING: KKT matrix singular! Removed %i constraints and added %i bounds before refactorization.\n", + defect-bndsAdded, bndsAdded ); + + delete[] zeroPivots; + + return SUCCESSFUL_RETURN; +} + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/SolutionAnalysis.cpp b/locomotion/src/third_party/qpOASES/src/SolutionAnalysis.cpp new file mode 100644 index 0000000..66d0fd1 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/SolutionAnalysis.cpp @@ -0,0 +1,681 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/SolutionAnalysis.cpp + * \author Hans Joachim Ferreau (thanks to Boris Houska) + * \version 3.2 + * \date 2008-2017 + * + * Implementation of the SolutionAnalysis class designed to perform + * additional analysis after solving a QP with qpOASES. + * + */ + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * S o l u t i o n A n a l y s i s + */ +SolutionAnalysis::SolutionAnalysis( ) +{ + +} + + +/* + * S o l u t i o n A n a l y s i s + */ +SolutionAnalysis::SolutionAnalysis( const SolutionAnalysis& rhs ) +{ + +} + + +/* + * ~ S o l u t i o n A n a l y s i s + */ +SolutionAnalysis::~SolutionAnalysis( ) +{ + +} + + +/* + * o p e r a t o r = + */ +SolutionAnalysis& SolutionAnalysis::operator=( const SolutionAnalysis& rhs ) +{ + if ( this != &rhs ) + { + + } + + return *this; +} + + + +/* + * g e t K k t V i o l a t i o n + */ +real_t SolutionAnalysis::getKktViolation( QProblemB* const qp, + real_t* const maxStat, real_t* const maxFeas, real_t* const maxCmpl + ) const +{ + int_t i; + int_t nV = qp->getNV(); + + if ( qp == 0 ) + return INFTY; + + /* setup Hessian matrix array (or pass NULL pointer) */ + real_t* H_ptr = 0; + BooleanType hasIdentityHessian = BT_FALSE; + + switch( qp->getHessianType() ) + { + case HST_ZERO: + break; + + case HST_IDENTITY: + hasIdentityHessian = BT_TRUE; + break; + + default: + H_ptr = qp->H->full(); + if ( qp->usingRegularisation() == BT_TRUE ) + for( i=0; iregVal; + } + + real_t* workingSetB = new real_t[nV]; + qp->getWorkingSetBounds( workingSetB ); + + /* determine maximum KKT violation */ + real_t maxKktViolation=0.0, stat=0.0, feas=0.0, cmpl=0.0; + + returnValue returnvalue = REFER_NAMESPACE_QPOASES getKktViolation( nV, + H_ptr,qp->g, + qp->lb,qp->ub, + qp->x,qp->y, + stat,feas,cmpl, + workingSetB,hasIdentityHessian + ); + if ( workingSetB != 0 ) + delete[] workingSetB; + + if ( H_ptr != 0 ) + delete[] H_ptr; + + if ( returnvalue != SUCCESSFUL_RETURN ) + THROWERROR( returnvalue ); + + /* assign return values */ + if ( maxStat != 0 ) + *maxStat = stat; + + if ( maxFeas != 0 ) + *maxFeas = feas; + + if ( maxCmpl != 0 ) + *maxCmpl = cmpl; + + maxKktViolation = getMax( maxKktViolation,stat ); + maxKktViolation = getMax( maxKktViolation,feas ); + maxKktViolation = getMax( maxKktViolation,cmpl ); + + return maxKktViolation; +} + + +/* + * g e t K k t V i o l a t i o n + */ +real_t SolutionAnalysis::getKktViolation( QProblem* const qp, + real_t* const maxStat, real_t* const maxFeas, real_t* const maxCmpl + ) const +{ + int_t i; + int_t nV = qp->getNV(); + int_t nC = qp->getNC(); + + if ( qp == 0 ) + return INFTY; + + /* setup Hessian matrix array (or pass NULL pointer) */ + real_t* H_ptr = 0; + BooleanType hasIdentityHessian = BT_FALSE; + + switch( qp->getHessianType() ) + { + case HST_ZERO: + break; + + case HST_IDENTITY: + hasIdentityHessian = BT_TRUE; + break; + + default: + H_ptr = qp->H->full(); + if ( qp->usingRegularisation() == BT_TRUE ) + for( i=0; iregVal; + } + + /* setup constraint matrix array */ + real_t* A_ptr = qp->A->full(); + + real_t* workingSetB = new real_t[nV]; + qp->getWorkingSetBounds( workingSetB ); + + real_t* workingSetC = new real_t[nC]; + qp->getWorkingSetConstraints( workingSetC ); + + /* determine maximum KKT violation */ + real_t maxKktViolation=0.0, stat=0.0, feas=0.0, cmpl=0.0; + + returnValue returnvalue = REFER_NAMESPACE_QPOASES getKktViolation( nV,nC, + H_ptr,qp->g,A_ptr, + qp->lb,qp->ub,qp->lbA,qp->ubA, + qp->x,qp->y, + stat,feas,cmpl, + workingSetB,workingSetC,hasIdentityHessian + ); + + if ( workingSetC != 0 ) + delete[] workingSetC; + + if ( workingSetB != 0 ) + delete[] workingSetB; + + if ( A_ptr != 0 ) + delete[] A_ptr; + + if ( H_ptr != 0 ) + delete[] H_ptr; + + if ( returnvalue != SUCCESSFUL_RETURN ) + THROWERROR( returnvalue ); + + /* assign return values */ + if ( maxStat != 0 ) + *maxStat = stat; + + if ( maxFeas != 0 ) + *maxFeas = feas; + + if ( maxCmpl != 0 ) + *maxCmpl = cmpl; + + maxKktViolation = getMax( maxKktViolation,stat ); + maxKktViolation = getMax( maxKktViolation,feas ); + maxKktViolation = getMax( maxKktViolation,cmpl ); + + return maxKktViolation; +} + + +/* + * g e t K k t V i o l a t i o n + */ +real_t SolutionAnalysis::getKktViolation( SQProblem* const qp, + real_t* const maxStat, real_t* const maxFeas, real_t* const maxCmpl + ) const +{ + return getKktViolation( (QProblem*)qp, maxStat,maxFeas,maxCmpl ); +} + + + +/* + * g e t V a r i a n c e C o v a r i a n c e + */ +returnValue SolutionAnalysis::getVarianceCovariance( QProblemB* const qp, + const real_t* const g_b_bA_VAR, real_t* const Primal_Dual_VAR + ) const +{ + return THROWERROR( RET_NOT_YET_IMPLEMENTED ); +} + + +/* + * g e t V a r i a n c e C o v a r i a n c e + */ +returnValue SolutionAnalysis::getVarianceCovariance( QProblem* qp, + const real_t* const g_b_bA_VAR, real_t* const Primal_Dual_VAR + ) const +{ + + /* DEFINITION OF THE DIMENSIONS nV AND nC: + * --------------------------------------- */ + int_t nV = qp->getNV( ); /* dimension of x / the bounds */ + int_t nC = qp->getNC( ); /* dimension of the constraints */ + int_t dim = 2*nV+nC; /* dimension of input and output */ + /* variance-covariance matrix */ + int_t run1, run2, run3; /* simple run variables (for loops). */ + + + /* ALLOCATION OF MEMORY: + * --------------------- */ + real_t* delta_g_cov = new real_t[nV]; /* a covariance-vector of g */ + real_t* delta_lb_cov = new real_t[nV]; /* a covariance-vector of lb */ + real_t* delta_ub_cov = new real_t[nV]; /* a covariance-vector of ub */ + real_t* delta_lbA_cov = new real_t[nC]; /* a covariance-vector of lbA */ + real_t* delta_ubA_cov = new real_t[nC]; /* a covariance-vector of ubA */ + + returnValue returnvalue; /* the return value */ + BooleanType Delta_bC_isZero = BT_FALSE; /* (just use FALSE here) */ + BooleanType Delta_bB_isZero = BT_FALSE; /* (just use FALSE here) */ + + + + /* ASK FOR THE NUMBER OF FREE AND FIXED VARIABLES: + * (ASSUMES THAT ACTIVE SET IS CONSTANT FOR THE + * VARIANCE-COVARIANCE EVALUATION) + * ----------------------------------------------- */ + int_t nFR, nFX, nAC; + + nFR = qp->getNFR( ); + nFX = qp->getNFX( ); + nAC = qp->getNAC( ); + + + /* ASK FOR THE CORRESPONDING INDEX ARRAYS: + * --------------------------------------- */ + int_t *FR_idx, *FX_idx, *AC_idx; + + if ( qp->bounds.getFree( )->getNumberArray( &FR_idx ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_HOTSTART_FAILED ); + + if ( qp->bounds.getFixed( )->getNumberArray( &FX_idx ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_HOTSTART_FAILED ); + + if ( qp->constraints.getActive( )->getNumberArray( &AC_idx ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_HOTSTART_FAILED ); + + + + /* INTRODUCE VARIABLES TO MEASURE THE REACTION OF THE QP-SOLUTION TO + * THE VARIANCE-COVARIANCE DISTURBANCE: + * ----------------------------------------------------------------- */ + real_t *delta_xFR = new real_t[nFR]; + real_t *delta_xFX = new real_t[nFX]; + real_t *delta_yAC = new real_t[nAC]; + real_t *delta_yFX = new real_t[nFX]; + + real_t* K = new real_t[dim*dim]; /* matrix to store */ + /* an intermediate */ + /* result. */ + + /* SOME INITIALIZATIONS: + * --------------------- */ + for( run1 = 0; run1 < dim*dim; run1++ ){ + K [run1] = 0.0; + Primal_Dual_VAR[run1] = 0.0; + } + + + /* ================================================================= */ + + /* FIRST MATRIX MULTIPLICATION (OBTAINS THE INTERMEDIATE RESULT + * K := [ ("ACTIVE" KKT-MATRIX OF THE QP)^(-1) * g_b_bA_VAR ]^T ) + * THE EVALUATION OF THE INVERSE OF THE KKT-MATRIX OF THE QP + * WITH RESPECT TO THE CURRENT ACTIVE SET + * USES THE EXISTING CHOLESKY AND TQ-DECOMPOSITIONS. FOR DETAILS + * cf. THE (protected) FUNCTION determineStepDirection. */ + + for( run3 = 0; run3 < dim; run3++ ){ + + + for( run1 = 0; run1 < nV; run1++ ){ + delta_g_cov [run1] = g_b_bA_VAR[run3*dim+run1]; + delta_lb_cov [run1] = g_b_bA_VAR[run3*dim+nV+run1]; /* LINE-WISE LOADING OF THE INPUT */ + delta_ub_cov [run1] = g_b_bA_VAR[run3*dim+nV+run1]; /* VARIANCE-COVARIANCE */ + } + for( run1 = 0; run1 < nC; run1++ ){ + delta_lbA_cov [run1] = g_b_bA_VAR[run3*dim+2*nV+run1]; + delta_ubA_cov [run1] = g_b_bA_VAR[run3*dim+2*nV+run1]; + } + + + /* EVALUATION OF THE STEP: + * ------------------------------------------------------------------------------ */ + + returnvalue = qp->determineStepDirection( delta_g_cov, delta_lbA_cov, delta_ubA_cov, delta_lb_cov, delta_ub_cov, + Delta_bC_isZero, Delta_bB_isZero, delta_xFX,delta_xFR, + delta_yAC,delta_yFX ); + + /* ------------------------------------------------------------------------------ */ + + + /* STOP THE ALGORITHM IN THE CASE OF NO SUCCESFUL RETURN: + * ------------------------------------------------------ */ + if ( returnvalue != SUCCESSFUL_RETURN ){ + + delete[] delta_g_cov; + delete[] delta_lb_cov; + delete[] delta_ub_cov; + delete[] delta_lbA_cov; + delete[] delta_ubA_cov; + delete[] delta_xFR; + delete[] delta_xFX; + delete[] delta_yAC; + delete[] delta_yFX; + delete[] K; + + THROWERROR( RET_STEPDIRECTION_DETERMINATION_FAILED ); + return returnvalue; + } + + + + for( run1=0; run1determineStepDirection( delta_g_cov, delta_lbA_cov, delta_ubA_cov, delta_lb_cov, delta_ub_cov, + Delta_bC_isZero, Delta_bB_isZero, delta_xFX,delta_xFR, + delta_yAC,delta_yFX); + + + /* ------------------------------------------------------------------------------ */ + + + /* STOP THE ALGORITHM IN THE CASE OF NO SUCCESFUL RETURN: + * ------------------------------------------------------ */ + if ( returnvalue != SUCCESSFUL_RETURN ){ + + delete[] delta_g_cov; + delete[] delta_lb_cov; + delete[] delta_ub_cov; + delete[] delta_lbA_cov; + delete[] delta_ubA_cov; + delete[] delta_xFR; + delete[] delta_xFX; + delete[] delta_yAC; + delete[] delta_yFX; + delete[] K; + + THROWERROR( RET_STEPDIRECTION_DETERMINATION_FAILED ); + return returnvalue; + } + + + + for( run1=0; run1getNFX( ); + nAC = qp->getNAC( ); + + // If no bounds are active reduced Hessian is positive definite (otherwise qpOASES wouldnt have finished) + if( nFX == 0 ) + return SUCCESSFUL_RETURN; + + // Get active bounds (deep copy) + qp->getBounds( saveBounds ); + saveBounds.getFixed( )->getNumberArray( &FX_idx ); + + // We have to change the status to modify the active set + saveStatus = qp->getStatus(); + qp->status = QPS_PERFORMINGHOMOTOPY; + + // If a variable is active now but has not been in the previous major iteration remove it + for( k=0; kx[FX_idx[k]]) > eps ) + if ( qp->bounds.moveFixedToFree( FX_idx[k] ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVEBOUND_FAILED ); + + // Do a new factorization and check the inertia + ret = qp->resetSchurComplement( BT_FALSE ); + neig = qp->sparseSolver->getNegativeEigenvalues( ); + if( ret == SUCCESSFUL_RETURN && neig != nAC ) + ret = RET_INERTIA_CORRECTION_FAILED; + + // Add all bounds that have been removed + for( k=0; kbounds.getStatus( FX_idx[k] ) == ST_INACTIVE ) + qp->bounds.moveFreeToFixed( FX_idx[k], saveBounds.getStatus( FX_idx[k] ) ); + + qp->status = saveStatus; + return ret; +} + + +//int_t SolutionAnalysis::checkCurvatureOnStronglyActiveConstraints( SQProblemSchur* qp ) +//{ + //real_t eps = 1.0e-16; + //real_t oldDet, newDet; + //int_t oldNS; + //returnValue ret; + //Bounds saveBounds; + //QProblemStatus saveStatus; + //int_t nFX, *FX_idx; + //int_t k, fail, neig, rmCnt, nAC; + + //// Get active bounds (deep copy) + //nFX = qp->getNFX( ); + //nAC = qp->getNAC( ); + //qp->getBounds( saveBounds ); + //saveBounds.getFixed( )->getNumberArray( &FX_idx ); + + //// If no bounds are active reduced Hessian is positive definite (otherwise qpOASES wouldnt have finished) + //if( nFX == 0 ) + //return 0; + + //// We have to modify the status to call removeBound() + //saveStatus = qp->getStatus(); + //qp->status = QPS_PERFORMINGHOMOTOPY; + + //// If a variable is active but was not active in the previous major iteration + //// remove it to see if a negative eigenvalue appears + //rmCnt = 0; + //fail = 0; + //for( k=0; kx[FX_idx[k]]) > eps ) + //{ + //oldDet = qp->detS; + //oldNS = qp->nS; + + //ret = qp->removeBound( FX_idx[k], BT_TRUE, BT_FALSE, BT_FALSE ); + //if( ret != SUCCESSFUL_RETURN ) + //{ + //fail = 1; + //break; + //} + + //newDet = qp->detS; + //rmCnt++; + + //// Case 1: S has grown by 1 row and column + //if( qp->nS == oldNS + 1 ) + //{ + //// If the determinant does not change sign, then S has gained a positive eigenvalue. + //// That means there is a negative eigenvalue in the (extended) reduced Hessian! + //if ( ( oldDet <= 0.0 && newDet <= 0.0 ) || ( oldDet >= 0.0 && newDet >= 0.0 ) ) + //{ + //fail = 1; + //break; + //} + //} + //// Case 2: S has shrunk by 1 row and column + //else if( qp->nS == oldNS - 1 ) + //{ + //// If the determinant changes sign, then S has lost a negative eigenvalue. + //// That means there is a negative eigenvalue in the (extended) reduced Hessian! + //if ( ( oldDet <= 0.0 && newDet > 0.0 ) || ( oldDet >= 0.0 && newDet < 0.0 ) ) + //{ + //fail = 1; + //break; + //} + //} + //// Case 3: S was reset + //else if( qp->nS == 0 ) + //{ + //// Check inertia of KKT matrix + //neig = qp->sparseSolver->getNegativeEigenvalues( ); + //if( neig > nAC ) + //{ + //fail = 1; + //break; + //} + //} + //else + //printf("ERROR!\n"); + //} + + //// If test is successful, add all bounds that have been removed + //// If not, don't bother with that because we will discard this QP object anyway + //if( fail == 0 ) + //for( k=0; kaddBound( FX_idx[k], saveBounds.getStatus( FX_idx[k] ), BT_TRUE, BT_FALSE ); + //if( ret != SUCCESSFUL_RETURN && ret != RET_BOUND_ALREADY_ACTIVE ) + //printf( "addBound() in checkCurvatureOnStronglyActiveConstraints(): %s\n", getGlobalMessageHandler()->getErrorCodeMessage( ret ) ); + //} + + //qp->status = saveStatus; + //return fail; +//} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/SparseSolver.cpp b/locomotion/src/third_party/qpOASES/src/SparseSolver.cpp new file mode 100644 index 0000000..c3b996a --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/SparseSolver.cpp @@ -0,0 +1,1612 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/SparseSolver.cpp + * \author Andreas Waechter, Dennis Janka + * \version 3.2 + * \date 2012-2017 + * + * Interfaces to sparse linear solvers that are used in a Schur-complement + * implementation in qpOASES. + */ + + +#include + +#ifndef __MATLAB__ +# include +void MyPrintf(const char* pformat, ... ); +#else +# include +# define MyPrintf mexPrintf +#endif + +#if SOLVER_MUMPS + +#define USE_COMM_WORLD -987654 + +#include "mumps_compat.h" + + +#ifdef USE_MPI_H +#include "mpi.h" +#else +#include "mumps_mpi.h" +#endif /* USE_MPI_H */ + +#include "dmumps_c.h" +#define MUMPS_STRUC_C DMUMPS_STRUC_C +#define mumps_c dmumps_c + +#endif /* SOLVER_MUMPS */ + +BEGIN_NAMESPACE_QPOASES + +/***************************************************************************** + * P U B L I C * + ****************************************************************************/ + +/* + * S p a r s e S o l v e r + */ +SparseSolver::SparseSolver( ) +{ +} + + +/* + * S p a r s e S o l v e r + */ +SparseSolver::SparseSolver( const SparseSolver& rhs ) +{ + copy( rhs ); +} + + +/* + * ~ S p a r s e S o l v e r + */ +SparseSolver::~SparseSolver( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +SparseSolver& SparseSolver::operator=( const SparseSolver& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + copy( rhs ); + } + + return *this; +} + +/* + * r e s e t + */ +returnValue SparseSolver::reset( ) +{ + return SUCCESSFUL_RETURN; +} + +/* + * g e t N e g a t i v e E i g e n v a l u e s + */ +int_t SparseSolver::getNegativeEigenvalues( ) +{ + return -1; +} + +/* + * g e t R a n k + */ +int_t SparseSolver::getRank( ) +{ + return -1; +} + +/* + * g e t Z e r o P i v o t s + */ +returnValue SparseSolver::getZeroPivots( int_t *&zeroPivots ) +{ + if ( zeroPivots ) delete[] zeroPivots; + zeroPivots = 0; + return SUCCESSFUL_RETURN; +} + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * c l e a r + */ +returnValue SparseSolver::clear( ) +{ + return SUCCESSFUL_RETURN; +} + + +/* + * c o p y + */ +returnValue SparseSolver::copy( const SparseSolver& rhs + ) +{ + return SUCCESSFUL_RETURN; +} + +#ifdef SOLVER_MA27 + +/***************************************************************************** + ***************************************************************************** + ***************************************************************************** + * M A 2 7 S P A R E S E S O L V E R * + ***************************************************************************** + ***************************************************************************** + *****************************************************************************/ + +#define MA27ID ma27id_ +#define MA27AD ma27ad_ +#define MA27BD ma27bd_ +#define MA27CD ma27cd_ + +extern "C" { + void MA27ID( fint_t* ICNTL, double* CNTL ); + void MA27AD( fint_t *N, fint_t *NZ, const fint_t *IRN, const fint_t* ICN, + fint_t *IW, fint_t* LIW, fint_t* IKEEP, fint_t *IW1, + fint_t* NSTEPS, fint_t* IFLAG, fint_t* ICNTL, + double* CNTL, fint_t *INFO, double* OPS); + void MA27BD( fint_t *N, fint_t *NZ, const fint_t *IRN, const fint_t* ICN, + double* A, fint_t* LA, fint_t* IW, fint_t* LIW, + fint_t* IKEEP, fint_t* NSTEPS, fint_t* MAXFRT, + fint_t* IW1, fint_t* ICNTL, double* CNTL, + fint_t* INFO); + void MA27CD( fint_t *N, double* A, fint_t* LA, fint_t* IW, + fint_t* LIW, double* W, fint_t* MAXFRT, + double* RHS, fint_t* IW1, fint_t* NSTEPS, + fint_t* ICNTL, double* CNTL); +} + +/***************************************************************************** + * P U B L I C * + ****************************************************************************/ + +/* + * M a 2 7 S p a r s e S o l v e r + */ +Ma27SparseSolver::Ma27SparseSolver( ) : SparseSolver() +{ + a_ma27 = 0; + irn_ma27 = 0; + jcn_ma27 = 0; + iw_ma27 = 0; + ikeep_ma27 = 0; + clear( ); + + /* Set default options for MA27 */ + MA27ID(icntl_ma27, cntl_ma27); + icntl_ma27[0] = 0; /* Suppress error messages */ + icntl_ma27[1] = 0; /* Suppress diagnostic messages */ + cntl_ma27[0] = 1e-8; /* Set pivot tolerance */ +} + + +/* + * M a 2 7 S p a r s e S o l v e r + */ +Ma27SparseSolver::Ma27SparseSolver( const Ma27SparseSolver& rhs ) +{ + copy( rhs ); +} + + +/* + * ~ M a 2 7 S p a r s e S o l v e r + */ +Ma27SparseSolver::~Ma27SparseSolver( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +Ma27SparseSolver& Ma27SparseSolver::operator=( const SparseSolver& rhs ) +{ + const Ma27SparseSolver* ma27_rhs = dynamic_cast(&rhs); + if (!ma27_rhs) + { + fprintf(getGlobalMessageHandler()->getOutputFile(),"Error in Ma27SparseSolver& Ma27SparseSolver::operator=( const SparseSolver& rhs )\n"); + throw; /* TODO: More elegant exit? */ + } + if ( this != ma27_rhs ) + { + clear( ); + SparseSolver::operator=( rhs ); + copy( *ma27_rhs ); + } + + return *this; +} + +/* + * s e t M a t r i x D a t a + */ +returnValue Ma27SparseSolver::setMatrixData( int_t dim_, + int_t numNonzeros_, + const int_t* const irn, + const int_t* const jcn, + const real_t* const avals + ) +{ + reset( ); + dim = dim_; + numNonzeros = numNonzeros_; + + if ( numNonzeros_ > 0 ) + { + a_ma27 = new double[numNonzeros_]; + irn_ma27 = new fint_t[numNonzeros_]; + jcn_ma27 = new fint_t[numNonzeros_]; + + numNonzeros=0; + for (int_t i=0; i= 4: PL^t P^t */ + fint_t *n, /* Order of matrix. */ + double *fact, /* Entries of factors. */ + fint_t *lfact, /* Length of array `fact'. */ + fint_t *ifact, /* Indexing info for factors. */ + fint_t *lifact, /* Length of array `ifact'. */ + fint_t *nrhs, /* Number of right hand sides. */ + double *rhs, /* Numerical Values. */ + fint_t *lrhs, /* Leading dimensions of `rhs'. */ + double *work, /* Real workspace. */ + fint_t *lwork, /* Length of `work', >= N*NRHS. */ + fint_t *iwork, /* Integer array of length `n'. */ + fint_t *icntl, /* Integer Control parameter array of length 20. */ + fint_t *info); /* Statistical Information; Integer array of length 40. */ +} + +/***************************************************************************** + * P U B L I C * + ****************************************************************************/ + + +/* + * M a 5 7 S p a r s e S o l v e r + */ +Ma57SparseSolver::Ma57SparseSolver( ) : SparseSolver() +{ + a_ma57 = 0; + irn_ma57 = 0; + jcn_ma57 = 0; + fact_ma57 = 0; + ifact_ma57 = 0; + pivots = 0; + clear( ); + + /* Set default options for MA57 */ + MA57ID( cntl_ma57, icntl_ma57 ); + + icntl_ma57[0] = -1; /* Suppress error messages */ + icntl_ma57[1] = -1; /* Suppress warning messages */ + icntl_ma57[2] = -1; /* Suppress monitoring messages */ + /*icntl_ma57[4] = 4; // Print everything (for debugging) */ + icntl_ma57[15] = 1; /* Place small pivots at the end of the factorization (default: 0) */ + + /* \todo good default values? + cntl_ma57[1] = 5.0e-16; // Pivots smaller than this are treated as zero and are placed at the end of the factorization (default: 1e-20) + cntl_ma57[0] = 0.5; // Set pivot tolerance: Higher values = more stable but slower/less sparse (default: 0.01, max 0.5) */ +} + + +/* + * M a 5 7 S p a r s e S o l v e r + */ +Ma57SparseSolver::Ma57SparseSolver( const Ma57SparseSolver& rhs ) +{ + copy( rhs ); +} + + +/* + * ~ M a 5 7 S p a r s e S o l v e r + */ +Ma57SparseSolver::~Ma57SparseSolver( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +Ma57SparseSolver& Ma57SparseSolver::operator=( const SparseSolver& rhs ) +{ + const Ma57SparseSolver* ma57_rhs = dynamic_cast(&rhs); + if (!ma57_rhs) + { + fprintf(getGlobalMessageHandler()->getOutputFile(),"Error in Ma57SparseSolver& Ma57SparseSolver::operator=( const SparseSolver& rhs )\n"); + throw; /* TODO: More elegant exit? */ + } + if ( this != ma57_rhs ) + { + clear( ); + SparseSolver::operator=( rhs ); + copy( *ma57_rhs ); + } + + return *this; +} + +/* + * s e t M a t r i x D a t a + */ +returnValue Ma57SparseSolver::setMatrixData( int_t dim_, + int_t numNonzeros_, + const int_t* const irn, + const int_t* const jcn, + const real_t* const avals + ) +{ + reset( ); + dim = dim_; + numNonzeros = numNonzeros_; + + if ( numNonzeros_ > 0 ) + { + a_ma57 = new double[numNonzeros_]; + irn_ma57 = new fint_t[numNonzeros_]; + jcn_ma57 = new fint_t[numNonzeros_]; + + numNonzeros=0; + for (int_t i=0; i dim ? numNonzeros : dim; + fint_t lkeep_ma57 = 5*dim + numNonzeros + max_nnz + 42; + fint_t *keep_ma57 = new fint_t[lkeep_ma57]; + fint_t *iwork_ma57 = new fint_t[5*dim]; + + /* Set initial pivot sequence. */ + for (fint_t i = 0; i < lkeep_ma57; i++) keep_ma57[i] = i+1; + + fint_t info_ma57[40]; + double rinfo_ma57[20]; + + MA57AD(&dim, &numNonzeros, irn_ma57, jcn_ma57, &lkeep_ma57, keep_ma57, + iwork_ma57, icntl_ma57, info_ma57, rinfo_ma57); + + /* Receive some information from MA57AD */ + fint_t iflag = info_ma57[0]; /* Information flag */ + fint_t ierror = info_ma57[1]; /* Error flag */ + if (iflag != 0) + { + MyPrintf("MA57AD returns iflag = %d with ierror = %d\n", iflag, ierror); + delete [] keep_ma57; + delete [] iwork_ma57; + clear( ); + return THROWERROR(RET_MATRIX_FACTORISATION_FAILED); + } + + /* Allocate memory for actual factorization */ + double lfact_factor = 10.0; /* This could be an option */ + + lfact_ma57 = (fint_t)(lfact_factor * (double)(info_ma57[8])); + fact_ma57 = new double[lfact_ma57]; + + lifact_ma57 = (fint_t)(lfact_factor * (double)(info_ma57[9])); + ifact_ma57 = new fint_t[lifact_ma57]; + + /******************************************* + * Call MA57BD for numerical factorization * + *******************************************/ + + MA57BD( &dim, &numNonzeros, a_ma57, fact_ma57, &lfact_ma57, + ifact_ma57, &lifact_ma57, &lkeep_ma57, keep_ma57, + iwork_ma57, icntl_ma57, cntl_ma57, info_ma57, rinfo_ma57 ); + + delete [] iwork_ma57; + delete [] keep_ma57; + + /* Receive some information from MA57BD */ + iflag = info_ma57[0]; /* Information flag */ + ierror = info_ma57[1]; /* Error flag */ + neig = info_ma57[23]; /* Number of negative eigenvalues */ + rank = info_ma57[24]; /* Rank of matrix */ + + /* Read pivot sequence (see MA57UD source code) */ + pivots = new fint_t[dim]; + fint_t nrows, ncols; + fint_t nblk = ifact_ma57[2]; + int_t iwpos = 3; /* = 4-1 */ + int_t k, kk, count = 0; + for ( k=0; k(calloc(1, sizeof(MUMPS_STRUC_C))); + mumps_->job = -1; //initialize mumps + mumps_->par = 1; //working host for sequential version + mumps_->sym = 2; //general symmetric matrix + mumps_->comm_fortran = USE_COMM_WORLD; + +// #ifndef IPOPT_MUMPS_NOMUTEX +// const std::lock_guard lock(mumps_call_mutex); +// #endif + + mumps_c(mumps_); + mumps_->icntl[1] = 0; + mumps_->icntl[2] = 0; //QUIETLY! + mumps_->icntl[3] = 0; + + + // these values are just copied from Ipopt: better values might exist + mem_percent_ = 1000; + mumps_permuting_scaling_ = 7; + mumps_pivot_order_ = 7; + mumps_scaling_ = 77; + mumps_dep_tol_ = 0.0; + + pivtol_ = 0.000001; + // pivtol_ = 1.0; + // pivtol_ = 0.1; + // pivtol_ = 0.0; + pivtolmax_ = 0.1; // actually unused atm + + // Reset all private data + initialized_ = false; + pivtol_changed_ = false; + refactorize_ = false; + have_symbolic_factorization_ = false; + mumps_ptr_ = (void*) mumps_; + +} + + +/* + * M u m p s S p a r s e S o l v e r + */ +MumpsSparseSolver::MumpsSparseSolver( const MumpsSparseSolver& rhs ) +{ + copy( rhs ); +} + + +/* + * ~ M u m p s S p a r s e S o l v e r + */ +MumpsSparseSolver::~MumpsSparseSolver( ) +{ + +// #ifndef IPOPT_MUMPS_NOMUTEX +// const std::lock_guard lock(mumps_call_mutex); +// #endif + + MUMPS_STRUC_C* mumps_ = static_cast(mumps_ptr_); + mumps_->job = -2; //terminate mumps + mumps_c(mumps_); + delete[] mumps_->a; + free(mumps_); +} + + +/* + * o p e r a t o r = + */ +MumpsSparseSolver& MumpsSparseSolver::operator=( const SparseSolver& rhs ) +{ + const MumpsSparseSolver* mumps_rhs = dynamic_cast(&rhs); + if (!mumps_rhs) + { + fprintf(getGlobalMessageHandler()->getOutputFile(),"Error in MumpsSparseSolver& MumpsSparseSolver::operator=( const SparseSolver& rhs )\n"); + throw; /* TODO: More elegant exit? */ + } + if ( this != mumps_rhs ) + { + clear( ); + SparseSolver::operator=( rhs ); + copy( *mumps_rhs ); + } + + return *this; +} + +/* + * s e t M a t r i x D a t a + */ +returnValue MumpsSparseSolver::setMatrixData( int_t dim_, + int_t numNonzeros_, + const int_t* const irn, + const int_t* const jcn, + const real_t* const avals + ) +{ + reset( ); + dim = dim_; + numNonzeros = numNonzeros_; + + if ( numNonzeros_ > 0 ) + { + a_mumps = new double[numNonzeros_]; + irn_mumps = new fint_t[numNonzeros_]; + jcn_mumps = new fint_t[numNonzeros_]; + + numNonzeros=0; + for (int_t i=0; i(mumps_ptr_); + + MUMPS_STRUC_C* mumps_ = static_cast(mumps_ptr_); + mumps_data->n = dim; + mumps_data->nz = numNonzeros; + delete[] mumps_data->a; + mumps_data->a = NULL; + + mumps_data->a = new double[numNonzeros]; + mumps_data->irn = const_cast(irn_mumps); + mumps_data->jcn = const_cast(jcn_mumps); + + // make sure we do the symbolic factorization before a real + // factorization + have_symbolic_factorization_ = false; + +// #ifndef IPOPT_MUMPS_NOMUTEX +// const std::lock_guard lock(mumps_call_mutex); +// #endif + + mumps_data->job = 1; //symbolic ordering pass + + //mumps_data->icntl[1] = 6; + //mumps_data->icntl[2] = 6;//QUIETLY! + //mumps_data->icntl[3] = 4; + + mumps_data->icntl[5] = mumps_permuting_scaling_; + mumps_data->icntl[6] = mumps_pivot_order_; + mumps_data->icntl[7] = mumps_scaling_; + mumps_data->icntl[9] = 0; //no iterative refinement iterations + + mumps_data->icntl[12] = 1; //avoid lapack bug, ensures proper inertia; mentioned to be very expensive in mumps manual + mumps_data->icntl[13] = mem_percent_; //% memory to allocate over expected + mumps_data->cntl[0] = pivtol_; // Set pivot tolerance + + // dump_matrix(mumps_data); + + // MyPrintf("Calling MUMPS-1 for symbolic factorization.\n"); + mumps_c(mumps_data); + // MyPrintf("Done with MUMPS-1 for symbolic factorization.\n"); + int error = mumps_data->info[0]; + const int& mumps_permuting_scaling_used = mumps_data->infog[22]; + const int& mumps_pivot_order_used = mumps_data->infog[6]; + + //return appropriate value + if( error == -6 ) //system is singular + { + MyPrintf("MUMPS returned INFO(1) = %i matrix is singular.\n", error); + return RET_MATRIX_FACTORISATION_FAILED; + } + if( error < 0 ) + { + printf("nnz = %i\n",numNonzeros); + MyPrintf("Error=%i returned from MUMPS in Factorization.\n", error); + MyPrintf("MUMPS returned INFO(2) = %i.\n", mumps_data->info[1]); + return RET_MATRIX_FACTORISATION_FAILED; + } + + //// IPOPT-MUMPS (ACTUAL FACTORIZATION) + // MUMPS_STRUC_C* mumps_data = static_cast(mumps_ptr_); + + mumps_data->job = 2; //numerical factorization + + // dump_matrix(mumps_data); + // MyPrintf("Calling MUMPS-2 for numerical factorization.\n"); + mumps_c(mumps_data); + // MyPrintf("Done with MUMPS-2 for numerical factorization.\n"); + error = mumps_data->info[0]; + + //Check for errors + if( error == -8 || error == -9 ) //not enough memory + { + const int trycount_max = 20; + for( int trycount = 0; trycount < trycount_max; trycount++ ) + { + MyPrintf("MUMPS returned INFO(1) = %i and requires more memory, reallocating. Attempt %d\n", error, trycount + 1); + MUMPS_INT old_mem_percent = mumps_data->icntl[13]; + ComputeMemIncrease(mumps_data->icntl[13], 2.0 * (double)old_mem_percent, MUMPS_INT(0), "percent extra working space for MUMPS"); + MyPrintf("Increasing icntl[13] from % to % .\n", old_mem_percent, mumps_data->icntl[13]); + + // dump_matrix(mumps_data); + MyPrintf("Calling MUMPS-2 (repeated) for numerical factorization.\n"); + mumps_c(mumps_data); + MyPrintf("Done with MUMPS-2 (repeated) for numerical factorization.\n"); + error = mumps_data->info[0]; + if( error != -8 && error != -9 ) + { + break; + } + } + if( error == -8 || error == -9 ) + { + MyPrintf("MUMPS was not able to obtain enough memory.\n"); + return RET_MATRIX_FACTORISATION_FAILED; + } + } + + // MyPrintf("Number of doubles for MUMPS to hold factorization (INFO(9)) = %i\n", mumps_data->info[8]); + // MyPrintf("Number of integers for MUMPS to hold factorization (INFO(10)) = %i\n", mumps_data->info[9]); + + if( error == -10 ) //system is singular + { + MyPrintf("MUMPS returned INFO(1) = %i matrix is singular.\n", error); + return RET_MATRIX_FACTORISATION_FAILED; + } + + negevals_ = mumps_data->infog[11]; + + if( error == -13 ) + { + MyPrintf("MUMPS returned INFO(1) =%i - out of memory when trying to allocate % %s.\nIn some cases it helps to decrease the value of the option \"mumps_mem_percent\".\n", + error, mumps_data->info[1] < 0 ? -mumps_data->info[1] : mumps_data->info[1], + mumps_data->info[1] < 0 ? "MB" : "bytes"); + return RET_MATRIX_FACTORISATION_FAILED; + } + if( error < 0 ) //some other error + { + MyPrintf("MUMPS returned INFO(1) =%i MUMPS failure.\n", error); + return RET_MATRIX_FACTORISATION_FAILED; + } + + + have_factorization = true; + + return SUCCESSFUL_RETURN; +} + + +/* + * s o l v e + */ +returnValue MumpsSparseSolver::solve( int_t dim_, + const real_t* const rhs, + real_t* const sol + ) +{ + + // printf("in solve (MUMPS)\n"); + /* consistency check */ + if ( dim_ != dim ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + if ( !have_factorization ) + { + MyPrintf("Factorization not called before solve in MumpsSparseSolver::solve.\n"); + return THROWERROR( RET_INVALID_ARGUMENTS ); + } + + if ( dim == 0 ) + { + return SUCCESSFUL_RETURN; + } + + // MUMPS overwrites the rhs, copy rhs to sol and pass that to the solver + for (int_t i=0; i(mumps_ptr_); + + mumps_data->rhs = sol; + mumps_data->job = 3; //solve + // MyPrintf("Calling MUMPS-3 for solve.\n"); + mumps_c(mumps_data); + // MyPrintf("Done with MUMPS-3 for solve.\n"); + int error = mumps_data->info[0]; + if( error < 0 ) + { + MyPrintf("Error=%i returned from MUMPS in Solve.\n", error); + return THROWERROR(RET_MATRIX_FACTORISATION_FAILED); + } + + return SUCCESSFUL_RETURN; +} + +/* + * r e s e t + */ +returnValue MumpsSparseSolver::reset( ) +{ + /* AW: We probably want to avoid resetting factorization in QProblem */ + if ( SparseSolver::reset( ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_RESET_FAILED ); + + clear( ); + return SUCCESSFUL_RETURN; +} + +/* + * g e t N e g a t i v e E i g e n v a l u e s */ +int_t MumpsSparseSolver::getNegativeEigenvalues( ) +{ + if( !have_factorization ) + return -1; + else + return negevals_; +} + + +// TODO(andrea: not implemented yet, default behavior) + +/* + * g e t R a n k + */ +int_t MumpsSparseSolver::getRank( ) +{ + return -1; +} +/* + * g e t Z e r o P i v o t s + */ +returnValue MumpsSparseSolver::getZeroPivots( int_t *&zeroPivots ) +{ + if ( zeroPivots ) delete[] zeroPivots; + zeroPivots = 0; + return SUCCESSFUL_RETURN; +} + + +/***************************************************************************** + * P R O T E C T E D * + *****************************************************************************/ + +/* + * c l e a r + */ +returnValue MumpsSparseSolver::clear( ) +{ + delete [] a_mumps; + delete [] irn_mumps; + delete [] jcn_mumps; + + dim = -1; + numNonzeros = -1; + negevals_ = -1; + mumps_pivot_order_ = 0; + + a_mumps = 0; + irn_mumps = 0; + jcn_mumps = 0; + + have_factorization = false; + return SUCCESSFUL_RETURN; +} + + +/* + * c o p y + */ +returnValue MumpsSparseSolver::copy( const MumpsSparseSolver& rhs + ) +{ + dim = rhs.dim; + numNonzeros = rhs.numNonzeros; + negevals_ = rhs.negevals_; + have_factorization = rhs.have_factorization; + + if ( rhs.a_mumps != 0 ) + { + a_mumps = new double[numNonzeros]; + memcpy( a_mumps,rhs.a_mumps,numNonzeros*sizeof(double) ); + } + else + a_mumps = 0; + + if ( rhs.irn_mumps != 0 ) + { + irn_mumps = new fint_t[numNonzeros]; + memcpy( irn_mumps,rhs.irn_mumps,numNonzeros*sizeof(fint_t) ); + } + else + irn_mumps = 0; + + if ( rhs.jcn_mumps != 0 ) + { + jcn_mumps = new fint_t[numNonzeros]; + memcpy( jcn_mumps,rhs.jcn_mumps,numNonzeros*sizeof(fint_t) ); + } + else + jcn_mumps = 0; + + return SUCCESSFUL_RETURN; +} + +#endif /* SOLVER_MUMPS */ + +#ifdef SOLVER_NONE + +returnValue DummySparseSolver::setMatrixData( int_t dim, /**< Dimension of the linear system. */ + int_t numNonzeros, /**< Number of nonzeros in the matrix. */ + const int_t* const airn, /**< Row indices for each matrix entry. */ + const int_t* const acjn, /**< Column indices for each matrix entry. */ + const real_t* const avals /**< Values for each matrix entry. */ + ) +{ + return THROWERROR(RET_NO_SPARSE_SOLVER); +} + +returnValue DummySparseSolver::factorize( ) +{ + return THROWERROR(RET_NO_SPARSE_SOLVER); +} + +returnValue DummySparseSolver::solve( int_t dim, /**< Dimension of the linear system. */ + const real_t* const rhs, /**< Values for the right hand side. */ + real_t* const sol /**< Solution of the linear system. */ + ) +{ + return THROWERROR(RET_NO_SPARSE_SOLVER); +} + +#endif /* SOLVER_NONE */ + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/SubjectTo.cpp b/locomotion/src/third_party/qpOASES/src/SubjectTo.cpp new file mode 100644 index 0000000..846786a --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/SubjectTo.cpp @@ -0,0 +1,289 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/SubjectTo.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2007-2017 + * + * Implementation of the SubjectTo class designed to manage working sets of + * constraints and bounds within a QProblem. + */ + + +#include + + +BEGIN_NAMESPACE_QPOASES + + +/***************************************************************************** + * P U B L I C * + *****************************************************************************/ + + +/* + * S u b j e c t T o + */ +SubjectTo::SubjectTo( ) +{ + type = 0; + status = 0; + + init( ); +} + + +/* + * S u b j e c t T o + */ +SubjectTo::SubjectTo( int_t _n ) +{ + type = 0; + status = 0; + + init( _n ); +} + + +/* + * S u b j e c t T o + */ +SubjectTo::SubjectTo( const SubjectTo& rhs ) +{ + copy( rhs ); +} + + +/* + * ~ S u b j e c t T o + */ +SubjectTo::~SubjectTo( ) +{ + clear( ); +} + + +/* + * o p e r a t o r = + */ +SubjectTo& SubjectTo::operator=( const SubjectTo& rhs ) +{ + if ( this != &rhs ) + { + clear( ); + copy( rhs ); + } + + return *this; +} + + +/* + * i n i t + */ +returnValue SubjectTo::init( int_t _n + ) +{ + int_t i; + + if ( _n < 0 ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + clear( ); + + n = _n; + noLower = BT_TRUE; + noUpper = BT_TRUE; + + if ( n > 0 ) + { + type = new SubjectToType[n]; + status = new SubjectToStatus[n]; + + for( i=0; iaddNumber( newnumber ) == RET_INDEXLIST_EXCEEDS_MAX_LENGTH ) + return THROWERROR( RET_ADDINDEX_FAILED ); + } + else + return THROWERROR( RET_INVALID_ARGUMENTS ); + + return SUCCESSFUL_RETURN; +} + + +/* + * r e m o v e I n d e x + */ +returnValue SubjectTo::removeIndex( Indexlist* const indexlist, + int_t removenumber + ) +{ + if ( status != 0 ) + status[removenumber] = ST_UNDEFINED; + else + return THROWERROR( RET_REMOVEINDEX_FAILED ); + + if ( indexlist != 0 ) + { + if ( indexlist->removeNumber( removenumber ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_REMOVEINDEX_FAILED ); + } + else + return THROWERROR( RET_INVALID_ARGUMENTS ); + + return SUCCESSFUL_RETURN; +} + + +/* + * s w a p I n d e x + */ +returnValue SubjectTo::swapIndex( Indexlist* const indexlist, + int_t number1, int_t number2 + ) +{ + /* consistency checks */ + if ( status != 0 ) + { + if ( status[number1] != status[number2] ) + return THROWERROR( RET_SWAPINDEX_FAILED ); + } + else + return THROWERROR( RET_SWAPINDEX_FAILED ); + + if ( number1 == number2 ) + { + THROWWARNING( RET_NOTHING_TO_DO ); + return SUCCESSFUL_RETURN; + } + + if ( indexlist != 0 ) + { + if ( indexlist->swapNumbers( number1,number2 ) != SUCCESSFUL_RETURN ) + return THROWERROR( RET_SWAPINDEX_FAILED ); + } + else + return THROWERROR( RET_INVALID_ARGUMENTS ); + + return SUCCESSFUL_RETURN; +} + + +END_NAMESPACE_QPOASES + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/src/Utils.cpp b/locomotion/src/third_party/qpOASES/src/Utils.cpp new file mode 100644 index 0000000..f8e142d --- /dev/null +++ b/locomotion/src/third_party/qpOASES/src/Utils.cpp @@ -0,0 +1,1061 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file src/Utils.cpp + * \author Hans Joachim Ferreau, Andreas Potschka, Christian Kirches (thanks to Eckhard Arnold) + * \version 3.2 + * \date 2007-2017 + * + * Implementation of some utility functions for working with qpOASES. + */ + + +#include + +#if defined(__WIN32__) || defined(WIN32) + #include +#elif defined(LINUX) || defined(__LINUX__) + #include + #include +#endif + +#ifdef __MATLAB__ + #include "mex.h" +#endif + +#ifdef __SCILAB__ + #include +#endif + + +#include + + +#ifdef __NO_SNPRINTF__ +#if (!defined(_MSC_VER)) || defined(__DSPACE__) || defined(__XPCTARGET__) +/* If snprintf is not available, provide an empty implementation. */ +int snprintf( char* s, size_t n, const char* format, ... ) +{ + if ( n > 0 ) + s[0] = '\0'; + + return 0; +} +#endif +#endif /* __NO_SNPRINTF__ */ + + +BEGIN_NAMESPACE_QPOASES + + +/* + * p r i n t + */ +returnValue print( const real_t* const v, int_t n, const char* name ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + int_t i; + char myPrintfString[MAX_STRING_LENGTH]; + + /* Print vector name. */ + if ( name != 0 ) + { + snprintf( myPrintfString,MAX_STRING_LENGTH,"%s = \n", name ); + myPrintf( myPrintfString ); + } + + /* Print vector data. */ + for( i=0; igetOutputFile( ); + if ( outputfile == 0 ) + return THROWERROR( RET_NO_GLOBAL_MESSAGE_OUTPUTFILE ); + fprintf( outputfile, "%s", s ); + #endif /* __SCILAB__ */ + #endif /* __MATLAB__ */ + + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + +/* + * p r i n t C o p y r i g h t N o t i c e + */ +returnValue printCopyrightNotice( ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + #ifndef __XPCTARGET__ + #ifndef __DSPACE__ + #ifndef __NO_COPYRIGHT__ + myPrintf( "\nqpOASES -- An Implementation of the Online Active Set Strategy.\nCopyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka,\nChristian Kirches et al. All rights reserved.\n\nqpOASES is distributed under the terms of the \nGNU Lesser General Public License 2.1 in the hope that it will be \nuseful, but WITHOUT ANY WARRANTY; without even the implied warranty \nof MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \nSee the GNU Lesser General Public License for more details.\n\n" ); + #endif /* __NO_COPYRIGHT__ */ + #endif /* __DSPACE__ */ + #endif /* __XPCTARGET__ */ + #endif /* __SUPPRESSANYOUTPUT__ */ + return SUCCESSFUL_RETURN; +} + + +/* + * r e a d F r o m F i l e + */ +returnValue readFromFile( real_t* data, int_t nrow, int_t ncol, + const char* datafilename + ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + int_t i, j; + real_t float_data; + FILE* datafile; + + /* 1) Open file. */ + if ( ( datafile = fopen( datafilename, "r" ) ) == 0 ) + { + char errstr[MAX_STRING_LENGTH]; + snprintf( errstr,MAX_STRING_LENGTH,"(%s)",datafilename ); + return getGlobalMessageHandler( )->throwError( RET_UNABLE_TO_OPEN_FILE,errstr,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + } + + /* 2) Read data from file. */ + for( i=0; ithrowError( RET_UNABLE_TO_READ_FILE,errstr,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + } + data[i*ncol + j] = ( (real_t) float_data ); + } + } + + /* 3) Close file. */ + fclose( datafile ); + + return SUCCESSFUL_RETURN; + + #else /* __SUPPRESSANYOUTPUT__ */ + + return RET_NOT_YET_IMPLEMENTED; + + #endif /* __SUPPRESSANYOUTPUT__ */ +} + + +/* + * r e a d F r o m F i l e + */ +returnValue readFromFile( real_t* data, int_t n, + const char* datafilename + ) +{ + return readFromFile( data, n, 1, datafilename ); +} + + + +/* + * r e a d F r o m F i l e + */ +returnValue readFromFile( int_t* data, int_t n, + const char* datafilename + ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + int_t i; + FILE* datafile; + + /* 1) Open file. */ + if ( ( datafile = fopen( datafilename, "r" ) ) == 0 ) + { + char errstr[MAX_STRING_LENGTH]; + snprintf( errstr,MAX_STRING_LENGTH,"(%s)",datafilename ); + return getGlobalMessageHandler( )->throwError( RET_UNABLE_TO_OPEN_FILE,errstr,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + } + + /* 2) Read data from file. */ + for( i=0; ithrowError( RET_UNABLE_TO_READ_FILE,errstr,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + } + } + + /* 3) Close file. */ + fclose( datafile ); + + return SUCCESSFUL_RETURN; + + #else /* __SUPPRESSANYOUTPUT__ */ + + return RET_NOT_YET_IMPLEMENTED; + + #endif /* __SUPPRESSANYOUTPUT__ */ +} + + +/* + * w r i t e I n t o F i l e + */ +returnValue writeIntoFile( const real_t* const data, int_t nrow, int_t ncol, + const char* datafilename, BooleanType append + ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + + int_t i, j; + FILE* datafile; + + /* 1) Open file. */ + if ( append == BT_TRUE ) + { + /* append data */ + if ( ( datafile = fopen( datafilename, "a" ) ) == 0 ) + { + char errstr[MAX_STRING_LENGTH]; + snprintf( errstr,MAX_STRING_LENGTH,"(%s)",datafilename ); + return getGlobalMessageHandler( )->throwError( RET_UNABLE_TO_OPEN_FILE,errstr,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + } + } + else + { + /* do not append data */ + if ( ( datafile = fopen( datafilename, "w" ) ) == 0 ) + { + char errstr[MAX_STRING_LENGTH]; + snprintf( errstr,MAX_STRING_LENGTH,"(%s)",datafilename ); + return getGlobalMessageHandler( )->throwError( RET_UNABLE_TO_OPEN_FILE,errstr,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + } + } + + /* 2) Write data into file. */ + for( i=0; ithrowError( RET_UNABLE_TO_OPEN_FILE,errstr,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + } + } + else + { + /* do not append data */ + if ( ( datafile = fopen( datafilename, "w" ) ) == 0 ) + { + char errstr[MAX_STRING_LENGTH]; + snprintf( errstr,MAX_STRING_LENGTH,"(%s)",datafilename ); + return getGlobalMessageHandler( )->throwError( RET_UNABLE_TO_OPEN_FILE,errstr,__FUNC__,__FILE__,__LINE__,VS_VISIBLE ); + } + } + + /* 2) Write data into file. */ + for( i=0; i stat) stat = getAbs(sum); + } + + /* check primal feasibility and complementarity of bounds */ + /* feasibility */ + for (i = 0; i < nV; i++) + { + if ( lb != 0 ) + if (lb[i] - x[i] > feas) + feas = lb[i] - x[i]; + + if ( ub != 0 ) + if (x[i] - ub[i] > feas) + feas = x[i] - ub[i]; + } + + /* complementarity */ + if ( workingSetB == 0 ) + { + for (i = 0; i < nV; i++) + { + prod = 0.0; + + /* lower bound */ + if ( lb != 0 ) + if (y[i] > dualActiveTolerance) + prod = (x[i] - lb[i]) * y[i]; + + /* upper bound */ + if ( ub != 0 ) + if (y[i] < -dualActiveTolerance) + prod = (x[i] - ub[i]) * y[i]; + + if (getAbs(prod) > cmpl) cmpl = getAbs(prod); + } + } + else + { + for (i = 0; i < nV; i++) + { + prod = 0.0; + + /* lower bound */ + if ( lb != 0 ) + { + if ( isEqual(workingSetB[i],-1.0) == BT_TRUE ) + prod = (x[i] - lb[i]) * y[i]; + } + + /* upper bound */ + if ( ub != 0 ) + { + if ( isEqual(workingSetB[i],1.0) == BT_TRUE ) + prod = (x[i] - ub[i]) * y[i]; + } + + if (getAbs(prod) > cmpl) cmpl = getAbs(prod); + } + } + + /* check primal feasibility and complementarity of constraints */ + for (i = 0; i < nC; i++) + { + /* compute sum = (A*x)_i */ + sum = 0.0; + if ( A != 0 ) + for (j = 0; j < nV; j++) + sum += A[i*nV+j] * x[j]; + + /* feasibility */ + if ( lbA != 0 ) + if (lbA[i] - sum > feas) + feas = lbA[i] - sum; + + if ( ubA != 0 ) + if (sum - ubA[i] > feas) + feas = sum - ubA[i]; + + /* complementarity */ + prod = 0.0; + + /* lower bound */ + if ( lbA != 0 ) + { + if ( workingSetC == 0 ) + { + if (y[nV+i] > dualActiveTolerance) + prod = (sum - lbA[i]) * y[nV+i]; + } + else + { + if ( isEqual(workingSetC[i],-1.0) == BT_TRUE ) + prod = (sum - lbA[i]) * y[nV+i]; + } + } + + /* upper bound */ + if ( ubA != 0 ) + { + if ( workingSetC == 0 ) + { + if (y[nV+i] < -dualActiveTolerance) + prod = (sum - ubA[i]) * y[nV+i]; + } + else + { + if ( isEqual(workingSetC[i],1.0) == BT_TRUE ) + prod = (sum - ubA[i]) * y[nV+i]; + } + } + + if (getAbs(prod) > cmpl) cmpl = getAbs(prod); + } + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t K k t V i o l a t i o n + */ +returnValue getKktViolation( int_t nV, + const real_t* const H, const real_t* const g, + const real_t* const lb, const real_t* const ub, + const real_t* const x, const real_t* const y, + real_t& stat, real_t& feas, real_t& cmpl, + const real_t* const workingSetB, BooleanType hasIdentityHessian + ) +{ + return getKktViolation( nV,0, + H,g,0,lb,ub,0,0, + x,y, + stat,feas,cmpl, + workingSetB,0,hasIdentityHessian + ); +} + + +/* + * c o n v e r t B o o l e a n T y p e T o S t r i n g + */ +returnValue convertBooleanTypeToString( BooleanType value, char* const string ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + if ( value == BT_FALSE ) + snprintf( string,20,"BT_FALSE" ); + else + snprintf( string,20,"BT_TRUE" ); + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + +/* + * c o n v e r t S u b j e c t T o S t a t u s T o S t r i n g + */ +returnValue convertSubjectToStatusToString( SubjectToStatus value, char* const string ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + switch( value ) + { + case ST_INACTIVE: + snprintf( string,20,"ST_INACTIVE" ); + break; + + case ST_LOWER: + snprintf( string,20,"ST_LOWER" ); + break; + + case ST_UPPER: + snprintf( string,20,"ST_UPPER" ); + break; + + case ST_UNDEFINED: + snprintf( string,20,"ST_UNDEFINED" ); + break; + + case ST_INFEASIBLE_LOWER: + snprintf( string,20,"ST_INFEASIBLE_LOWER" ); + break; + + case ST_INFEASIBLE_UPPER: + snprintf( string,20,"ST_INFEASIBLE_UPPER" ); + break; + + default: + snprintf( string,20,"" ); + break; + } + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + +/* + * c o n v e r t P r i n t L e v e l T o S t r i n g + */ +returnValue convertPrintLevelToString( PrintLevel value, char* const string ) +{ + #ifndef __SUPPRESSANYOUTPUT__ + switch( value ) + { + case PL_NONE: + snprintf( string,20,"PL_NONE" ); + break; + + case PL_LOW: + snprintf( string,20,"PL_LOW" ); + break; + + case PL_MEDIUM: + snprintf( string,20,"PL_MEDIUM" ); + break; + + case PL_HIGH: + snprintf( string,20,"PL_HIGH" ); + break; + + case PL_TABULAR: + snprintf( string,20,"PL_TABULAR" ); + break; + + case PL_DEBUG_ITER: + snprintf( string,20,"PL_DEBUG_ITER" ); + break; + + default: + snprintf( string,20,"" ); + break; + } + #endif /* __SUPPRESSANYOUTPUT__ */ + + return SUCCESSFUL_RETURN; +} + + +/* + * g e t S i m p l e S t a t u s + */ +int_t getSimpleStatus( returnValue returnvalue, + BooleanType doPrintStatus + ) +{ + int_t simpleStatus = -1; + + /* determine simple status from returnvalue */ + switch ( returnvalue ) + { + case SUCCESSFUL_RETURN: + simpleStatus = 0; + break; + + case RET_MAX_NWSR_REACHED: + simpleStatus = 1; + break; + + case RET_INIT_FAILED_INFEASIBILITY: + case RET_HOTSTART_STOPPED_INFEASIBILITY: + simpleStatus = -2; + break; + + case RET_INIT_FAILED_UNBOUNDEDNESS: + case RET_HOTSTART_STOPPED_UNBOUNDEDNESS: + simpleStatus = -3; + break; + + default: + simpleStatus = -1; + break; + } + + if ( doPrintStatus == BT_TRUE ) + { + VisibilityStatus vsInfo = getGlobalMessageHandler( )->getInfoVisibilityStatus( ); + getGlobalMessageHandler( )->setInfoVisibilityStatus( VS_VISIBLE ); + getGlobalMessageHandler( )->setErrorCount( -1 ); + + int_t retValNumber = (int_t)RET_SIMPLE_STATUS_P0 - simpleStatus; + THROWINFO( (returnValue)retValNumber ); + + getGlobalMessageHandler( )->setInfoVisibilityStatus( vsInfo ); + } + + return simpleStatus; +} + + +/* + * n o r m a l i s e C o n s t r a i n t s + */ +returnValue normaliseConstraints( int_t nV, int_t nC, + real_t* A, real_t* lbA, real_t* ubA, + int_t type + ) +{ + int_t ii, jj; + real_t curNorm; + + if ( ( nV <= 0 ) || ( nC <= 0 ) || ( A == 0 ) ) + return THROWERROR( RET_INVALID_ARGUMENTS ); + + for( ii=0; ii EPS ) + { + /* normalise if norm is positive */ + for( jj=0; jj + +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + int_t nWSR; + qpOASES_Options options; + + real_t xOpt[2]; + real_t yOpt[2+1]; + real_t obj; + int_t status; + + qpOASES_Options_init( &options,0 ); + options.printLevel = PL_MEDIUM; + + + QProblem_setup( 2,1,HST_UNKNOWN ); + + /* Solve first QP. */ + nWSR = 10; + QProblem_init( H,g,A,lb,ub,lbA,ubA, + &nWSR,0,&options, + xOpt,yOpt,&obj,&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2], obj ); + + + /* Solve second QP. */ + nWSR = 10; + QProblem_hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, + &nWSR,0, + xOpt,yOpt,&obj,&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2], obj ); + + + QProblem_cleanup(); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/c/test_c_example1a.c b/locomotion/src/third_party/qpOASES/testing/c/test_c_example1a.c new file mode 100644 index 0000000..690c661 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/c/test_c_example1a.c @@ -0,0 +1,105 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/c/test_c_example1a.c + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Very simple example for testing qpOASES (using SQProblem class through C interface). + */ + +#include + +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t H_new[2*2] = { 1.0, 0.5, 0.5, 0.5 }; + real_t A_new[1*2] = { 1.0, 5.0 }; + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + int_t nWSR; + + real_t xOpt[2]; + real_t yOpt[2+1]; + real_t obj; + int_t status; + + qpOASES_Options options; + qpOASES_Options_init( &options,0 ); + + + SQProblem_setup( 2,1,HST_UNKNOWN ); + + /* Solve first QP. */ + nWSR = 10; + SQProblem_init( H,g,A,lb,ub,lbA,ubA, + &nWSR,0,&options, + xOpt,yOpt,&obj,&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2], obj ); + + + /* Solve second QP. */ + nWSR = 10; + SQProblem_hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, + &nWSR,0, + xOpt,yOpt,&obj,&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2], obj ); + + + SQProblem_cleanup(); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/c/test_c_example1b.c b/locomotion/src/third_party/qpOASES/testing/c/test_c_example1b.c new file mode 100644 index 0000000..84a4ffd --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/c/test_c_example1b.c @@ -0,0 +1,102 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/c/test_example1b.c + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Very simple example for testing qpOASES (using QProblemB class through C interface). + */ + +#include + +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + + int_t nWSR; + qpOASES_Options options; + + real_t xOpt[2]; + real_t yOpt[2]; + real_t obj; + int_t status; + + qpOASES_Options_init( &options,0 ); + /*options.enableFlippingBounds = 0; */ + options.initialStatusBounds = ST_INACTIVE; + options.numRefinementSteps = 1; + options.enableCholeskyRefactorisation = 1; + + + QProblemB_setup( 2,HST_UNKNOWN ); + + /* Solve first QP. */ + nWSR = 10; + QProblemB_init( H,g,lb,ub, + &nWSR,0,&options, + xOpt,yOpt,&obj,&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1], obj ); + + + /* Solve second QP. */ + nWSR = 10; + QProblemB_hotstart( g_new,lb_new,ub_new, + &nWSR,0, + xOpt,yOpt,&obj,&status + ); + + /* Print solution of first QP. */ + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1], obj ); + + + QProblemB_cleanup(); + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/checkForMemoryLeaks b/locomotion/src/third_party/qpOASES/testing/checkForMemoryLeaks new file mode 100755 index 0000000..346a333 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/checkForMemoryLeaks @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: testing/checkForMemoryLeaks +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2014-2017 + +# defining colors for output +red='\e[0;31m' +green='\e[0;32m' +NC='\e[0m' # No Color + +# runs valgrind on a number of examples to detect possible memory leaks + +function callValgrind { + echo -n "Checking for memory leaks in $2 $3... " + + valgrind --tool=memcheck --leak-check=yes --error-exitcode=42 -q $2 $3 > dummy.txt; + retVal=$?; + rm -rf dummy.txt; + + if [ $retVal == 42 ]; then + echo -e "${red}failed!${NC}" + counter=$[counter+1]; + else + if [ $retVal == 99 ]; then + echo "problem data missing!" + else + echo -e "${green}passed!${NC}" + fi + fi +} + + +cd ..; +make examples testing; +cd testing; + +counter=0; + +# run examples in /examples +callValgrind $counter ../bin/example1; +callValgrind $counter ../bin/example1a; +callValgrind $counter ../bin/example1b; +callValgrind $counter ../bin/example2; +callValgrind $counter ../bin/example3; +callValgrind $counter ../bin/example3b; +callValgrind $counter ../bin/example4; +callValgrind $counter ../bin/example5; +callValgrind $counter ../bin/exampleLP; +callValgrind $counter ../bin/qrecipe; +callValgrind $counter ../bin/qrecipeSchur; + +# run examples in /testing ... +callValgrind $counter ../bin/test_matrices; +callValgrind $counter ../bin/test_matrices2; +callValgrind $counter ../bin/test_indexlist; +callValgrind $counter ../bin/test_example6; +callValgrind $counter ../bin/test_example7; +callValgrind $counter ../bin/test_infeasible1; +callValgrind $counter ../bin/test_sebastien1; +callValgrind $counter ../bin/test_vanBarelsUnboundedQP; +callValgrind $counter ../bin/test_janick1; +callValgrind $counter ../bin/test_janick2; +callValgrind $counter ../bin/test_constraintProduct1; +callValgrind $counter ../bin/test_constraintProduct2; +callValgrind $counter ../bin/test_guessedWS1; +callValgrind $counter ../bin/test_externalChol1; +callValgrind $counter ../bin/test_runAllOqpExamples; + + +# ... including testbench with different settings +callValgrind $counter ../bin/test_bench Odd; # default dense +callValgrind $counter ../bin/test_bench Ods; # default sparse +callValgrind $counter ../bin/test_bench Omd; # MPC dense +callValgrind $counter ../bin/test_bench Ors; # reliable dense + + +if [ $counter == 0 ]; then + echo -e "${green}All available tests passed successfully!${NC}" +else + echo -e "${red}$counter test(s) failed!${NC}" + exit 1 +fi diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/Makefile b/locomotion/src/third_party/qpOASES/testing/cpp/Makefile new file mode 100644 index 0000000..8d0bba8 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/Makefile @@ -0,0 +1,138 @@ +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: testing/cpp/Makefile +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2007-2017 +## + + +include ../../make.mk + +## +## flags +## + +IFLAGS = -I. \ + -I${IDIR} + +QPOASES_TEST_EXES = \ + ${BINDIR}/test_bench${EXE} \ + ${BINDIR}/test_matrices${EXE} \ + ${BINDIR}/test_matrices2${EXE} \ + ${BINDIR}/test_matrices3${EXE} \ + ${BINDIR}/test_indexlist${EXE} \ + ${BINDIR}/test_example1${EXE} \ + ${BINDIR}/test_example1a${EXE} \ + ${BINDIR}/test_example1b${EXE} \ + ${BINDIR}/test_example2${EXE} \ + ${BINDIR}/test_example4${EXE} \ + ${BINDIR}/test_example5${EXE} \ + ${BINDIR}/test_example6${EXE} \ + ${BINDIR}/test_example7${EXE} \ + ${BINDIR}/test_exampleLP${EXE} \ + ${BINDIR}/test_qrecipe${EXE} \ + ${BINDIR}/test_qrecipeSchur${EXE} \ + ${BINDIR}/test_smallSchur${EXE} \ + ${BINDIR}/test_infeasible1${EXE} \ + ${BINDIR}/test_hs268${EXE} \ + ${BINDIR}/test_gradientShift${EXE} \ + ${BINDIR}/test_runAllOqpExamples${EXE} \ + ${BINDIR}/test_sebastien1${EXE} \ + ${BINDIR}/test_vanBarelsUnboundedQP${EXE} \ + ${BINDIR}/test_janick1${EXE} \ + ${BINDIR}/test_janick2${EXE} \ + ${BINDIR}/test_constraintProduct1${EXE} \ + ${BINDIR}/test_constraintProduct2${EXE} \ + ${BINDIR}/test_guessedWS1${EXE} \ + ${BINDIR}/test_externalChol1${EXE} \ + ${BINDIR}/test_identitySqproblem${EXE} + + +## +## targets +## + +all: ${QPOASES_TEST_EXES} + +runTests: ${QPOASES_TEST_EXES} + @cd .. && ./runUnitTests && ./checkForMemoryLeaks && cd cpp + +${BINDIR}/%${EXE}: %.${OBJEXT} ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + +${BINDIR}/test_matrices2${EXE}: test_matrices2.${OBJEXT} test_qrecipe_data.hpp ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + +${BINDIR}/test_matrices3${EXE}: test_matrices3.${OBJEXT} test_qrecipe_data.hpp ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + +${BINDIR}/test_qrecipe${EXE}: test_qrecipe.${OBJEXT} test_qrecipe_data.hpp ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + +${BINDIR}/test_qrecipeSchur${EXE}: test_qrecipeSchur.${OBJEXT} test_qrecipe_data.hpp ${LINK_DEPENDS} + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${CPPFLAGS} $< ${QPOASES_LINK} ${LINK_LIBRARIES} + + +clean: + @${ECHO} "Cleaning up (testing/cpp)" + @${RM} -f *.${OBJEXT} ${QPOASES_TEST_EXES} + +clobber: clean + + +${LINK_DEPENDS}: + @cd ../..; ${MAKE} -s src + +test_matrices2.${OBJEXT}: test_matrices2.cpp test_qrecipe_data.hpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${IFLAGS} ${CPPFLAGS} -c $< + +test_matrices3.${OBJEXT}: test_matrices3.cpp test_qrecipe_data.hpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${IFLAGS} ${CPPFLAGS} -c $< + +test_qrecipe.${OBJEXT}: test_qrecipe.cpp test_qrecipe_data.hpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${IFLAGS} ${CPPFLAGS} -c $< + +test_qrecipeSchur.${OBJEXT}: test_qrecipeSchur.cpp test_qrecipe_data.hpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${IFLAGS} ${CPPFLAGS} -c $< + +%.${OBJEXT}: %.cpp + @${ECHO} "Creating" $@ + @${CPP} ${DEF_TARGET} ${IFLAGS} ${CPPFLAGS} -c $< + + +## +## end of file +## diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/data/fetch_cpp_data b/locomotion/src/third_party/qpOASES/testing/cpp/data/fetch_cpp_data new file mode 100755 index 0000000..cc52452 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/data/fetch_cpp_data @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: testing/cpp/data/fetch_cpp_data +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2014 + + +svn export https://projects.coin-or.org/svn/qpOASES/misc/testingdata/cpp . --force diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_bench.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_bench.cpp new file mode 100644 index 0000000..58ca740 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_bench.cpp @@ -0,0 +1,310 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_bench.cpp + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2010-2017 + * + * Unit test running all benchmark examples stored in problems directory. + */ + + + +#include +#include +#include +#include +#include + + +/** Run benchmark examples. */ +int main( int argc, char *argv[] ) +{ + USING_NAMESPACE_QPOASES + #ifdef __USE_SINGLE_PRECISION__ + const real_t TOL = 5e-2; + #else + const real_t TOL = 1e-5; + #endif + + /* 1) Define benchmark arguments. */ + BooleanType isSparse = BT_FALSE; + //BooleanType isSparse = BT_TRUE; + Options options; + options.setToDefault(); + //options.setToMPC(); + //options.setToReliable(); + options.printLevel = PL_LOW; + //options.printLevel = PL_MEDIUM; + //options.printLevel = PL_TABULAR; + //options.enableFarBounds = BT_FALSE; + +// options.initialStatusBounds = ST_LOWER; + //options.numRegularisationSteps = 1; + //options.epsRegularisation = 1.0e3 * EPS; + + //options.enableFlippingBounds = BT_FALSE; + //options.enableFlippingBounds = BT_FALSE; + //options.enableRamping = BT_TRUE; + //options.enableFarBounds = BT_FALSE; + //options.enableNZCTests = BT_FALSE; + //options.epsNZCTests = 1.0e4 * EPS; + //options.epsFlipping = 1.0e5 * EPS; + //options.enableFullLITests = BT_TRUE; + //options.enableDriftCorrection = 1; + //options.enableEqualities = BT_TRUE; + //options.enableEqualities = BT_FALSE; + //options.epsNum = -1.0e3 * EPS; + //options.epsDen = 1.0e3 * EPS; + + + int_t nWSR; + real_t maxCPUtime; /* seconds */ + real_t maxStationarity = 0.0, maxFeasibility = 0.0, maxComplementarity = 0.0; + real_t avgStationarity = 0.0, avgFeasibility = 0.0, avgComplementarity = 0.0; + + int_t scannedDir = 0; + int_t nfail = 0, npass = 0; + int_t nproblems, i; + struct dirent **namelist; + char resstr[MAX_STRING_LENGTH], oqpProblem[MAX_STRING_LENGTH]; + char *problem; + returnValue returnvalue; + + int_t expectedNumSolvedProblems = 44; + real_t expectedAvgStationarity = TOL; + real_t expectedAvgFeasibility = TOL; + real_t expectedAvgComplementarity = TOL; + + + if ( argv[argc-1][0] == 'O' ) + { + if ( strlen(argv[argc-1]) != 3 ) + { + fprintf( stdout,"ERROR (testbench): Invalid options passed!\n" ); + return TEST_DATA_NOT_FOUND; + } + + fprintf( stdout,"Analysing passed options: " ); + switch ( argv[argc-1][1] ) + { + case 'd': + fprintf( stdout,"default options, " ); + options.setToDefault(); + if ( argv[argc-1][2] == 's' ) + { + expectedNumSolvedProblems = 44; + expectedAvgStationarity = 1e-9; + expectedAvgFeasibility = 1e-9; + expectedAvgComplementarity = 5e-7; + } + else + { + expectedNumSolvedProblems = 44; + expectedAvgStationarity = 5e-10; + expectedAvgFeasibility = 5e-10; + expectedAvgComplementarity = 5e-8; + } + break; + + case 'r': + fprintf( stdout,"reliable options, " ); + options.setToReliable(); + if ( argv[argc-1][2] == 's' ) + { + expectedNumSolvedProblems = 44; + expectedAvgStationarity = 2e-9; + expectedAvgFeasibility = 2e-11; + expectedAvgComplementarity = 3e-9; + } + else + { + expectedNumSolvedProblems = 44; + expectedAvgStationarity = 2e-9; + expectedAvgFeasibility = 2e-9; + expectedAvgComplementarity = 3e-7; + } + break; + + case 'm': + fprintf( stdout,"MPC options, " ); + options.setToMPC(); + if ( argv[argc-1][2] == 's' ) + { + expectedNumSolvedProblems = 42; + expectedAvgStationarity = 2e-8; + expectedAvgFeasibility = 1e-8; + expectedAvgComplementarity = 2e-7; + } + else + { + expectedNumSolvedProblems = 42; + expectedAvgStationarity = 3e-8; + expectedAvgFeasibility = 1e-8; + expectedAvgComplementarity = 5e-8; + } + break; + + default: + fprintf( stdout,"ERROR (testbench): Invalid options passed!\n" ); + return TEST_DATA_NOT_FOUND; + } + + switch ( argv[argc-1][2] ) + { + case 's': + fprintf( stdout,"sparse QP data\n" ); + isSparse = BT_TRUE; + break; + + case 'd': + fprintf( stdout,"dense QP data\n" ); + isSparse = BT_FALSE; + break; + + default: + fprintf( stdout,"ERROR (testbench): Invalid options passed!\n" ); + return TEST_DATA_NOT_FOUND; + } + options.printLevel = PL_NONE; + //options.enableFlippingBounds = BT_FALSE; + + nproblems = argc-2; + } + else + { + nproblems = argc-1; + } + + + if (nproblems == 0) + { + /* 2a) Scan problem directory */ + nproblems = scandir("../testing/cpp/data/problems", &namelist, NULL, alphasort); + if (nproblems <= 0) + { + myPrintf( "No test problems found!\n" ); + return TEST_DATA_NOT_FOUND; + } + scannedDir = 1; + } + else + { + /* 2b) Use problem list given by arguments */ + scannedDir = 0; + } + + /* 3) Run benchmark. */ + printf("%10s %9s %9s %9s %6s %-12s\n", "problem", "stat", + "feas", "compl", "nWSR", "result"); + for (i = 0; i < nproblems; i++) + { + if (scannedDir) + { + /* skip special directories and zip file cuter.*bz2 */ + if (namelist[i]->d_name[0] == '.' || namelist[i]->d_name[0] == 'c') + { + free(namelist[i]); + continue; + } + problem = namelist[i]->d_name; + } + else + { + problem = argv[i+1]; + } + + fprintf(stdFile, "%-10s ", problem); + fflush(stdFile); + + snprintf(oqpProblem, MAX_STRING_LENGTH, "../testing/cpp/data/problems/%s/", problem); + maxCPUtime = 300.0; + nWSR = 2500; + + returnvalue = runOqpBenchmark( oqpProblem, isSparse, options, + nWSR, maxCPUtime, maxStationarity, maxFeasibility, maxComplementarity + ); + if (returnvalue == SUCCESSFUL_RETURN + && maxStationarity < TOL + && maxFeasibility < TOL + && maxComplementarity < TOL) + { + npass++; + + avgStationarity += maxStationarity; + avgFeasibility += maxFeasibility; + avgComplementarity += maxComplementarity; + + strncpy(resstr, "pass", MAX_STRING_LENGTH); + } + else + { + if ( returnvalue == RET_BENCHMARK_ABORTED ) + return TEST_DATA_NOT_FOUND; + + nfail++; + snprintf (resstr, MAX_STRING_LENGTH, "fail (%d)",(int)returnvalue); + } + fprintf(stdFile, "%9.2e %9.2e %9.2e %6d %-12s\n", maxStationarity, + maxFeasibility, maxComplementarity, (int)nWSR, resstr); + + if (scannedDir) free(namelist[i]); + } + if (scannedDir) free(namelist); + + avgStationarity /= (real_t)npass; + avgFeasibility /= (real_t)npass; + avgComplementarity /= (real_t)npass; + + + /* 4) Print results. */ + printf( "\n\n" ); + printf( "Testbench results:\n" ); + printf( "======================\n\n" ); + printf( "Pass: %3d\n",(int)npass ); + printf( "Fail: %3d\n",(int)nfail ); + printf( "Ratio: %5.1f%%\n", 100.0 * (real_t)npass / (real_t)(npass+nfail) ); + printf( "\n" ); + + QPOASES_TEST_FOR_TRUE( npass >= expectedNumSolvedProblems ); + + + printf( "avg. stat: %e\n", avgStationarity ); + printf( "avg. feas: %e\n", avgFeasibility ); + printf( "avg. cmpl: %e\n", avgComplementarity ); + + QPOASES_TEST_FOR_TOL( avgStationarity, expectedAvgStationarity ); + QPOASES_TEST_FOR_TOL( avgFeasibility, expectedAvgFeasibility ); + QPOASES_TEST_FOR_TOL( avgComplementarity, expectedAvgComplementarity ); + + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_constraintProduct1.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_constraintProduct1.cpp new file mode 100644 index 0000000..339289e --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_constraintProduct1.cpp @@ -0,0 +1,200 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_constraintProduct1.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Another example for testing qpOASES using the possibility to specify + * user-defined constraint product function. + */ + + + +#include +#include + + + +USING_NAMESPACE_QPOASES + + +/** + * \brief Example illustrating the use of the \a ConstraintProduct class. + * + * Example illustrating the use of the \a ConstraintProduct class. + * + * \author Hans Joachim Ferreau + * \version 3.1 + * \date 2007-2017 + */ +class MpcConstraintProduct : public ConstraintProduct +{ + public: + /** Default constructor. */ + MpcConstraintProduct( ) {}; + + /** Constructor. */ + MpcConstraintProduct( int_t _nV, + int_t _nC, + int_t _diagOffset, + real_t* _A + ) + { + nV = _nV; + nC = _nC; + diagOffset = _diagOffset; + A = _A; + }; + + /** Copy constructor (flat copy). */ + MpcConstraintProduct( const MpcConstraintProduct& rhs + ) + { + nV = rhs.nV; + nC = rhs.nC; + diagOffset = rhs.diagOffset; + A = rhs.A; + }; + + /** Destructor. */ + virtual ~MpcConstraintProduct( ) {}; + + /** Assignment operator (flat copy). */ + MpcConstraintProduct& operator=( const MpcConstraintProduct& rhs + ) + { + if ( this != &rhs ) + { + nV = rhs.nV; + nC = rhs.nC; + diagOffset = rhs.diagOffset; + A = rhs.A; + } + else + return *this; + }; + + virtual int_t operator() ( int_t constrIndex, + const real_t* const x, + real_t* const constrValue + ) const + { + int_t i; + int_t maxI = (int_t)(((real_t)constrIndex) * ((real_t)nV) / ((real_t)nC)) + diagOffset; + maxI = getMin( maxI,nV ); + + constrValue[0] = 0.0; + + for( i=0; i +#include + + + +USING_NAMESPACE_QPOASES + + +/** + * \brief Example illustrating the use of the \a ConstraintProduct class. + * + * Example illustrating the use of the \a ConstraintProduct class. + * + * \author Hans Joachim Ferreau + * \version 3.1 + * \date 2007-2017 + */ +class MpcConstraintProduct : public ConstraintProduct +{ + public: + /** Default constructor. */ + MpcConstraintProduct( ) {}; + + /** Constructor. */ + MpcConstraintProduct( int_t _nV, + int_t _nC, + int_t _diagOffset, + real_t* _A + ) + { + nV = _nV; + nC = _nC; + diagOffset = _diagOffset; + A = _A; + }; + + /** Copy constructor (flat copy). */ + MpcConstraintProduct( const MpcConstraintProduct& rhs + ) + { + nV = rhs.nV; + nC = rhs.nC; + diagOffset = rhs.diagOffset; + A = rhs.A; + }; + + /** Destructor. */ + virtual ~MpcConstraintProduct( ) {}; + + /** Assignment operator (flat copy). */ + MpcConstraintProduct& operator=( const MpcConstraintProduct& rhs + ) + { + if ( this != &rhs ) + { + nV = rhs.nV; + nC = rhs.nC; + diagOffset = rhs.diagOffset; + A = rhs.A; + } + else + return *this; + }; + + virtual int_t operator() ( int_t constrIndex, + const real_t* const x, + real_t* const constrValue + ) const + { + int_t i; + int_t maxI = (int_t)(((real_t)constrIndex) * ((real_t)nV) / ((real_t)nC)) + diagOffset; + maxI = getMin( maxI,nV ); + + constrValue[0] = 0.0; + + for( i=0; i +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + + /* Setting up QProblem object. */ + QProblem example( 2,1 ); + + Options options; + example.setOptions( options ); + + /* Solve first QP. */ + int_t nWSR = 10; + example.init( H,g,A,lb,ub,lbA,ubA, nWSR ); + + /* Get and print solution of second QP. */ + real_t xOpt[2]; + real_t yOpt[2+1]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2],example.getObjVal() ); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + + /* Solve second QP. */ + nWSR = 10; + example.hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2],example.getObjVal() ); + + /* Compute KKT tolerances */ + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_example1a.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_example1a.cpp new file mode 100644 index 0000000..21a04ef --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_example1a.cpp @@ -0,0 +1,111 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_example1a.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Very simple example for testing qpOASES using the SQProblem class. + */ + + + +#include +#include + + +/** Example for qpOASES main function using the SQProblem class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t H_new[2*2] = { 1.0, 0.5, 0.5, 0.5 }; + real_t A_new[1*2] = { 1.0, 5.0 }; + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + + /* Setting up SQProblem object. */ + SQProblem example( 2,1 ); + + /* Solve first QP. */ + int_t nWSR = 10; + example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + + real_t xOpt[2]; + real_t yOpt[2+1]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + + /* Solve second QP. */ + nWSR = 10; + example.hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,0 ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() ); + + /* Compute KKT tolerances */ + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,2e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_example1b.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_example1b.cpp new file mode 100644 index 0000000..533ca87 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_example1b.cpp @@ -0,0 +1,112 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_example1b.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Very simple example for testing qpOASES using the QProblemB class. + */ + + +#include +#include + + +/** Example for qpOASES main function using the QProblemB class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + + + /* Setting up QProblemB object. */ + QProblemB example( 2 ); + + Options options; + //options.enableFlippingBounds = BT_FALSE; + options.initialStatusBounds = ST_INACTIVE; + options.numRefinementSteps = 1; + options.enableCholeskyRefactorisation = 1; + example.setOptions( options ); + + /* Solve first QP. */ + int_t nWSR = 10; + example.init( H,g,lb,ub, nWSR,0 ); +// printf( "\nnWSR = %d\n\n", nWSR ); + + real_t xOpt[2]; + real_t yOpt[2]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + + /* Solve second QP. */ + nWSR = 10; + example.hotstart( g_new,lb_new,ub_new, nWSR,0 ); +// printf( "\nnWSR = %d\n\n", nWSR ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() ); + + /* Compute KKT tolerances */ + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_example2.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_example2.cpp new file mode 100644 index 0000000..d8068bf --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_example2.cpp @@ -0,0 +1,131 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_example2.cpp + * \author Hans Joachim Ferreau (thanks to Boris Houska) + * \version 3.2 + * \date 2008-2017 + * + * Very simple example for testing qpOASES in combination + * with the SolutionAnalysis class. + */ + + + +#include +#include + + +/** Example for qpOASES main function using the SolutionAnalysis class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t H_new[2*2] = { 1.0, 0.5, 0.5, 0.5 }; + real_t A_new[1*2] = { 1.0, 5.0 }; + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + + /* Setting up SQProblem object and solution analyser. */ + SQProblem example( 2,1 ); + SolutionAnalysis analyser; + + /* Solve first QP ... */ + int_t nWSR = 10; + example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + + /* ... and analyse it. */ + real_t maxKktViolation = analyser.getKktViolation( &example ); + printf( "maxKktViolation: %e\n", maxKktViolation ); + + QPOASES_TEST_FOR_TOL( maxKktViolation,1e-15 ); + + + /* Solve second QP ... */ + nWSR = 10; + example.hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,0 ); + + /* ... and analyse it. */ + maxKktViolation = analyser.getKktViolation( &example ); + printf( "maxKktViolation: %e\n", maxKktViolation ); + + QPOASES_TEST_FOR_TOL( maxKktViolation,2e-15 ); + + +// ------------ VARIANCE-COVARIANCE EVALUATION -------------------- + + real_t *Var = new real_t[5*5]; + real_t *Primal_Dual_Var = new real_t[5*5]; + + int_t run1, run2; + for( run1 = 0; run1 < 5*5; run1++ ) + Var[run1] = 0.0; + + Var[0] = 1.0; + Var[6] = 1.0; + +// ( 1 0 0 0 0 ) +// ( 0 1 0 0 0 ) +// Var = ( 0 0 0 0 0 ) +// ( 0 0 0 0 0 ) +// ( 0 0 0 0 0 ) + + + analyser.getVarianceCovariance( &example, Var,Primal_Dual_Var ); + + printf("\nPrimal_Dual_VAR = \n"); + for( run1 = 0; run1 < 5; run1++ ){ + for( run2 = 0; run2 < 5; run2++ ){ + printf(" %10f", Primal_Dual_Var[run1*5+run2]); + } + printf("\n"); + } + + delete[] Primal_Dual_Var; + delete[] Var; + + QPOASES_TEST_FOR_NEAR( Primal_Dual_Var[3*5+3], 26.0 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_example4.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_example4.cpp new file mode 100644 index 0000000..6ee37b5 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_example4.cpp @@ -0,0 +1,206 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_example4.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2009-2017 + * + * Very simple example for testing qpOASES (using the possibility to specify + * user-defined constraint product function). + */ + + + +#include + +#include +#include "../../examples/example4CP.cpp" +#include + + +/** Example for qpOASES main function using the possibility to specify + * user-defined constraint product function. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t i,j; + + /* Setup data of first QP... */ + real_t H[7*7]; + real_t A[50*7]; + real_t g[7]; + real_t lbA[50]; + + /* ( 1.0 0.5 | ) + * ( 0.5 2.0 | ) + * ( --------+------------------- ) + * H = ( | 1e-6 ) + * ( | 1e-6 ) + * ( | ... ) + * ( | 1e-6 ) */ + for( i=0; i<7*7; ++i ) + H[i] = 0.0; + for( i=2; i<7; ++i ) + H[i*7+i] = 1.0e-6; + H[0] = 1.0; + H[1] = 0.5; + H[7] = 0.5; + H[8] = 2.0; + + /* ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | 1.0 ) + * A = ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) */ + for( i=0; i<50*7; ++i ) + A[i] = 0.0; + for( i=0; i<50; ++i ) + { + for( j=0; j<2; ++j ) + A[i*7+j] = (real_t)rand() / (real_t)RAND_MAX; + + A[i*7 + (i/10)+2] = 1.0; + } + + /* ( -1.0 ) + * ( -0.5 ) + * ( ---- ) + * g = ( ) + * ( ) + * ( ) + * ( ) */ + for( i=0; i<7; ++i ) + g[i] = 0.0; + g[0] = -1.0; + g[1] = -0.5; + + for( i=0; i<50; ++i ) + lbA[i] = 1.0; + + /* ... and setting up user-defined constraint product function. */ + MyConstraintProduct myCP( 7,50,A ); + + + /* Setting up QProblem object and set construct product function. */ + QProblem exampleCP( 7,50 ); + exampleCP.setPrintLevel( PL_NONE ); + + exampleCP.setConstraintProduct( &myCP ); + + + /* Solve first QP. */ + real_t cputime = 1.0; + int_t nWSR = 100; + exampleCP.init( H,g,A,0,0,lbA,0, nWSR,&cputime ); + + + /* Solve second QP using a modified gradient. */ + g[0] = -2.0; + g[1] = 0.5; + + cputime = 1.0; + nWSR = 100; + exampleCP.hotstart( g,0,0,lbA,0, nWSR,&cputime ); + + /* Get and print solution of second QP. */ + real_t xOptCP[7]; + real_t yOptCP[7+50]; + exampleCP.getPrimalSolution( xOptCP ); + exampleCP.getDualSolution( yOptCP ); + printf( "\nxOpt = [ %e, %e, %e ... ]; objVal = %e\n", xOptCP[0],xOptCP[1],xOptCP[2],exampleCP.getObjVal() ); + printf( "CPU time: %.3f microseconds\n\n", cputime*1.0e6 ); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzerCP; + + analyzerCP.getKktViolation( &exampleCP, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + + /* Do the same without specifying constraint product. */ + QProblem example( 7,50 ); + example.setPrintLevel( PL_NONE ); + + /* Solve first QP. */ + g[0] = -1.0; + g[1] = -0.5; + + cputime = 1.0; + nWSR = 100; + example.init( H,g,A,0,0,lbA,0, nWSR,&cputime ); + + /* Solve second QP using a modified gradient. */ + g[0] = -2.0; + g[1] = 0.5; + + cputime = 1.0; + nWSR = 100; + example.hotstart( g,0,0,lbA,0, nWSR,&cputime ); + + /* Get and print solution of second QP. */ + real_t xOpt[7]; + real_t yOpt[7+50]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e, %e ... ]; objVal = %e\n", xOpt[0],xOpt[1],xOpt[2],example.getObjVal() ); + printf( "CPU time: %.3f microseconds\n\n", cputime*1.0e6 ); + + /* Compute KKT tolerances */ + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + for( int_t ii=0; ii<7; ++ii ) + QPOASES_TEST_FOR_NEAR( xOptCP[ii],xOpt[ii] ); + + for( int_t ii=0; ii<7+50; ++ii ) + QPOASES_TEST_FOR_NEAR( yOptCP[ii],yOpt[ii] ); + + QPOASES_TEST_FOR_NEAR( exampleCP.getObjVal(),example.getObjVal() ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_example5.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_example5.cpp new file mode 100644 index 0000000..6add109 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_example5.cpp @@ -0,0 +1,204 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_example5.cpp + * \author Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2011-2017 + * + * Very simple example for testing qpOASES (using the possibility to + * compute the local linear feedback law) + */ + + + +#include + +#include +#include "../../examples/example4CP.cpp" +#include + + +/** Example for qpOASES main function using the possibility to specify + * user-defined constraint product function. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t i,j,jj; + real_t d = 0.0; + + /* Setup data of first QP... */ + real_t H[7*7]; + real_t A[50*7]; + real_t g[7]; + real_t lbA[50]; + + /* ( 1.0 0.5 | ) + * ( 0.5 2.0 | ) + * ( --------+------------------- ) + * H = ( | 1e-6 ) + * ( | 1e-6 ) + * ( | ... ) + * ( | 1e-6 ) */ + for( i=0; i<7*7; ++i ) + H[i] = 0.0; + for( i=2; i<7; ++i ) + H[i*7+i] = 1.0e-6; + H[0] = 1.0; + H[1] = 0.5; + H[7] = 0.5; + H[8] = 2.0; + + /* ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | 1.0 ) + * A = ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) + * ( x.x x.x | ... ) + * ( x.x x.x | 1.0 ) */ + for( i=0; i<50*7; ++i ) + A[i] = 0.0; + for( i=0; i<50; ++i ) + { + for( j=0; j<2; ++j ) + A[i*7+j] = (real_t)rand() / (real_t)RAND_MAX; + + A[i*7 + (i/10)+2] = 1.0; + } + + /* ( -1.0 ) + * ( -0.5 ) + * ( ---- ) + * g = ( ) + * ( ) + * ( ) + * ( ) */ + for( i=0; i<7; ++i ) + g[i] = 0.0; + g[0] = -1.0; + g[1] = -0.5; + + for( i=0; i<50; ++i ) + lbA[i] = 1.0; + + /* ... and setting up user-defined constraint product function. */ + MyConstraintProduct myCP( 7,50,A ); + + + /* Setting up QProblem object and set construct product function. */ + QProblem example( 7,50 ); + example.setConstraintProduct( &myCP ); + + + /* Solve first QP. */ + real_t cputime = 1.0; + int_t nWSR = 100; + example.init( H,g,A,0,0,lbA,0, nWSR,&cputime ); + + /* Get and print solution of QP. */ + real_t xOpt[7], yOpt[7+50]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + + + /* Compute local linear feedback law */ + const int_t n_rhs = 7+7+50; + real_t g_in[7*n_rhs]; + real_t b_in[7*n_rhs]; + real_t bA_in[50*n_rhs]; + real_t x_out[7*n_rhs]; + real_t y_out[(7+50)*n_rhs]; + + int_t ii; + memset (g_in, 0, sizeof (g_in)); + memset (b_in, 0, sizeof (b_in)); + memset (bA_in, 0, sizeof (bA_in)); + + for ( ii = 0; ii < 7; ++ii ) + g_in[ii*7 + ii] = 1.0; + for ( ii = 0; ii < 7; ++ii ) + b_in[(ii+7)*7 + ii] = 1.0; + for ( ii = 0; ii < 50; ++ii ) + bA_in[(ii+14)*50 + ii] = 1.0; + + example.solveCurrentEQP ( n_rhs, g_in, b_in, b_in, bA_in, bA_in, x_out, y_out ); + + /* Verify validity of local feedback law by perturbation and hot starts */ + real_t perturb = 1.0e-6; + real_t nrm = 0.0; + for ( ii = 0; ii < n_rhs; ++ii ) + { + for ( jj = 0; jj < 7; ++jj ) + g_in[ii*7 + jj] = g[jj] + g_in[ii*7+jj]*perturb; + for ( jj = 0; jj < 50; ++jj ) + bA_in[ii*50 + jj] = lbA[jj] + bA_in[ii*50+jj]*perturb; + + nWSR = 100; + example.hotstart( &g_in[ii*7],0,0,&bA_in[ii*50],0, nWSR, 0 ); + + real_t xPer[7], yPer[7+50]; + example.getPrimalSolution( xPer ); + example.getDualSolution( yPer ); + + for ( jj = 0; jj < 7; ++jj ) + { + d = getAbs (x_out[ii*7+jj]*perturb - (xPer[jj]-xOpt[jj]) ); + if (nrm < d) nrm=d; + } + for ( jj = 0; jj < 7+50; ++jj ) + { + d = getAbs (y_out[ii*(7+50)+jj]*perturb - (yPer[jj]-yOpt[jj]) ); + if (nrm < d) nrm=d; + } + } + printf ("Maximum perturbation over all directions: %e\n", nrm); + + QPOASES_TEST_FOR_TOL( nrm,1e-15 ); + + + /* // print feedback matrix + for (ii = 0; ii < n_rhs; ++ii) + { + printf ("x: "); + for (jj = 0; jj < 7; ++jj ) + printf ("%8.2e ", x_out[ii*7+jj]); + printf (" y: "); + for (jj = 0; jj < 7+50; ++jj ) + printf ("%8.2e ", y_out[ii*(7+50)+jj]); + printf("\n"); + } +*/ + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_example6.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_example6.cpp new file mode 100644 index 0000000..afe7225 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_example6.cpp @@ -0,0 +1,109 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_example6.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Example that caused troubles in an earlier release. + */ + + + +#include +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[5*5] = { 1.224642131370767e+01, 2.908638763113702e+00, 0.0, 0.0, 0.0, + 2.908638763113702e+00, 2.497106275003180e+00, 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 5.158460640334052e-02, 4.723556059962540e-02, + 0.0, 0.0, 0.0, 4.723556059962540e-02, 4.325317843302175e-02 }; + real_t A[2*5] = { -1.404358970692652e+00, -2.556613491156063e+00, 3.202524559238066e+00, -1.0, 0.0, + 6.587910295430314e-01, -5.349454475937998e-01, 4.391976356955536e-01, 0.0, -1.0 }; + real_t g[5] = { 2.474135331302147e+01, + 5.857286430296258e+00, + 2.359382646348721e-01, + 1.721047069188781e-01, + 1.575947337774199e-01 }; + real_t lb[5] = { -10.0, -10.0, -10.0, -10.0, -10.0 }; + real_t ub[5] = { 10.0, 10.0, 10.0, 10.0, 10.0 }; + real_t lbA[2] = { 1.643135416077167e+00, 1.056813028189597e+00 }; + real_t ubA[2] = { 1.643135416077167e+00, 1.056813028189597e+00 }; + + /* Setting up QProblem object. */ + QProblem example( 5,2 ); + + Options options; + //options.enableFlippingBounds = BT_FALSE; + //options.enableEqualities = BT_TRUE; + //options.initialStatusBounds = ST_INACTIVE; + example.setOptions( options ); + example.setPrintLevel( PL_NONE ); + + /* Solve first QP. */ + returnValue retVal; + int_t simpleStatus = -1; + + int_t nWSR = 10; + retVal = example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + simpleStatus = getSimpleStatus( retVal,BT_TRUE ); + + QPOASES_TEST_FOR_TRUE( simpleStatus == 0 ); + + + /* Get and print solution of second QP. */ + real_t xOpt[5]; + real_t yOpt[5+2]; + + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e, ... ]; objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() ); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-14 ); + QPOASES_TEST_FOR_TOL( feas,1e-14 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_example7.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_example7.cpp new file mode 100644 index 0000000..3c18931 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_example7.cpp @@ -0,0 +1,87 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_example7.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Example that caused troubles in an earlier release. + */ + + + +#include +#include + + +int main( ) +{ + USING_NAMESPACE_QPOASES + + real_t H[5*5] = {0.8514828085899353, -0.15739890933036804, -0.081726007163524628, -0.530426025390625, 0.16773293912410736, -0.15739890933036804, 1.1552412509918213, 0.57780224084854126, -0.0072606131434440613, 0.010559185408055782, -0.081726007163524628, 0.57780224084854126, 0.28925251960754395, 5.324830453901086e-006, -3.0256599075073609e-006, -0.530426025390625, -0.0072606131434440613, 5.324830453901086e-006, 0.35609596967697144, -0.15124998986721039, 0.16773293912410736, 0.010559185408055782, -3.0256599075073609e-006, -0.15124998986721039, 0.15129712224006653}; + real_t g[5] = {0.30908384919166565, 0.99325823783874512, 0.49822014570236206, -0.26309865713119507, 0.024296050891280174}; + real_t A[5*5] = {1,0,0,0,0, + 0,1,0,0,0, + 0,0,1,0,0, + 0,0,0,1,0, + 0,0,0,0,1}; + real_t lb[5] = {-0.052359879016876221, -0.052359879016876221, -0.052359879016876221, -0.052359879016876221, -0.052359938621520996}; + real_t ub[5] = { 0.052359879016876221, 0.052359879016876221, 0.052359879016876221, 0, 0}; + real_t lbA[5] = {-0.052359879016876221, -0.052359879016876221, -0.052359879016876221, -0.052359879016876221, -0.052359938621520996}; + real_t ubA[5] = {0.052359879016876221, 0.052359879016876221, 0.052359879016876221, 0, 0}; + + /* Setting up QProblem object. */ + QProblem example( 5,5 ); + + /* Solve first QP. */ + int_t nWSR = 100; + returnValue retVal = example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + printf( "nWSR = %d, retVal = %d (%s)\n", (int)nWSR,retVal,getGlobalMessageHandler( )->getErrorCodeMessage(retVal) ); + + + real_t sol[5] = {0}; + real_t yOpt[5+5] = {0}; + example.getPrimalSolution(sol); + example.getDualSolution(yOpt); + + printf("l1 = %f, l2 = %f, l3 = %f, l4 = %f, l5 = %f\n",(float) lb[0], (float) lb[1], (float) lb[2], (float) lb[3], (float) lb[4]); + printf("x1 = %f, x2 = %f, x3 = %f, x4 = %f, x5 = %f\n",(float) sol[0], (float) sol[1], (float) sol[2], (float) sol[3], (float) sol[4]); + printf("u1 = %f, u2 = %f, u3 = %f, u4 = %f, u5 = %f\n",(float) ub[0], (float) ub[1], (float) ub[2], (float) ub[3], (float) ub[4]); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + return TEST_PASSED; +} + diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_exampleLP.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_exampleLP.cpp new file mode 100644 index 0000000..16e0c81 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_exampleLP.cpp @@ -0,0 +1,115 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_exampleLP.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2008-2017 + * + * Very simple example for solving a LP sequence using qpOASES. + */ + + + +#include +#include + + +/** Example for qpOASES main function solving LPs. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + real_t tol = 1e-14; + + /* Setup data of first LP. */ + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second LP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + + /* Setting up QProblem object with zero Hessian matrix. */ + QProblem example( 2,1,HST_ZERO ); + + Options options; + /*options.setToMPC();*/ + example.setOptions( options ); + + /* Solve first LP. */ + int_t nWSR = 10; + example.init( 0,g,A,lb,ub,lbA,ubA, nWSR,0 ); + + real_t xOpt[2]; + real_t yOpt[2+1]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + printf( "%d\n",example.getHessianType() ); + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,tol ); + QPOASES_TEST_FOR_TOL( feas,tol ); + QPOASES_TEST_FOR_TOL( cmpl,tol ); + + + /* Solve second LP. */ + nWSR = 10; + example.hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,0 ); + + + /* Get and print solution of second LP. */ + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() ); + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,tol ); + QPOASES_TEST_FOR_TOL( feas,tol ); + QPOASES_TEST_FOR_TOL( cmpl,tol ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_externalChol1.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_externalChol1.cpp new file mode 100644 index 0000000..b3f029f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_externalChol1.cpp @@ -0,0 +1,101 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_externalChol1.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2015-2017 + * + * Very simple example for testing qpOASES using the QProblem class + * and providing a pre-computed Cholesky factor of the Hessian matrix. + */ + + + +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 }; + real_t A[1*2] = { 1.0, 1.0 }; + real_t g[2] = { 1.5, 1.0 }; + real_t lb[2] = { 0.5, -2.0 }; + real_t ub[2] = { 5.0, 2.0 }; + real_t lbA[1] = { -1.0 }; + real_t ubA[1] = { 2.0 }; + + /* Setup data of second QP. */ + real_t g_new[2] = { 1.0, 1.5 }; + real_t lb_new[2] = { 0.0, -1.0 }; + real_t ub_new[2] = { 5.0, -0.5 }; + real_t lbA_new[1] = { -2.0 }; + real_t ubA_new[1] = { 1.0 }; + + real_t R[2*2] = { sqrt(1.0), 0.0, 0.0, sqrt(0.5) }; + + + /* Setting up QProblem object. */ + QProblem example( 2,1 ); + + Options options; + example.setOptions( options ); + + /* Solve first QP. */ + int_t nWSR = 10; + example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0, 0,0,0,0, R ); + + /* Get and print solution of first QP. */ + real_t xOpt[2]; + real_t yOpt[2+1]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2],example.getObjVal() ); + + /* Solve second QP. */ + nWSR = 10; + example.hotstart( g_new,lb_new,ub_new,lbA_new,ubA_new, nWSR ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf( "\nxOpt = [ %e, %e ]; yOpt = [ %e, %e, %e ]; objVal = %e\n\n", + xOpt[0],xOpt[1],yOpt[0],yOpt[1],yOpt[2],example.getObjVal() ); + + example.printOptions(); + /*example.printProperties();*/ + + return 0; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_gradientShift.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_gradientShift.cpp new file mode 100644 index 0000000..4317475 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_gradientShift.cpp @@ -0,0 +1,125 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2009 by Hans Joachim Ferreau et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_gradientShift.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Simple test case which caused troubles in version 2.0. + */ + + + +#include +#include +#include +#include + + +/** Running simple test case which caused troubles in version 2.0. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + + real_t H[2*2] = { 0.055944055944055944,0, 0, 0 }; + real_t A[1*2] = { 0.70514808036997589, -1 }; + //real_t g[2] = { -15.830543073928741, 0}; + real_t g[2] = { 0, 0 }; + real_t lb[2] = { 137.00242299940646, 154.0 }; + real_t ub[2] = { 282.19008595111382, 198.98579740786641}; + real_t lbA[1] = {0.0}; + real_t ubA[1] = {0.0}; + + real_t gStart=-16.4; + + /* Setting up QProblem object. */ + QProblem example( 2,1 ); + Options options; + options.setToMPC(); + options.printLevel = REFER_NAMESPACE_QPOASES PL_NONE; + example.setOptions( options ); + + returnValue ret; + int_t nWSR = 10; + real_t Xopt[2]={0.0,0.0}; + //fprintf(stdFile, "g[0]\t,\tReturn code\n"); + int_t errorCount=0; + int_t i=0; + real_t granularity=0.00001; + g[0]=gStart; + for( i=0; i< 70000; i++) + { + + g[0] += granularity; + /* Solve first QP. */ + nWSR = 10; + ret= example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + if (ret != SUCCESSFUL_RETURN) + { + //fprintf(stdFile, "%f\t,\t%d\n",g[0],ret); + errorCount++; + } + //fprintf(stdFile, "%f\t,\t%d\n",g[0],ret); + } + example.printProperties(); + fprintf( stdFile, "#Number of optimizer runs: %d\n",(int)i ); + fprintf( stdFile, "#g[0] test interval: %f < g[0] < %f\n",gStart,g[0] ); + fprintf( stdFile, "#Granularity: %f\n",granularity); + real_t errorPercent = real_t(errorCount)/real_t(i)*100.0; + fprintf( stdFile, "#Number of errors (error): %d (%f)\n",(int)errorCount,errorPercent ); + + example.getPrimalSolution(Xopt); + fprintf( stdFile,"#Optimization primary result : LD=%f BD=%f\n",Xopt[0], Xopt[1]); + + real_t Yopt[3]={0.0,0.0,0.0}; + example.getDualSolution(Yopt); + fprintf( stdFile,"#Optimization dual result : %f %f %f8\n",Yopt[0], Yopt[1], Yopt[2]); + + int_t Nc=0; + Nc=example.getNC(); + fprintf( stdFile,"#Number of constraints : %d\n",(int)Nc ); + + int_t Nec=0; + Nec=example.getNEC(); + fprintf( stdFile,"#Number of equality constraints : %d\n",(int)Nec ); + + int_t Nac=0; + Nac=example.getNAC(); + fprintf( stdFile,"#Number of active constraints : %d\n",(int)Nac ); + + int_t Niac=0; + Niac=example.getNIAC(); + fprintf( stdFile,"#Number of inactive constraints : %d\n",(int)Niac ); + + QPOASES_TEST_FOR_TRUE( errorCount == 0 ) + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_guessedWS1.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_guessedWS1.cpp new file mode 100644 index 0000000..8ad55f1 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_guessedWS1.cpp @@ -0,0 +1,153 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_guessedWS1.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2014-2017 + * + * Very simple example for testing qpOASES (using QProblem class). + */ + + + +#include +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[4*4] = { 1.0, 0.0, 0.0, 0.5, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.0, 0.0, 1.0 }; + real_t A[3*4] = { 1.0, 1.0, 0.0, 0.0, + 1.0, 1.0, 1.0, 0.0, + 1.0, 1.0, 1.0, 1.0 }; + real_t g[4] = { 1.5, 1.0, -1.0, -1.0 }; + real_t lb[4] = { 0.5, -2.0, 0.0, 0.0 }; + real_t ub[4] = { 1.0, 2.0, 1.0, 0.5 }; + real_t lbA[3] = { -1.0, -1.0, -1.0 }; + real_t ubA[3] = { 0.0, 0.25, 1.0 }; + + + + /* Setting up QProblem object. */ + QProblem example( 4,3 ); + + Options options; + example.setOptions( options ); + + /* Solve first QP. */ + int_t nWSR = 10; + example.init( H,g,A,lb,ub,lbA,ubA, nWSR ); + + /* Get and print solution of second QP. */ + real_t xOpt[4]; + real_t yOpt[4+3]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + print( xOpt,4,"xOpt" ); + print( yOpt,4+3,"yOpt" ); + printf( "objVal = %e\n\n", example.getObjVal() ); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + + /* Solve first QP again (with optimal guess for working set). */ + Bounds prevBounds; + Constraints prevConstraints; + + example.getBounds( prevBounds ); + example.getConstraints( prevConstraints ); + + nWSR = 10; + example.hotstart( g,lb,ub,lbA,ubA, nWSR,0,&prevBounds,&prevConstraints ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + print( xOpt,4,"xOpt" ); + print( yOpt,4+3,"yOpt" ); + printf( "objVal = %e\n\n", example.getObjVal() ); + + /* Compute KKT tolerances */ + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + + /* Solve first QP again (with inaccurate guess for working set). */ + prevBounds.print(); + prevBounds.rotate(1); + //prevBounds.moveFixedToFree(0); + prevBounds.print(); + + prevConstraints.print(); + //prevConstraints.moveInactiveToActive(0,ST_LOWER); + prevConstraints.moveActiveToInactive(1); + prevConstraints.print(); + + nWSR = 10; + example.hotstart( g,lb,ub,lbA,ubA, nWSR,0,&prevBounds,&prevConstraints ); + + /* Get and print solution of second QP. */ + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + print( xOpt,4,"xOpt" ); + print( yOpt,4+3,"yOpt" ); + printf( "objVal = %e\n\n", example.getObjVal() ); + + /* Compute KKT tolerances */ + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-15 ); + QPOASES_TEST_FOR_TOL( feas,1e-15 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_hs268.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_hs268.cpp new file mode 100644 index 0000000..0b687a8 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_hs268.cpp @@ -0,0 +1,106 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_hs268.cpp + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2010-2017 + * + * Unit test running all benchmark examples stored in problems directory. + */ + + + +#include +#include +#include +#include +#include + + +/** Run benchmark examples. */ +int main( int argc, char *argv[] ) +{ + USING_NAMESPACE_QPOASES + + /* 1) Define benchmark arguments. */ + BooleanType isSparse = BT_FALSE; + //BooleanType isSparse = BT_TRUE; + Options options; + options.setToDefault(); + //options.setToMPC(); + //options.setToReliable(); + //options.printLevel = PL_LOW; + //options.printLevel = PL_MEDIUM; + options.printLevel = PL_TABULAR; + + + int_t nWSR; + int_t npass = 0; + real_t maxCPUtime; /* seconds */ + real_t maxStationarity = 0.0, maxFeasibility = 0.0, maxComplementarity = 0.0; + + char oqpProblem[MAX_STRING_LENGTH]; + char problem[] = "HS268"; + returnValue returnvalue; + + + /* 3) Run benchmark. */ + fprintf(stdFile, "%-10s ", problem); + fflush(stdFile); + + snprintf(oqpProblem, MAX_STRING_LENGTH, "../testing/cpp/data/problems/%s/", problem); + maxCPUtime = 100.0; + nWSR = 100; + + returnvalue = runOqpBenchmark( oqpProblem, isSparse, options, + nWSR, maxCPUtime, maxStationarity, maxFeasibility, maxComplementarity + ); + + if(returnvalue == RET_UNABLE_TO_READ_BENCHMARK) + return TEST_DATA_NOT_FOUND; + + if(returnvalue == SUCCESSFUL_RETURN) + npass += 1; + + QPOASES_TEST_FOR_TRUE( npass >= 1 ); + + printf( "\n" ); + printf( "stat: %e\n", maxStationarity ); + printf( "feas: %e\n", maxFeasibility ); + printf( "cmpl: %e\n", maxComplementarity ); + + QPOASES_TEST_FOR_TOL( maxStationarity, 1e-11 ); + QPOASES_TEST_FOR_TOL( maxFeasibility, 1e-14 ); + QPOASES_TEST_FOR_TOL( maxComplementarity, 1e-14 ); + + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_identitySqproblem.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_identitySqproblem.cpp new file mode 100644 index 0000000..b6d3276 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_identitySqproblem.cpp @@ -0,0 +1,129 @@ +#include + +int main(int argc, char** argv) +{ + USING_NAMESPACE_QPOASES + + //Quadratic prog param + real_t H[7*7]; //here H = Id + real_t A[6*7] = {-0.270792, -0.140175, -0.249325, -0.412277, -0.250952, -0.298071, 1.49078e-19, 0.534738, 0.00704892, 0.483388, -0.193107, 0.302895, -0.2471, -2.1684e-17, 0, -0.451464, 0.117068, -0.348254, 0.00703103, 0.00620952, -7.96211e-20, 0, 0.0502231, 0.393264, -0.584145, 0.758854, -0.637889, -0.023751, 0, 0.998738, -0.0197759, 0.766682, 0.632337, 0.769921, 0.00352803, 1, 4.89658e-12, 0.919213, 0.266407, -0.155855, 0.017872, -0.999712}; //the jacobian + real_t g[7]; //set to 0 + real_t lb[7]; //joints lower velocity limits + real_t ub[7]; //joints upper velocity limits + //Position control - no orientation + real_t lbA[6] = {0.00442514, -0.122699, -0.0725897, 0, 0, 0}; //stylus velocity : ubA = lbA + real_t ubA[6] = {0.00442514, -0.122699, -0.0725897, 0, 0, 0};; //stylus velocity : ubA = lbA + int_t nWSR = 1000; //specifies the maximum number of working set recalculation + real_t cpu_time = 1.0; //maximum allowed CPU time(s) for the whole initialisation + real_t xOpt[7]; + + H[0] = 1.0; + for(int i=1; i<7*7; ++i ) + { + if (i%8 == 0) + H[i] = 1.0; + else + H[i] = 0.0; + } + for (int i = 0 ; i < 7 ; i++) + { + g[i] = 0.0; //g = 0 + } + + //joints velocities limits + lb[0] = -1.5; //s0 joints lower limits + lb[1] = -1.5; //s1 joints lower limits + lb[2] = -1.5; //e0 joints lower limits + lb[3] = -1.5; //e1 joints lower limits + lb[4] = -4.0; //w0 joints lower limits + lb[5] = -4.0; //w1 joints lower limits + lb[6] = -4.0; //w2 joints lower limits + for (int i = 0 ; i < 7 ; i++) + { + ub[i] = -lb[i]; //joints lower limits + } + cpu_time = 1.0; //maximum amount of cpu time + nWSR = 100; + + /*//linear and angular velocities + the first three elements represent the linear velocity (px, py, pz) while + the next three are the angular velocity (yaw, pitch, roll)*/ + for (int i = 0 ; i < 6 ; i++) + { + lbA[i] = 0.0; + ubA[i] = lbA[i]; + } + + printf("Initialisation of the QP problem"); + SQProblem joints_velocities(7,6); //create qp problem of 7 variables and 6 constraints with the hessian matrix set with the identity + joints_velocities.init(H,g,A,lb,ub,lbA,ubA, nWSR, &cpu_time); + if (joints_velocities.isSolved()) + printf( "qp problem solved"); + if (joints_velocities.isInfeasible()) + printf( "qp problem not feasible"); + joints_velocities.getPrimalSolution( xOpt ); + printf( "\nxOpt = [ %e, %e, %e, %e, %e, %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1], xOpt[2],xOpt[3], xOpt[4],xOpt[5], xOpt[6], joints_velocities.getObjVal() ); + + + A[0] = -0.284328; + A[1] = -0.118524; + A[2] = -0.190925; + A[3] = -0.350569; + A[4] = -0.318565; + A[5] = -0.229695; + A[6] = 3.93023e-19; + A[7] = 0.559749 ; + A[8] = 0.0299793; + A[9] = 0.431302; + A[10] = -0.0760635; + A[11] = 0.234798; + A[12] = -0.311727; + A[13] = -9.11272e-17; + A[14] = 0; + A[15] = -0.403937; + A[16] = 0.293076; + A[17] = -0.267321; + A[18] = 0.00656818; + A[19] = 0.00311694; + A[20] = -3.12555e-19; + A[21] = 0; + A[22] = 0.245215; + A[23] = 0.688118; + A[24] = -0.611048; + A[25] = 0.592551; + A[26] = -0.804865; + A[27] = -0.0181344; + A[28] = 0; + A[29] = 0.969469; + A[30] = -0.174051; + A[31] = 0.38453; + A[32] = 0.801775; + A[33] = 0.593226; + A[34] = 0.003365; + A[35] = 1; + A[36] = 4.89658e-12; + A[37] = 0.704415; + A[38] = 0.691923; + A[39] = 0.0777117; + A[40] = 0.0165947; + A[41] = -0.99983; + + lbA[0] = -2.4834; + lbA[1] = -1.4414; + lbA[2] = -1.85119; + lbA[3] = 0; + lbA[4] = 0; + lbA[5] = 0; + + for (int i = 0 ; i < 6 ; i++) + { + ubA[i] = lbA[i]; + } + + nWSR = 100; + cpu_time = 1.0; + joints_velocities.init(H,g,A,lb,ub,lbA,ubA, nWSR, &cpu_time); + joints_velocities.getPrimalSolution( xOpt ); + printf( "\nxOpt = [ %e, %e, %e, %e, %e, %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1], xOpt[2],xOpt[3], xOpt[4],xOpt[5], xOpt[6], joints_velocities.getObjVal() ); + return 0; +} diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_indexlist.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_indexlist.cpp new file mode 100644 index 0000000..b69e4d7 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_indexlist.cpp @@ -0,0 +1,96 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_indexlist.cpp + * \author Andreas Potschka, Hans Joachim Ferreau + * \version 3.2 + * \date 2010-2017 + * + * Unit test for Indexlist class. + */ + + + +#include +#include + + +/** Test Indexlist sorting */ +int main() +{ + USING_NAMESPACE_QPOASES + + Indexlist il(10); + int_t i, *numbers; + + il.addNumber(1); + il.addNumber(3); + il.addNumber(5); + il.addNumber(2); + il.addNumber(4); + il.addNumber(0); + il.addNumber(7); + il.addNumber(6); + il.addNumber(8); + il.addNumber(9); + + il.getNumberArray(&numbers); + fprintf(stdFile, "Unsorted numbers: "); + for (i = 0; i < 10; i++) + fprintf(stdFile, " %2d", (int)(numbers[i]) ); + fprintf(stdFile, "\n"); + + fprintf(stdFile, "Unsorted index of number 0: %3d\n", (int)(il.getIndex(0)) ); + + QPOASES_TEST_FOR_TRUE( il.getIndex(0) == 5 ) + + il.removeNumber(5); + fprintf(stdFile, "Unsorted index of (removed) number 5: %3d\n", (int)(il.getIndex(5)) ); + + QPOASES_TEST_FOR_TRUE( il.getIndex(5) == -1 ) + + il.getNumberArray(&numbers); + fprintf(stdFile, "Unsorted numbers: "); + for (i = 0; i < 9; i++) + fprintf(stdFile, " %2d", (int)(numbers[i]) ); + fprintf(stdFile, "\n"); + + il.swapNumbers(2, 7); + + il.getNumberArray(&numbers); + fprintf(stdFile, "Unsorted numbers: "); + for (i = 0; i < 9; i++) + fprintf(stdFile, " %2d", (int)(numbers[i]) ); + fprintf(stdFile, "\n"); + + QPOASES_TEST_FOR_TRUE( numbers[2] == 7 ) + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_infeasible1.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_infeasible1.cpp new file mode 100644 index 0000000..50882d0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_infeasible1.cpp @@ -0,0 +1,104 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_infeasible1.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2015-2017 + * + * Example to test occurence of infeasible QP. + */ + + + +#include +#include + + +/** Example for qpOASES main function using the QProblem class. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* Setup data of first QP. */ + real_t H[5*5] = { 1.224642131370767e+01, 2.908638763113702e+00, 0.0, 0.0, 0.0, + 2.908638763113702e+00, 2.497106275003180e+00, 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 5.158460640334052e-02, 4.723556059962540e-02, + 0.0, 0.0, 0.0, 4.723556059962540e-02, 4.325317843302175e-02 }; + real_t A[2*5] = { -1.404358970692652e+00, -2.556613491156063e+00, 3.202524559238066e+00, -1.0, 0.0, + 6.587910295430314e-01, -5.349454475937998e-01, 4.391976356955536e-01, 0.0, -1.0 }; + real_t g[5] = { 2.474135331302147e+01, + 5.857286430296258e+00, + 2.359382646348721e-01, + 1.721047069188781e-01, + 1.575947337774199e-01 }; + real_t lb[5] = { 5.0, 5.0, 8.0, 9.0, 5.0 }; + real_t ub[5] = { 10.0, 10.0, 10.0, 10.0, 10.0 }; + real_t lbA[2] = { 1.643135416077167e+00, 1.056813028189597e+00 }; + real_t ubA[2] = { 1.643135416077167e+00, 1.056813028189597e+00 }; + + /* Setting up QProblem object. */ + QProblem example( 5,2 ); + + Options options; + //options.enableFlippingBounds = BT_FALSE; + //options.enableEqualities = BT_TRUE; + //options.initialStatusBounds = ST_INACTIVE; + example.setOptions( options ); + example.setPrintLevel( PL_NONE ); + + /* Solve first QP. */ + returnValue retVal; + int_t simpleStatus = -1; + + int_t nWSR = 10; + retVal = example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 ); + simpleStatus = getSimpleStatus( retVal,BT_TRUE ); + + + /* Get and print solution of second QP. */ + real_t xOpt[5]; + real_t yOpt[5+2]; + + printf( "getPrimalSolution = %d\n", example.getPrimalSolution( xOpt ) ); + printf( "getDualSolution = %d\n", example.getDualSolution( yOpt ) ); + printf( "\nxOpt = [ %e, %e, %e, %e, %e ]; objVal = %e\n\n", xOpt[0],xOpt[1],xOpt[2],xOpt[3],xOpt[4],example.getObjVal() ); + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + + getKktViolation( 5,2, H,g,A,lb,ub,lbA,ubA, xOpt,yOpt, stat,feas,cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TRUE( simpleStatus == -2 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_janick1.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_janick1.cpp new file mode 100644 index 0000000..edaeafa --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_janick1.cpp @@ -0,0 +1,190 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_janick1.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + * + * Example that causes troubles when hotstarting. + */ + + + +#include +#include + +#include + + +//#define __MAKE_POS_DEF__ +#undef __MAKE_POS_DEF__ + +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t nWSR = 100; + /* Setting up QProblem object. */ + SQProblem example( 11,3 ); + + Options options; + options.setToFast(); + //options.setToDefault(); + //options.initialStatusBounds = qpOASES::ST_INACTIVE; + example.setOptions( options ); + + + /* Setup data of first QP. */ + real_t H[11*11] = { + 6.20100988531485e+00, 0.00000000000000e+00, 0.00000000000000e+00, -3.84861756786704e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -7.43268431723266e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 1.00000000000000e-01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -3.84861756786704e+00, 0.00000000000000e+00, 0.00000000000000e+00, 5.41188294952735e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 4.61304826562310e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.10000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 1.00000000000000e-01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.01000000000000e+01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.10000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -7.43268431723266e+00, 0.00000000000000e+00, 0.00000000000000e+00, 4.61304826562310e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -1.73544778892019e+01, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+01 + }; + real_t g[11] = { + -1.28196485091041e-07, 1.13322235104306e-08, 4.52417455660281e-06, 1.95881304363781e-07, 1.61991589634459e-06, 2.69786724710014e-09, 0.00000000000000e+00, 0.00000000000000e+00, -1.18185813270785e+02, 9.58903285459640e-06, 3.82276791847511e-06 + }; + real_t zLow[11] = { + -1.07876236159966e+01, -1.00000000002784e+12, -1.00000000000000e+12, 0.00000000000000e+00, -7.00000000000000e+00, -2.60479553037772e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -4.50000000000000e+01, -1.00000000000000e+12 + }; + real_t zUpp[11] = { + 9.99999999989212e+11, 9.99999999972157e+11, 1.00000000000000e+12, 4.68471854329546e+01, 7.00000000000000e+00, 9.99999999997395e+11, 1.00000000000000e+12, 1.00000000000000e+12, 0.00000000000000e+00, 4.50000000000000e+01, 1.00000000000000e+12 + }; + real_t D[11*3] = { + 1.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -1.00000000000000e-02, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -1.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -1.00000000000000e-02, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 1.00000000000000e+00, 0.00000000000000e+00, -1.00000000000000e-02, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00 + }; + real_t dLow[3] = { + -1.00000000000000e+12, -1.00000000000000e+12, -1.00000000000000e+12 + }; + real_t dUpp[3] = { + 2.12376384003361e-01, 4.78762361599664e+00, 8.95204469622285e-01 + }; + + #ifdef __MAKE_POS_DEF__ + H[9*11+9] += 30; + #endif + returnValue status = example.init( H,g,D,zLow,zUpp,dLow,dUpp, nWSR ); + printf("\nqpOASES_status = %d\n", (int)status ); + + /* Get and print solution of first QP. */ + real_t xOpt[11]; + real_t yOpt[11+3]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf("first QP:\n"); + for (int_t ii =0; ii<11; ++ii ) { + printf("x[%d] = %.3e\n", (int)ii, xOpt[ii]); + } + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "\nstat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-9 ); + QPOASES_TEST_FOR_TOL( feas,1e-7 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + + + nWSR = 100; + + /* Setup data of second QP. */ + real_t H2[11*11] = { + 6.20100988531485e+00, 0.00000000000000e+00, 0.00000000000000e+00, -3.84861756786704e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -7.43268433147671e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 1.00000000000000e-01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -3.84861756786704e+00, 0.00000000000000e+00, 0.00000000000000e+00, 5.41188294952735e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 4.61304827446359e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.10000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 1.00000000000000e-01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.01000000000000e+01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.10000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -7.43268433147671e+00, 0.00000000000000e+00, 0.00000000000000e+00, 4.61304827446359e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -1.73544778550554e+01, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+01 + }; + real_t g2[11] = { + -6.57752219998813e-04, 3.61759517784935e-04, -7.51224940044046e-05, 6.01232615232452e-04, 1.23562395380546e-04, 4.59040118744990e-05, 0.00000000000000e+00, 0.00000000000000e+00, -1.18185813270785e+02, 3.38813178901720e-21, 0.00000000000000e+00 + }; + real_t zLow2[11] = { + -2.41857058824735e-08, -2.77410094895458e-10, -9.90563843681406e-09, -3.85694249871449e-08, 4.50633213817586e-14, -2.22044604925031e-15, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -4.49999952054836e+01, -1.00000000000000e+12 + }; + real_t zUpp2[11] = { + -2.41857058824735e-08, -2.77410094895458e-10, -9.90563843681406e-09, -3.85694249871449e-08, 4.50633213817586e-14, -2.22044604925031e-15, 1.00000000000000e+12, 1.00000000000000e+12, 0.00000000000000e+00, 4.50000047945164e+01, 1.00000000000000e+12, + }; + real_t D2[11*3] = { + 1.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -1.00000000000000e-02, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -1.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -1.00000000000000e-02, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 1.00000000000000e+00, 0.00000000000000e+00, -1.00000000000000e-02, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00 + }; + real_t dLow2[3] = { + -1.00000000000000e+12, -1.00000000000000e+12, -1.00000000000000e+12 + }; + real_t dUpp2[3] = { + 2.12376363329877e-01, 4.78762363667012e+00, 8.95204496600957e-01 + }; + #ifdef __MAKE_POS_DEF__ + H2[9*11+9] += 30; + #endif + + + status = example.hotstart( H2,g2,D2,zLow2,zUpp2,dLow2,dUpp2, nWSR ); + printf("qpOASES_status = %d\n", (int)status ); + + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf("second QP:\n"); + for (int_t ii =0; ii<11; ++ii ) { + printf("x[%d] = %.3e\n", (int)ii, xOpt[ii]); + } + + /* Compute KKT tolerances */ + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-9 ); + QPOASES_TEST_FOR_TOL( feas,1e-7 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-12 ); + + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_janick2.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_janick2.cpp new file mode 100644 index 0000000..1202208 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_janick2.cpp @@ -0,0 +1,275 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_janick2.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2011-2017 + * + * Example that causes troubles when hotstarting. + */ + + +#include +#include +#include + +#define __MAKE_POS_DEF__ +// #undef __MAKE_POS_DEF__ + +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t nWSR = 100; + /* Setting up QProblem object. */ + SQProblem example( 11,3 ); + + Options options; + options.setToFast(); +// options.setToDefault(); + options.initialStatusBounds = REFER_NAMESPACE_QPOASES ST_INACTIVE; + + //options.terminationTolerance = 1.e-12; + options.initialStatusBounds = REFER_NAMESPACE_QPOASES ST_INACTIVE; + //options.enableFarBounds = REFER_NAMESPACE_QPOASES BT_FALSE; + //options.enableRegularisation = REFER_NAMESPACE_QPOASES BT_FALSE; + + example.setOptions( options ); + + + /* Setup data of first QP. */ + real_t H[11*11] = { + 6.20100988531485e+00, 0.00000000000000e+00, 0.00000000000000e+00, -3.84861756786704e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -7.43268431723266e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 1.00000000000000e-01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -3.84861756786704e+00, 0.00000000000000e+00, 0.00000000000000e+00, 5.41188294952735e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 4.61304826562310e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.10000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 1.00000000000000e-01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.01000000000000e+01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.10000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -7.43268431723266e+00, 0.00000000000000e+00, 0.00000000000000e+00, 4.61304826562310e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -1.73544778892019e+01, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+01, + }; + real_t g[11] = { +// 9.13378607947379e-07, +// 0.00000000000000e+00, +// 0.00000000000000e+00, +// -1.12448469735682e-06, +// 0.00000000000000e+00, +// 0.00000000000000e+00, +// 0.00000000000000e+00, +// 0.00000000000000e+00, +// -1.18185650936822e+02, +// 0.00000000000000e+00, +// 0.00000000000000e+00, + -6.93766478421491e-04, + 3.84943289898669e-04, + -3.63779116055460e-05, + 6.38114176725135e-04, + 1.85797765355698e-04, + 6.21922122437904e-05, + 0.00000000000000e+00, + 0.00000000000000e+00, + -1.18185758699839e+02, + 1.54357580390960e-05, + 5.39852809009711e-06, + }; + real_t zLow[11] = { + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + -4.50000000000000e+01, + -1.00000000000000e+12, + }; + real_t zUpp[11] = { + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 1.00000000000000e+12, + 1.00000000000000e+12, + 0.00000000000000e+00, + 4.50000000000000e+01, + 1.00000000000000e+12, + }; + real_t D[11*3] = { + 1.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -1.00000000000000e-02, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -1.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -1.00000000000000e-02, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 1.00000000000000e+00, 0.00000000000000e+00, -1.00000000000000e-02, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + }; + real_t dLow[3] = { + -1.00000000000000e+12, + -1.00000000000000e+12, + -1.00000000000000e+12, + }; + real_t dUpp[3] = { + 2.12376384003361e-01, + 4.78762361599664e+00, + 8.95204469622285e-01, + }; + + + #ifdef __MAKE_POS_DEF__ +// H[9*11+9] += 30; + H[8*11+8] += 30; + #endif + returnValue status = example.init( H,g,D,zLow,zUpp,dLow,dUpp, nWSR ); + printf("qpOASES_status = %d\n", (int)status ); + + /* Get and print solution of second QP. */ + real_t xOpt[11]; + real_t yOpt[11+3]; + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf("first QP:\n"); + for (int_t ii =0; ii<11; ++ii ) { + printf("x[%d] = %.3e\n", (int)ii, xOpt[ii]); + } + + /* Compute KKT tolerances */ + real_t stat, feas, cmpl; + SolutionAnalysis analyzer; + + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "\nstat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-9 ); + QPOASES_TEST_FOR_TOL( feas,1e-7 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + nWSR = 100; + + /* Setup data of second QP. */ + real_t H2[11*11] = { + 6.20101055067033e+00, 0.00000000000000e+00, 0.00000000000000e+00, -3.84861780549400e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -7.43268533746787e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 1.00000000000000e-01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -3.84861780549400e+00, 0.00000000000000e+00, 0.00000000000000e+00, 5.41188396792859e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 4.61304896387257e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.10000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 1.00000000000000e-01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.01000000000000e+01, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.10000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -7.43268533746787e+00, 0.00000000000000e+00, 0.00000000000000e+00, 4.61304896387257e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -1.73544780086860e+01, 0.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+00, 0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 2.00000000000000e+01, + }; + real_t g2[11] = { + -8.92227256391600e-08, + 6.89531726031141e-08, + -1.91970120006650e-07, + 1.77206607789402e-07, + -3.83145267945144e-09, + -1.88284265021358e-08, + 0.00000000000000e+00, + 0.00000000000000e+00, + -1.18185657392775e+02, + 1.45337027424899e-17, + -6.04156175796480e-20, + }; + real_t zLow2[11] = { + -1.07876236566374e+01, + -1.00000000002784e+12, + -1.00000000000000e+12, + -8.30554585107279e-08, + -7.00000003695781e+00, + -2.60479531522807e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + 0.00000000000000e+00, + -4.50000000018062e+01, + -1.00000000000000e+12, + }; + real_t zUpp2[11] = { + 9.99999999989212e+11, + 9.99999999972157e+11, + 1.00000000000000e+12, + 4.68471853498991e+01, + 6.99999996304219e+00, + 9.99999999997395e+11, + 1.00000000000000e+12, + 1.00000000000000e+12, + 0.00000000000000e+00, + 4.49999999981938e+01, + 1.00000000000000e+12, + }; + real_t D2[11*3] = { + 1.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, -1.00000000000000e-02, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + -1.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -1.00000000000000e-02, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, -0.00000000000000e+00, + 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, 1.00000000000000e+00, 0.00000000000000e+00, -1.00000000000000e-02, 0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00, + }; + real_t dLow2[3] = { + -1.00000000000000e+12, + -1.00000000000000e+12, + -1.00000000000000e+12, + }; + real_t dUpp2[3] = { + 2.12376343362616e-01, + 4.78762365663739e+00, + 8.95204684771929e-01, + }; + #ifdef __MAKE_POS_DEF__ + H2[8*11+8] += 30; +// H2[9*11+9] += 30; + #endif + + + status = example.hotstart( H2,g2,D2,zLow2,zUpp2,dLow2,dUpp2, nWSR ); + printf("qpOASES_status = %d\n", (int)status ); + + example.getPrimalSolution( xOpt ); + example.getDualSolution( yOpt ); + printf("second QP:\n"); + for (int_t ii =0; ii<11; ++ii ) { + printf("x[%d] = %.3e\n", (int)ii, xOpt[ii]); + } + + printf( "\nQP objective value: %.3e\n", example.getObjVal() ); + + /* Compute KKT tolerances */ + analyzer.getKktViolation( &example, &stat,&feas,&cmpl ); + printf( "\nstat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl ); + + QPOASES_TEST_FOR_TOL( stat,1e-9 ); + QPOASES_TEST_FOR_TOL( feas,1e-7 ); + QPOASES_TEST_FOR_TOL( cmpl,1e-15 ); + + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices.cpp new file mode 100644 index 0000000..37a7242 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices.cpp @@ -0,0 +1,903 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_matrices.cpp + * \author Andreas Potschka, Christian Kirches, Hans Joachim Ferreau + * \version 3.2 + * \date 2010-2017 + * + * Unit test for Matrix classes. + */ + + + +#include +#include + + +USING_NAMESPACE_QPOASES + + +/** Compare deviations when computing dot product. */ +int sumOfSquares() +{ + int_t i; + + /* sum of first n squares */ + const int_t N = 100; + real_t *av = new real_t[N]; + real_t *aTv = new real_t[N]; + real_t *bv = new real_t[N]; + real_t c; + + for (i = 0; i < N; i++) av[i] = (real_t)i+1.0; + for (i = 0; i < N; i++) aTv[i] = (real_t)i+1.0; + for (i = 0; i < N; i++) bv[i] = (real_t)i+1.0; + + DenseMatrix a(1, N, N, av); + DenseMatrix aT(N, 1, 1, aTv); + + a.times(1, 1.0, bv, N, 0.0, &c, 1); + real_t err = c - (1.0/6.0)*N*(N+1)*(2*N+1); + fprintf(stdFile, "Dot product; Error in sum of first %d squares: %9.2e\n", (int)N, err ); + + aT.transTimes(1, 1.0, bv, N, 0.0, &c, 1); + real_t errT = c - (1.0/6.0)*N*(N+1)*(2*N+1); + fprintf(stdFile, "Transpose; Error in sum of first %d squares: %9.2e\n", (int)N, errT); + + delete[] bv; + aT.free (); // or delete[] aTv; + a.free (); // or delete[] av; + + QPOASES_TEST_FOR_TOL( err ,1e-10 ) + QPOASES_TEST_FOR_TOL( errT,1e-10 ) + + return TEST_PASSED; +} + + +/** Compare deviations when multiplying Hilbert matrix with its inverse. */ +int hilbert() +{ + int_t i, j; + real_t d, err; + + /* permuted 4x4 Hilbert matrix, row major format */ + real_t _Av[] = {1.0/3.0, 1.0, 0.5, 0.25, + 0.25, 0.5, 1.0/3.0, 0.2, + 0.2, 1.0/3.0, 0.25, 1.0/6.0, + 1.0/6.0, 0.25, 0.2, 1.0/7.0}; + /* and its inverse, column major format */ + real_t Bv[] = {240, 16, -120, -140, + -2700, -120, 1200, 1680, + 6480, 240, -2700, -4200, + -4200, -140, 1680, 2800}; + + /* result */ + real_t *Av = new real_t[4*4]; + real_t *Cv = new real_t[4*4]; + + DenseMatrix A(4, 4, 4, Av); + + for (i = 0; i < 16; i++) Av[i] = _Av[i]; + + A.times(4, 1.0, Bv, 4, 0.0, Cv, 4); + + err = 0.0; + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + d = getAbs(Cv[j*4+i] - static_cast(i == j)); + if (d > err) err = d; + } + } + fprintf(stdFile, "Hilbert; Deviation from identity: %9.2e\n", err); + + delete[] Cv; + A.free (); // or delete[] Av; + + QPOASES_TEST_FOR_TOL( err,1e-12 ) + + return TEST_PASSED; +} + + +/** Compare deviations when multiplying sub-matrices. */ +int submatrix() +{ + int_t i, j; + real_t d, err; + + /* 2x3 transposed submatrix */ + real_t _Asubv[] = {1.0/3.0, 0.25, + 1.0, 0.5, + 0.5, 1.0/3.0, + 0.25, 0.2}; + real_t Bsubv[] = {240, 16, -120, -140, + -2700, -120, 1200, 1680}; + real_t Csubv[2*2]; + + real_t *Asubv = new real_t[2*4]; + + for (i = 0; i < 8; i++) Asubv[i] = _Asubv[i]; + + DenseMatrix Asub(4, 2, 2, Asubv); + + Asub.transTimes(2, 1.0, Bsubv, 4, 0.0, Csubv, 2); + + err = 0.0; + for (j = 0; j < 2; j++) + { + for (i = 0; i < 2; i++) + { + d = getAbs(Csubv[j*2+i] - static_cast(i == j)); + if (d > err) err = d; + } + } + fprintf(stdFile, "Submatrix transpose; Deviation from identity: %9.2e\n", err); + + Asub.free (); // or delete[] Asubv; + + QPOASES_TEST_FOR_TOL( err,1e-13 ) + + return TEST_PASSED; +} + + +/** Compare deviations when multiplying dense sub-matrices via index lists. */ +int indexDenseSubmatrix() +{ + /* dense submatrices via index lists */ + const int_t M = 20, N = 15, K = 5; + int_t i, j, k, m, n; + Indexlist rows(N), cols(N); + int_t *rNum, *cNum; + real_t err=0.0, errT=0.0; + real_t *Av, *X, *Y, *x, *y, *xc, *yc; + + // prepare index lists + m = (M-3)/4; + n = (N-3)/4; + for (i = 0; i < m; i++) { rows.addNumber(M-1 - 2*i); rows.addNumber(2*i); } + for (i = 0; i < n; i++) { cols.addNumber(N-1 - 2*i); cols.addNumber(2*i); } + m *= 2; + n *= 2; + + rows.getNumberArray(&rNum); + fprintf(stdFile, "Rows: "); + for (i = 0; i < m; i++) fprintf(stdFile, " %2d", (int)(rNum[i]) ); + fprintf(stdFile, "\n"); + + cols.getNumberArray(&cNum); + fprintf(stdFile, "Cols: "); + for (i = 0; i < n; i++) fprintf(stdFile, " %2d", (int)(cNum[i]) ); + fprintf(stdFile, "\n"); + + // prepare input matrices + Av = new real_t[M*N]; + X = new real_t[n*K]; + Y = new real_t[m*K]; + x = new real_t[n*K]; + y = new real_t[m*K]; + xc = new real_t[n*K]; + yc = new real_t[m*K]; + + DenseMatrix A(M, N, N, Av); + for (i = 0; i < M*N; i++) Av[i] = -0.5*N*M + (real_t)i; + for (i = 0; i < n*K; i++) X[i] = 1.0 / (real_t)(i+1); + for (i = 0; i < m*K; i++) Y[i] = 1.0 / (real_t)(i+1); + + // multiply + A.times(&rows, &cols, K, 1.0, X, n, 0.0, y, m); + + // check result + for (j = 0; j < m; j++) + { + for (k = 0; k < K; k++) + { + yc[j+k*m] = -y[j+k*m]; + for (i = 0; i < n; i++) + yc[j+k*m] += Av[cNum[i]+rNum[j]*N] * X[i+k*n]; + if (getAbs(yc[j+k*m]) > err) err = getAbs(yc[j+k*m]); + } + } + fprintf(stdFile, "Indexlist submatrix; error: %9.2e\n", err); + + // transpose multiply + A.transTimes(&rows, &cols, K, 1.0, Y, m, 0.0, x, n); + + // check result + errT = 0.0; + for (j = 0; j < n; j++) + { + for (k = 0; k < K; k++) + { + xc[j+k*n] = -x[j+k*n]; + for (i = 0; i < m; i++) + xc[j+k*n] += Av[cNum[j]+rNum[i]*N] * Y[i+k*m]; + if (getAbs(xc[j+k*n]) > errT) errT = getAbs(xc[j+k*n]); + } + } + fprintf(stdFile, "Indexlist transpose submatrix; error: %9.2e\n", errT); + + // check result + + // clean up + delete[] yc; + delete[] xc; + delete[] y; + delete[] x; + delete[] Y; + delete[] X; + A.free (); // or delete[] Av; + + QPOASES_TEST_FOR_TOL( err ,1e-13 ) + QPOASES_TEST_FOR_TOL( errT,2e-14 ) + + return TEST_PASSED; +} + + +/** Obtain column of sparse matrix. */ +int spGetCol() +{ + long j, i; + sparse_int_t *ir = new sparse_int_t[10]; + sparse_int_t *jc = new sparse_int_t[4]; + real_t *val = new real_t[10]; + real_t *col = new real_t[4]; + + /* Test matrix: + * + * [ 0 3 6 ] + * [ 1 0 7 ] + * [ 2 0 8 ] + * [ 0 4 9 ] + * [ 0 5 10 ] + */ + + jc[0] = 0; jc[1] = 2; jc[2] = 5; jc[3] = 10; + ir[0] = 1; ir[1] = 2; + ir[2] = 0; ir[3] = 3; ir[4] = 4; + ir[5] = 0; ir[6] = 1; ir[7] = 2; ir[8] = 3; ir[9] = 4; + for (i = 0; i < 10; i++) val[i] = 1.0 + (double)i; + + SparseMatrix A(5, 3, ir, jc, val); + + Indexlist rows(4); + + rows.addNumber(2); + rows.addNumber(4); + rows.addNumber(3); + rows.addNumber(0); + + /* Indexed matrix: + * + * [ 2 0 8 ] + * [ 0 5 10 ] + * [ 0 4 9 ] + * [ 0 3 6 ] + */ + + for (j = 0; j < 3; j++) + { + fprintf(stdFile, "Column %ld:\n", j); + A.getCol( (int_t)j, &rows, 1.0, col ); + for (i = 0; i < 4; i++) + fprintf(stdFile, " %3.0f\n", col[i]); + } + + delete[] col; + A.free (); // or delete[] val,jc,ir; + + return TEST_PASSED; +} + + +/** Obtain row of sparse matrix. */ +int spGetRow() +{ + long j, i; + sparse_int_t *ir = new sparse_int_t[10]; + sparse_int_t *jc = new sparse_int_t[6]; + real_t *val = new real_t[10]; + real_t *row = new real_t[4]; + + /* Test matrix: + * + * [ 0 3 4 6 0 ] + * [ 1 0 0 7 9 ] + * [ 2 0 5 8 10 ] + */ + + jc[0] = 0; jc[1] = 2; jc[2] = 3; jc[3] = 5; jc[4] = 8; jc[5] = 10; + ir[0] = 1; ir[1] = 2; + ir[2] = 0; + ir[3] = 0; ir[4] = 2; + ir[5] = 0; ir[6] = 1; ir[7] = 2; + ir[8] = 1; ir[9] = 2; + for (i = 0; i < 10; i++) val[i] = 1.0 + (double)i; + + SparseMatrix A(3, 4, ir, jc, val); + + Indexlist cols(4); + + cols.addNumber(2); + cols.addNumber(4); + cols.addNumber(3); + cols.addNumber(1); + + /* Indexed matrix: + * + * [ 4 0 6 3 ] + * [ 0 9 7 0 ] + * [ 5 10 8 0 ] + */ + + for (j = 0; j < 3; j++) + { + A.getRow( (int_t)j, &cols, 1.0, row ); + for (i = 0; i < 4; i++) + fprintf(stdFile, " %3.0f", row[i]); + fprintf(stdFile, "\n"); + } + + delete[] row; + A.free (); + + return TEST_PASSED; +} + + +/** Compare deviations when multiplying sparse matrix. */ +int spTimes() +{ + long i; + sparse_int_t *ir = new sparse_int_t[10]; + sparse_int_t *jc = new sparse_int_t[6]; + real_t *val = new real_t[10]; + + real_t *x = new real_t[5*2]; + real_t *y = new real_t[3*2]; + + real_t Ax[] = {-23, -11, -26, 42, 74, 99}; + real_t ATy[] = {-63, -69, -222, -423, -359, 272, 126, 663, 1562, 1656}; + real_t err=0.0, errT=0.0; + + for (i = 0; i < 10; i++) x[i] = -4.0 + (double)i; + + /* Test matrix: + * + * [ 0 3 4 6 0 ] + * [ 1 0 0 7 9 ] + * [ 2 0 5 8 10 ] + */ + + jc[0] = 0; jc[1] = 2; jc[2] = 3; jc[3] = 5; jc[4] = 8; jc[5] = 10; + ir[0] = 1; ir[1] = 2; + ir[2] = 0; + ir[3] = 0; ir[4] = 2; + ir[5] = 0; ir[6] = 1; ir[7] = 2; + ir[8] = 1; ir[9] = 2; + for (i = 0; i < 10; i++) val[i] = 1.0 + (double)i; + + SparseMatrix A(3, 5, ir, jc, val); // reference to ir, jc, val + + A.times(2, 1.0, x, 5, 0.0, y, 3); + + for (i = 0; i < 6; i++) + if (getAbs(y[i] - Ax[i]) > err) err = getAbs(y[i] - Ax[i]); + fprintf(stdFile, "Error in sparse A*x: %9.2e\n", err); + + A.transTimes(2, 1.0, y, 3, 0.0, x, 5); + + errT = 0.0; + for (i = 0; i < 10; i++) + if (getAbs(x[i] - ATy[i]) > errT) errT = getAbs(x[i] - ATy[i]); + fprintf(stdFile, "Error in sparse A'*x: %9.2e\n", errT); + + A.free (); // or delete[] val,ir,jc + delete[] y; + delete[] x; + + QPOASES_TEST_FOR_TOL( err ,1e-15 ) + QPOASES_TEST_FOR_TOL( errT,1e-15 ) + + return TEST_PASSED; +} + + +/** Compare deviations when multiplying sparse matrix via index lists. */ +int spIndTimes() +{ + const long N = 4; + long i, j; + long nRows = 2 * N + 1; + long nCols = N; + long nnz = 3 * N; + sparse_int_t *ir = new sparse_int_t[nnz]; + sparse_int_t *jc = new sparse_int_t[nCols+1]; + real_t *val = new real_t[nnz]; + real_t *xc = new real_t[3*2]; + real_t *yc = new real_t[4*2]; + real_t Ax[] = {0.31, 0.05, 0.06, 0.30, 0.76, 0.20, 0.24, 0.60}; + real_t ATy[] = {0.278, 0.000, 0.548, 0.776, 0.000, 1.208}; + real_t err=0.0, errT=0.0; + + Indexlist rows(4), cols(3), allcols( (int_t)nCols ); + + rows.addNumber(2); + rows.addNumber(4); + rows.addNumber(3); + rows.addNumber(0); + + cols.addNumber(1); + cols.addNumber(3); + cols.addNumber(0); + + for (i = 0; i < nCols; i++) + allcols.addNumber( (int_t)i ); + + // build test matrix + for (i = 0; i <= N; i++) jc[i] = (sparse_int_t)(3*i); + for (j = 0; j < N; j++) + for (i = 0; i < 3; i++) + { + ir[j*3+i] = (sparse_int_t)(2*j + i); + val[j*3+i] = 1.0 - 0.1 * (double)(j*3+i); + } + SparseMatrix A( (int_t)nRows, (int_t)nCols, ir, jc, val ); + + fprintf(stdFile, "Test matrix A =\n"); + for (j = 0; j < nRows; j++) + { + A.getRow( (int_t)j, &allcols, 1.0, xc ); + for (i = 0; i < nCols; i++) + fprintf(stdFile, "%6.2f", xc[i]); + fprintf(stdFile, "\n"); + } + + for (i = 0; i < 6; i++) + xc[i] = (1.0 + (double)i) * 0.1; + + A.times(&rows, &cols, 2, 1.0, xc, 3, 0.0, yc, 4, BT_TRUE); + + for (i = 0; i < 8; i++) + if (getAbs(yc[i] - Ax[i]) > err) + err = getAbs(yc[i] - Ax[i]); + fprintf(stdFile, "Error in sparse indexed A*x: %9.2e\n", err); + + A.transTimes(&rows, &cols, 2, 1.0, yc, 4, 0.0, xc, 3); + errT = 0.0; + for (i = 0; i < 6; i++) + if (getAbs(xc[i] - ATy[i]) > errT) + errT = getAbs(xc[i] - ATy[i]); + fprintf(stdFile, "Error in sparse indexed A'*y: %9.2e\n", errT); + + delete[] xc; + delete[] yc; + A.free (); + + QPOASES_TEST_FOR_TOL( err ,1e-15 ) + QPOASES_TEST_FOR_TOL( errT,1e-15 ) + + return TEST_PASSED; +} + + +/** Obtain column of sparse row matrix. */ +int sprGetCol() +{ + long j, i; + sparse_int_t *ir = new sparse_int_t[10]; + sparse_int_t *jc = new sparse_int_t[4]; + real_t *val = new real_t[10]; + real_t *col = new real_t[4]; + + /* Test matrix: + * + * [ 0 3 6 ] + * [ 1 0 7 ] + * [ 2 0 8 ] + * [ 0 4 9 ] + * [ 0 5 10 ] + */ + + jc[0] = 0; jc[1] = 2; jc[2] = 5; jc[3] = 10; + ir[0] = 1; ir[1] = 2; + ir[2] = 0; ir[3] = 3; ir[4] = 4; + ir[5] = 0; ir[6] = 1; ir[7] = 2; ir[8] = 3; ir[9] = 4; + for (i = 0; i < 10; i++) val[i] = 1.0 + (double)i; + + SparseMatrix Ac(5, 3, ir, jc, val); + real_t *Acv = Ac.full(); // row major format + SparseMatrixRow A(5, 3, 3, Acv); + delete[] Acv; + Ac.free (); // or delete[] val,jc,ir; + + Indexlist rows(4); + + rows.addNumber(2); + rows.addNumber(4); + rows.addNumber(3); + rows.addNumber(0); + + /* Indexed matrix: + * + * [ 2 0 8 ] + * [ 0 5 10 ] + * [ 0 4 9 ] + * [ 0 3 6 ] + */ + + for (j = 0; j < 3; j++) + { + fprintf(stdFile, "Column %ld:\n", j); + A.getCol( (int_t)j, &rows, 1.0, col ); + for (i = 0; i < 4; i++) + fprintf(stdFile, " %3.0f\n", col[i]); + } + + delete[] col; + A.free (); // or delete[] val,jc,ir; + + return TEST_PASSED; +} + + +/** Obtain row of sparse row matrix. */ +int sprGetRow() +{ + long j, i; + sparse_int_t *ir = new sparse_int_t[10]; + sparse_int_t *jc = new sparse_int_t[6]; + real_t *val = new real_t[10]; + real_t *row = new real_t[4]; + + /* Test matrix: + * + * [ 0 3 4 6 0 ] + * [ 1 0 0 7 9 ] + * [ 2 0 5 8 10 ] + */ + + jc[0] = 0; jc[1] = 2; jc[2] = 3; jc[3] = 5; jc[4] = 8; jc[5] = 10; + ir[0] = 1; ir[1] = 2; + ir[2] = 0; + ir[3] = 0; ir[4] = 2; + ir[5] = 0; ir[6] = 1; ir[7] = 2; + ir[8] = 1; ir[9] = 2; + for (i = 0; i < 10; i++) val[i] = 1.0 + (double)i; + + SparseMatrix Ac(3, 5, ir, jc, val); + real_t *Acv = Ac.full(); // row major format + SparseMatrixRow A(3, 5, 5, Acv); + delete[] Acv; + Ac.free (); // or delete[] val,jc,ir; + + Indexlist cols(4); + + cols.addNumber(2); + cols.addNumber(4); + cols.addNumber(3); + cols.addNumber(1); + + /* Indexed matrix: + * + * [ 4 0 6 3 ] + * [ 0 9 7 0 ] + * [ 5 10 8 0 ] + */ + + for (j = 0; j < 3; j++) + { + A.getRow( (int_t)j, &cols, 1.0, row ); + for (i = 0; i < 4; i++) + fprintf(stdFile, " %3.0f", row[i]); + fprintf(stdFile, "\n"); + } + + delete[] row; + A.free (); + + return TEST_PASSED; +} + + +/** Compare deviations when multiplying sparse row matrix. */ +int sprTimes() +{ + long i; + sparse_int_t *ir = new sparse_int_t[10]; + sparse_int_t *jc = new sparse_int_t[6]; + real_t *val = new real_t[10]; + + real_t *x = new real_t[5*2]; + real_t *y = new real_t[3*2]; + + real_t Ax[] = {-23, -11, -26, 42, 74, 99}; + real_t ATy[] = {-63, -69, -222, -423, -359, 272, 126, 663, 1562, 1656}; + real_t err=0.0, errT=0.0; + + for (i = 0; i < 10; i++) x[i] = -4.0 + (double)i; + + /* Test matrix: + * + * [ 0 3 4 6 0 ] + * [ 1 0 0 7 9 ] + * [ 2 0 5 8 10 ] + */ + + jc[0] = 0; jc[1] = 2; jc[2] = 3; jc[3] = 5; jc[4] = 8; jc[5] = 10; + ir[0] = 1; ir[1] = 2; + ir[2] = 0; + ir[3] = 0; ir[4] = 2; + ir[5] = 0; ir[6] = 1; ir[7] = 2; + ir[8] = 1; ir[9] = 2; + for (i = 0; i < 10; i++) val[i] = 1.0 + (double)i; + + SparseMatrix Ac(3, 5, ir, jc, val); // reference to ir, jc, val + real_t *Acv = Ac.full(); // row major format + SparseMatrixRow A(3, 5, 5, Acv); + delete[] Acv; + Ac.free (); // or delete[] val,jc,ir; + + A.times(2, 1.0, x, 5, 0.0, y, 3); + + for (i = 0; i < 6; i++) + if (getAbs(y[i] - Ax[i]) > err) err = getAbs(y[i] - Ax[i]); + fprintf(stdFile, "Error in sparse A*x: %9.2e\n", err); + + A.transTimes(2, 1.0, y, 3, 0.0, x, 5); + + errT = 0.0; + for (i = 0; i < 10; i++) + if (getAbs(x[i] - ATy[i]) > errT) errT = getAbs(x[i] - ATy[i]); + fprintf(stdFile, "Error in sparse A'*x: %9.2e\n", errT); + + A.free (); // or delete[] val,ir,jc + delete[] y; + delete[] x; + + QPOASES_TEST_FOR_TOL( err ,1e-15 ) + QPOASES_TEST_FOR_TOL( errT,1e-15 ) + + return TEST_PASSED; +} + + +/** Compare deviations when multiplying sparse row matrix via index lists. */ +int sprIndTimes() +{ + const long N = 4; + long i, j; + long nRows = 2 * N + 1; + long nCols = N; + long nnz = 3 * N; + sparse_int_t *ir = new sparse_int_t[nnz]; + sparse_int_t *jc = new sparse_int_t[nCols+1]; + real_t *val = new real_t[nnz]; + real_t *xc = new real_t[3*2]; + real_t *yc = new real_t[4*2]; + real_t Ax[] = {0.31, 0.05, 0.06, 0.30, 0.76, 0.20, 0.24, 0.60}; + real_t ATy[] = {0.278, 0.000, 0.548, 0.776, 0.000, 1.208}; + real_t err=0.0, errT=0.0; + + Indexlist rows(4), cols(3), allcols( (int_t)nCols ); + + rows.addNumber(2); + rows.addNumber(4); + rows.addNumber(3); + rows.addNumber(0); + + cols.addNumber(1); + cols.addNumber(3); + cols.addNumber(0); + + for (i = 0; i < nCols; i++) + allcols.addNumber( (int_t)i ); + + // build test matrix + for (i = 0; i <= N; i++) jc[i] = (sparse_int_t)(3*i); + for (j = 0; j < N; j++) + for (i = 0; i < 3; i++) + { + ir[j*3+i] = (sparse_int_t)(2*j + i); + val[j*3+i] = 1.0 - 0.1 * (double)(j*3+i); + } + SparseMatrix Ac( (int_t)nRows, (int_t)nCols, ir, jc, val); + real_t *Acv = Ac.full(); // row major format + SparseMatrixRow A( (int_t)nRows, (int_t)nCols, (int_t)nCols, Acv); + delete[] Acv; + Ac.free (); // or delete[] val,jc,ir; + + fprintf(stdFile, "Test matrix A =\n"); + for (j = 0; j < nRows; j++) + { + A.getRow( (int_t)j, &allcols, 1.0, xc ); + for (i = 0; i < nCols; i++) + fprintf(stdFile, "%6.2f", xc[i]); + fprintf(stdFile, "\n"); + } + + for (i = 0; i < 6; i++) + xc[i] = (1.0 + (double)i) * 0.1; + + A.times(&rows, &cols, 2, 1.0, xc, 3, 0.0, yc, 4, BT_TRUE); + + for (i = 0; i < 8; i++) + if (getAbs(yc[i] - Ax[i]) > err) + err = getAbs(yc[i] - Ax[i]); + fprintf(stdFile, "Error in sparse indexed A*x: %9.2e\n", err); + + A.transTimes(&rows, &cols, 2, 1.0, yc, 4, 0.0, xc, 3); + for (i = 0; i < 3; i++) + { + for (j = 0; j < 2; j++) + fprintf(stdFile, "%6.2f", ATy[i + j*3]); + fprintf(stdFile, "\n"); + } + for (i = 0; i < 3; i++) + { + for (j = 0; j < 2; j++) + fprintf(stdFile, "%6.2f", xc[i + j*3]); + fprintf(stdFile, "\n"); + } + for (i = 0; i < 6; i++) + if (getAbs(xc[i] - ATy[i]) > errT) + errT = getAbs(xc[i] - ATy[i]); + fprintf(stdFile, "Error in sparse indexed A'*y: %9.2e\n", errT); + + delete[] xc; + delete[] yc; + A.free (); + + QPOASES_TEST_FOR_TOL( err ,1e-15 ) + QPOASES_TEST_FOR_TOL( errT,1e-15 ) + + return TEST_PASSED; +} + + +/** Compare deviations when using bilinear multiplication with dense matrix. */ +int symmetry() +{ + int_t i,j; + real_t *Hv = new real_t[6*6]; + real_t *Z = new real_t[6*3]; + real_t *ZHZd = new real_t[3*3]; + real_t *ZHZs = new real_t[3*3]; + real_t ZHZv[] = {0.144, 0.426, 0.708, 0.426, 1.500, 2.574, 0.708, 2.574, 4.440}; + real_t err=0.0, errS=0.0; + SymDenseMat *Hd; + SymSparseMat *Hs; + Indexlist *cols = new Indexlist(6); + + for (i = 0; i < 36; i++) Hv[i] = 0.0; + for (i = 0; i < 6; i++) Hv[i*7] = 1.0 - 0.1 * (real_t)i; + for (i = 0; i < 5; i++) Hv[i*7+1] = Hv[i*7+6] = -0.1 * ((real_t)i+1.0); + + Hd = new SymDenseMat(6, 6, 6, Hv); // deep-copy from Hv + Hs = new SymSparseMat(6, 6, 6, Hv); // deep-copy from Hv + Hs->createDiagInfo(); + + for (i = 0; i < 6; ++i) + { + for (j = 0; j < 6; ++j) + fprintf (stdFile, "%3.3f ", Hv[i*6+j]); + fprintf (stdFile, "\n"); + } + fprintf (stdFile, "\n"); + + cols->addNumber(3); + cols->addNumber(0); + cols->addNumber(4); + cols->addNumber(1); + for (i = 0; i < 18; i++) Z[i] = 0.1 * ((real_t)i+1.0); + + fprintf (stdFile, "\n"); + for (i = 0; i < 6; ++i) + { + for (j = 0; j < 3; ++j) + fprintf (stdFile, "%3.3f ", Z[i+j*6]); + fprintf (stdFile, "\n"); + } + fprintf (stdFile, "\n"); + + Hd->bilinear(cols, 3, Z, 6, ZHZd, 3); + + for (i = 0; i < 9; i++) + if (getAbs(ZHZd[i] - ZHZv[i]) > err) + err = getAbs(ZHZd[i] - ZHZv[i]); + fprintf(stdFile, "Error in indexed dense bilinear form: %9.2e\n", err); + + Hs->bilinear(cols, 3, Z, 6, ZHZs, 3); + + for (i = 0; i < 3; ++i) + { + for (j = 0; j < 3; ++j) + fprintf (stdFile, "%3.3f ", ZHZd[i*3+j]); + fprintf (stdFile, "\n"); + } + fprintf (stdFile, "\n"); + + for (i = 0; i < 3; ++i) + { + for (j = 0; j < 3; ++j) + fprintf (stdFile, "%3.3f ", ZHZv[i*3+j]); + fprintf (stdFile, "\n"); + } + fprintf (stdFile, "\n"); + + for (i = 0; i < 9; i++) + if (getAbs(ZHZs[i] - ZHZv[i]) > errS) + errS = getAbs(ZHZs[i] - ZHZv[i]); + fprintf(stdFile, "Error in indexed sparse bilinear form: %9.2e\n", errS); + + delete cols; + delete Hs; + delete Hd; + delete[] ZHZs; + delete[] ZHZd; + delete[] Z; + delete[] Hv; + + QPOASES_TEST_FOR_TOL( err ,1e-15 ) + QPOASES_TEST_FOR_TOL( errS,1e-15 ) + + return TEST_PASSED; +} + + +/** Run various tests on matrix classes. */ +int main() +{ + int errorCount = TEST_PASSED; + + errorCount += sumOfSquares(); + errorCount += hilbert(); + errorCount += submatrix(); + errorCount += indexDenseSubmatrix(); + + errorCount += spGetCol(); + errorCount += spGetRow(); + errorCount += spTimes(); + errorCount += spIndTimes(); + + errorCount += sprGetCol(); + errorCount += sprGetRow(); + errorCount += sprTimes(); + errorCount += sprIndTimes(); + + errorCount += symmetry(); + + return errorCount; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices2.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices2.cpp new file mode 100644 index 0000000..bbfd539 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices2.cpp @@ -0,0 +1,113 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_matrices2.cpp + * \author Hans Joachim Ferreau,Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2014-2017 + * + * Unit test for Matrix classes. + */ + + +#include + +#include +#include + + +#include "test_qrecipe_data.hpp" + + +/** Compare deviations when performing matrix operations. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t i; + + real_t errH=0.0, errA=0.0; + real_t v[180]; + real_t resHs[180]; + real_t resHd[180]; + real_t resAs[91]; + real_t resAd[91]; + + /* create sparse matrices */ + SymSparseMat *H = new SymSparseMat(180, 180, H_ir, H_jc, H_val); + SparseMatrix *A = new SparseMatrix(91, 180, A_ir, A_jc, A_val); + + H->createDiagInfo(); + + real_t* H_full = H->full(); + real_t* A_full = A->full(); + + //print( A_full,91,180 ); + + + SymDenseMat *Hd = new SymDenseMat(180,180,180,H_full); + DenseMatrix *Ad = new DenseMatrix(91,180,180,A_full); + + for( i=0; i<180; ++i ) + v[i] = 2.0 * ((real_t)rand()) / ((real_t)RAND_MAX) - 1.0; + + H ->times(1, 1.0, v, 180, 0.0, resHs, 180); + Hd->times(1, 1.0, v, 180, 0.0, resHd, 180); + + A ->times(1, 1.0, v, 180, 0.0, resAs, 91); + Ad->times(1, 1.0, v, 180, 0.0, resAd, 91); + + + for ( i=0; i<180; ++i ) + if ( getAbs(resHs[i] - resHd[i]) > errH) + errH = getAbs(resHs[i] - resHd[i]); + + fprintf(stdFile, "maximum difference in H*v: %9.2e\n", errH); + + + for ( i=0; i<91; ++i ) + if ( getAbs(resAs[i] - resAd[i]) > errA) + errA = getAbs(resAs[i] - resAd[i]); + + fprintf(stdFile, "maximum difference in A*v: %9.2e\n", errA); + + delete H; + delete A; + delete[] H_full; + delete[] A_full; + delete Hd; + delete Ad; + + + QPOASES_TEST_FOR_TOL( errH,1e-13 ) + QPOASES_TEST_FOR_TOL( errA,1e-13 ) + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices3.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices3.cpp new file mode 100644 index 0000000..f588dd0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_matrices3.cpp @@ -0,0 +1,90 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_matrices3.cpp + * \author Hans Joachim Ferreau,Andreas Potschka, Christian Kirches + * \version 3.2 + * \date 2014-2017 + * + * Unit test for Matrix classes. + */ + + +#include + +#include +#include + + +#include "test_qrecipe_data.hpp" + + +/** Compare deviations when performing matrix operations. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t i; + + real_t errH=0.0; + real_t v[180]; + real_t resHn[180]; + real_t resHt[180]; + + /* create sparse matrices */ + SymSparseMat *H = new SymSparseMat(180, 180, H_ir, H_jc, H_val); + + H->createDiagInfo(); + + real_t* H_full = H->full(); + + SymDenseMat *Hd = new SymDenseMat(180,180,180,H_full); + + for( i=0; i<180; ++i ) + v[i] = 2.0 * ((real_t)rand()) / ((real_t)RAND_MAX) - 1.0; + + Hd->times( 1, 1.0, v, 180, 0.0, resHn, 180); + Hd->transTimes(1, 1.0, v, 180, 0.0, resHt, 180); + + for ( i=0; i<180; ++i ) + if ( getAbs(resHn[i] - resHt[i]) > errH) + errH = getAbs(resHn[i] - resHt[i]); + + fprintf(stdFile, "maximum difference in H*v vs. H'*v: %9.2e\n", errH); + + delete H; + delete[] H_full; + delete Hd; + + + QPOASES_TEST_FOR_TOL( errH,1e-15 ) + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipe.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipe.cpp new file mode 100644 index 0000000..9c56cce --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipe.cpp @@ -0,0 +1,144 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_qrecipe.cpp + * \author Andreas Potschka + * \version 3.2 + * \date 2007-2017 + * + * QRECIPE example from the CUTEr test set with sparse matrices. + */ + + + +#include +#include + +#include "test_qrecipe_data.hpp" + + + +int main( ) +{ + USING_NAMESPACE_QPOASES + + long i; + int_t nWSR; + real_t tic, toc; + real_t errP=0.0, errD=0.0; + real_t *x1 = new real_t[180]; + real_t *y1 = new real_t[271]; + real_t *x2 = new real_t[180]; + real_t *y2 = new real_t[271]; + + /* create sparse matrices */ + SymSparseMat *H = new SymSparseMat(180, 180, H_ir, H_jc, H_val); + SparseMatrix *A = new SparseMatrix(91, 180, A_ir, A_jc, A_val); + + H->createDiagInfo(); + + real_t* H_full = H->full(); + real_t* A_full = A->full(); + + SymDenseMat *Hd = new SymDenseMat(180,180,180,H_full); + DenseMatrix *Ad = new DenseMatrix(91,180,180,A_full); + + /* solve with dense matrices */ + nWSR = 1000; + QProblem qrecipeD(180, 91); + tic = getCPUtime(); + qrecipeD.init(Hd, g, Ad, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeD.getPrimalSolution(x1); + qrecipeD.getDualSolution(y1); + + fprintf(stdFile, "Solved dense problem in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* Compute KKT tolerances */ + real_t statD, feasD, cmplD; + SolutionAnalysis analyzerD; + + analyzerD.getKktViolation( &qrecipeD, &statD,&feasD,&cmplD ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n\n", statD,feasD,cmplD ); + + + /* solve with sparse matrices */ + nWSR = 1000; + QProblem qrecipeS(180, 91); + tic = getCPUtime(); + qrecipeS.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeS.getPrimalSolution(x2); + qrecipeS.getDualSolution(y2); + + fprintf(stdFile, "Solved sparse problem in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* Compute KKT tolerances */ + real_t statS, feasS, cmplS; + SolutionAnalysis analyzerS; + + analyzerS.getKktViolation( &qrecipeS, &statS,&feasS,&cmplS ); + printf( "stat = %e\nfeas = %e\ncmpl = %e\n\n", statS,feasS,cmplS ); + + /* check distance of solutions */ + for (i = 0; i < 180; i++) + if (getAbs(x1[i] - x2[i]) > errP) + errP = getAbs(x1[i] - x2[i]); + fprintf(stdFile, "Primal error: %9.2e\n", errP); + + for (i = 0; i < 271; i++) + if (getAbs(y1[i] - y2[i]) > errD) + errD = getAbs(y1[i] - y2[i]); + fprintf(stdFile, "Dual error: %9.2e (might not be unique)\n", errD); + + delete H; + delete A; + delete[] H_full; + delete[] A_full; + delete Hd; + delete Ad; + + delete[] y2; + delete[] x2; + delete[] y1; + delete[] x1; + + QPOASES_TEST_FOR_TOL( statD,1e-14 ); + QPOASES_TEST_FOR_TOL( feasD,1e-14 ); + QPOASES_TEST_FOR_TOL( cmplD,1e-13 ); + + QPOASES_TEST_FOR_TOL( statS,1e-14 ); + QPOASES_TEST_FOR_TOL( feasS,1e-14 ); + QPOASES_TEST_FOR_TOL( cmplS,1e-13 ); + + QPOASES_TEST_FOR_TOL( errP,1e-13 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipeSchur.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipeSchur.cpp new file mode 100644 index 0000000..3f07baa --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipeSchur.cpp @@ -0,0 +1,178 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_qrecipeSchur.cpp + * \author Dennis Janka + * \version 3.2 + * \date 2007-2017 + * + * QRECIPE example from the CUTEr test set with sparse matrices. + * Comparison between nullspace factorization (dense and sparse) and + * Schur complement approach. + */ + + + +#include +#include + +#include "test_qrecipe_data.hpp" + + + +int main( ) +{ + USING_NAMESPACE_QPOASES + + long i; + int_t nWSR; + real_t errP1, errP2, errP3, errD1, errD2, errD3, tic, toc; + real_t *x1 = new real_t[180]; + real_t *y1 = new real_t[271]; + real_t *x2 = new real_t[180]; + real_t *y2 = new real_t[271]; + real_t *x3 = new real_t[180]; + real_t *y3 = new real_t[271]; + + Options options; + options.setToDefault(); + options.enableEqualities = BT_TRUE; + + /* create sparse matrices */ + SymSparseMat *H = new SymSparseMat(180, 180, H_ir, H_jc, H_val); + SparseMatrix *A = new SparseMatrix(91, 180, A_ir, A_jc, A_val); + + H->createDiagInfo(); + + real_t* H_full = H->full(); + real_t* A_full = A->full(); + + SymDenseMat *Hd = new SymDenseMat(180,180,180,H_full); + DenseMatrix *Ad = new DenseMatrix(91,180,180,A_full); + + /* solve with dense matrices */ + nWSR = 1000; + QProblem qrecipeD(180, 91); + qrecipeD.setOptions(options); + tic = getCPUtime(); + qrecipeD.init(Hd, g, Ad, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeD.getPrimalSolution(x1); + qrecipeD.getDualSolution(y1); + + fprintf(stdFile, "Solved dense problem in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* solve with sparse matrices (nullspace factorization) */ + nWSR = 1000; + QProblem qrecipeS(180, 91); + /* for some reason this is necessary to pass the test when using MUMPS */ +#if USE_SOLVER == MUMPS + options.enableEqualities = BT_FALSE; +#endif + qrecipeS.setOptions(options); + tic = getCPUtime(); + qrecipeS.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeS.getPrimalSolution(x2); + qrecipeS.getDualSolution(y2); + + fprintf(stdFile, "Solved sparse problem in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* solve with sparse matrices (Schur complement) */ + #ifndef SOLVER_NONE + nWSR = 1000; + SQProblemSchur qrecipeSchur(180, 91); + qrecipeSchur.setOptions(options); + tic = getCPUtime(); + qrecipeSchur.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qrecipeSchur.getPrimalSolution(x3); + qrecipeSchur.getDualSolution(y3); + + fprintf(stdFile, "Solved sparse problem (Schur complement approach) in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + #endif /* SOLVER_NONE */ + + /* check distance of solutions */ + errP1 = 0.0; + errP2 = 0.0; + errP3 = 0.0; + #ifndef SOLVER_NONE + for (i = 0; i < 180; i++) + if (getAbs(x1[i] - x2[i]) > errP1) + errP1 = getAbs(x1[i] - x2[i]); + for (i = 0; i < 180; i++) + if (getAbs(x1[i] - x3[i]) > errP2) + errP2 = getAbs(x1[i] - x3[i]); + for (i = 0; i < 180; i++) + if (getAbs(x2[i] - x3[i]) > errP3) + errP3 = getAbs(x2[i] - x3[i]); + #endif /* SOLVER_NONE */ + fprintf(stdFile, "Primal error (dense and sparse): %9.2e\n", errP1); + fprintf(stdFile, "Primal error (dense and Schur): %9.2e\n", errP2); + fprintf(stdFile, "Primal error (sparse and Schur): %9.2e\n", errP3); + + errD1 = 0.0; + errD2 = 0.0; + errD3 = 0.0; + for (i = 0; i < 271; i++) + if (getAbs(y1[i] - y2[i]) > errD1) + errD1 = getAbs(y1[i] - y2[i]); + #ifndef SOLVER_NONE + for (i = 0; i < 271; i++) + if (getAbs(y1[i] - y3[i]) > errD2) + errD2 = getAbs(y1[i] - y3[i]); + for (i = 0; i < 271; i++) + if (getAbs(y2[i] - y3[i]) > errD3) + errD3 = getAbs(y2[i] - y3[i]); + #endif /* SOLVER_NONE */ + fprintf(stdFile, "Dual error (dense and sparse): %9.2e (might not be unique)\n", errD1); + fprintf(stdFile, "Dual error (dense and Schur): %9.2e (might not be unique)\n", errD2); + fprintf(stdFile, "Dual error (sparse and Schur): %9.2e (might not be unique)\n", errD3); + + delete H; + delete A; + delete[] H_full; + delete[] A_full; + delete Hd; + delete Ad; + + delete[] y3; + delete[] x3; + delete[] y2; + delete[] x2; + delete[] y1; + delete[] x1; + + QPOASES_TEST_FOR_TOL( errP1,1e-13 ); + QPOASES_TEST_FOR_TOL( errP2,1e-13 ); + QPOASES_TEST_FOR_TOL( errP3,1e-13 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipe_data.hpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipe_data.hpp new file mode 100644 index 0000000..9cf0122 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_qrecipe_data.hpp @@ -0,0 +1,401 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_qrecipe.cpp + * \author Andreas Potschka + * \version 3.2 + * \date 2007-2017 + * + * QRECIPE example from the CUTEr test set with sparse matrices. + */ + + +USING_NAMESPACE_QPOASES + + + +const real_t Inf = INFTY; + +sparse_int_t H_jc[] = { 0, 4, 8, 12, 16, 20, 20, 20, 20, 20, 20, + 24, 28, 32, 36, 40, 40, 40, 40, 40, 40, + 44, 48, 52, 56, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 64, 68, 72, 76, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80 }; + +sparse_int_t H_ir[] = { + 0, 10, 20, 34, 1, 11, 21, 35, 2, 12, 22, 36, 3, 13, 23, 37, 4, 14, 24, 38, + 0, 10, 20, 34, 1, 11, 21, 35, 2, 12, 22, 36, 3, 13, 23, 37, 4, 14, 24, 38, + 0, 10, 20, 34, 1, 11, 21, 35, 2, 12, 22, 36, 3, 13, 23, 37, 4, 14, 24, 38, + 0, 10, 20, 34, 1, 11, 21, 35, 2, 12, 22, 36, 3, 13, 23, 37, 4, 14, 24, 38}; + +real_t H_val[] = {10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, + 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 1, + 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 1, 10, 1, + 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10, 1, 1, 1, 10}; + +sparse_int_t A_jc[] = { + 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, + 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, + 280, 290, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 331, + 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, + 363, 365, 367, 369, 371, 373, 383, 393, 403, 405, 408, 410, 413, 415, 418, + 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, + 450, 452, 454, 456, 458, 460, 462, 472, 482, 492, 494, 497, 499, 502, 504, + 507, 509, 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, + 537, 539, 541, 543, 545, 547, 549, 551, 561, 571, 581, 583, 586, 588, 591, + 593, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, + 610, 611, 612, 613, 614, 615, 616, 617, 618, 628, 638, 648, 650, 653, 655, + 658, 660, 663}; + +sparse_int_t A_ir[] = {0, 14, 35, 36, 71, 72, 85, 86, 87, 88, 1, 14, 35, 36, 71, 72, 85, + 86, 87, 88, 2, 14, 35, 36, 71, 72, 85, 86, 87, 88, 3, 14, 35, 36, 71, 72, + 85, 86, 87, 88, 4, 14, 35, 36, 71, 72, 85, 86, 87, 88, 5, 14, 35, 36, 71, + 72, 85, 86, 87, 88, 6, 14, 35, 36, 71, 72, 85, 86, 87, 88, 7, 14, 35, 36, + 71, 72, 85, 86, 87, 88, 8, 14, 35, 36, 71, 72, 85, 86, 87, 88, 9, 14, 35, + 36, 71, 72, 85, 86, 87, 88, 0, 15, 37, 38, 69, 70, 79, 80, 81, 82, 1, 15, + 37, 38, 69, 70, 79, 80, 81, 82, 2, 15, 37, 38, 69, 70, 79, 80, 81, 82, 3, + 15, 37, 38, 69, 70, 79, 80, 81, 82, 4, 15, 37, 38, 69, 70, 79, 80, 81, 82, + 5, 15, 37, 38, 69, 70, 79, 80, 81, 82, 6, 15, 37, 38, 69, 70, 79, 80, 81, + 82, 7, 15, 37, 38, 69, 70, 79, 80, 81, 82, 8, 15, 37, 38, 69, 70, 79, 80, + 81, 82, 9, 15, 37, 38, 69, 70, 79, 80, 81, 82, 0, 16, 39, 40, 67, 68, 73, + 74, 75, 76, 1, 16, 39, 40, 67, 68, 73, 74, 75, 76, 2, 16, 39, 40, 67, 68, + 73, 74, 75, 76, 3, 16, 39, 40, 67, 68, 73, 74, 75, 76, 4, 16, 39, 40, 67, + 68, 73, 74, 75, 76, 5, 16, 39, 40, 67, 68, 73, 74, 75, 76, 6, 16, 39, 40, + 67, 68, 73, 74, 75, 76, 7, 16, 39, 40, 67, 68, 73, 74, 75, 76, 8, 16, 39, + 40, 67, 68, 73, 74, 75, 76, 9, 16, 39, 40, 67, 68, 73, 74, 75, 76, 10, 11, + 12, 13, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 47, 58, 48, 59, 49, 60, 50, 61, 51, 62, 52, 63, 53, + 64, 54, 65, 55, 66, 46, 56, 45, 57, 47, 58, 48, 59, 49, 60, 50, 61, 51, 62, + 52, 63, 53, 64, 54, 65, 55, 66, 46, 56, 45, 57, 10, 14, 71, 72, 85, 86, 87, + 88, 89, 90, 11, 15, 69, 70, 79, 80, 81, 82, 83, 84, 12, 16, 67, 68, 73, 74, + 75, 76, 77, 78, 35, 90, 36, 89, 90, 37, 84, 38, 83, 84, 39, 78, 40, 77, 78, + 44, 58, 43, 59, 42, 60, 41, 61, 34, 62, 33, 63, 32, 64, 31, 65, 30, 66, 29, + 46, 28, 45, 44, 58, 43, 59, 42, 60, 41, 61, 34, 62, 33, 63, 32, 64, 31, 65, + 30, 66, 29, 46, 28, 45, 10, 14, 71, 72, 85, 86, 87, 88, 89, 90, 11, 15, 69, + 70, 79, 80, 81, 82, 83, 84, 12, 16, 67, 68, 73, 74, 75, 76, 77, 78, 35, 90, + 36, 89, 90, 37, 84, 38, 83, 84, 39, 78, 40, 77, 78, 27, 44, 26, 43, 25, 42, + 24, 41, 23, 34, 22, 33, 21, 32, 20, 31, 19, 30, 18, 29, 17, 28, 27, 44, 26, + 43, 25, 42, 24, 41, 23, 34, 22, 33, 21, 32, 20, 31, 19, 30, 18, 29, 17, 28, + 10, 14, 71, 72, 85, 86, 87, 88, 89, 90, 11, 15, 69, 70, 79, 80, 81, 82, 83, + 84, 12, 16, 67, 68, 73, 74, 75, 76, 77, 78, 35, 90, 36, 89, 90, 37, 84, 38, + 83, 84, 39, 78, 40, 77, 78, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 27, + 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 10, 14, 71, 72, 85, 86, 87, 88, 89, + 90, 11, 15, 69, 70, 79, 80, 81, 82, 83, 84, 12, 16, 67, 68, 73, 74, 75, 76, + 77, 78, 35, 90, 36, 89, 90, 37, 84, 38, 83, 84, 39, 78, 40, 77, 78}; + +real_t A_val[] = { +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.8678200000000004e+01, + 9.3617050000000006e+01, 1.6000000000000000e+01, 8.1999999999999993e+00, + 9.9000000000000000e+01, 8.0000000000000000e+01, 1.2000000000000000e+01, + 9.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.0062830000000005e+01, 9.9224010000000007e+01, 1.0000000000000000e+02, + 2.1100000000000001e+01, 1.0000000000000000e+02, 1.0000000000000000e+02, + 1.1400000000000000e+02, 1.1680000000000000e+02, -1.0000000000000000e+00, + 1.0000000000000000e+00, 7.4697360000000003e+01, 8.3801220000000001e+01, +-8.1999999999999993e+00, 2.0000000000000000e+00, 9.0000000000000000e+01, + 2.3999999999999999e+00, -1.2000000000000000e+01, -1.4800000000000001e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 7.9194209999999998e+01, + 9.0175110000000004e+01, 4.3000000000000000e+01, 8.0000000000000000e+00, + 1.0000000000000000e+02, 9.5000000000000000e+01, 9.0000000000000000e+00, + 2.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, + 7.8568219999999997e+01, 8.5996200000000002e+01, -1.2500000000000000e+01, + 1.0000000000000000e+00, 9.6500000000000000e+01, 4.0000000000000000e+00, +-1.8000000000000000e+01, -2.1899999999999999e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.2922240000000002e+01, 8.6963380000000001e+01, + 6.5000000000000000e+01, 1.2500000000000000e+01, 1.0000000000000000e+02, + 9.8000000000000000e+01, 4.9000000000000000e+01, 3.7000000000000000e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.2592740000000006e+01, + 9.3147599999999997e+01, -1.2000000000000000e+01, 1.0000000000000000e+00, + 9.6500000000000000e+01, 4.0000000000000000e+00, -1.8000000000000000e+01, +-2.1899999999999999e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 7.6506460000000004e+01, 7.8210250000000002e+01, 7.9000000000000000e+01, + 1.2000000000000000e+01, 1.0000000000000000e+02, 9.5000000000000000e+01, + 6.8000000000000000e+01, 6.1000000000000000e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.8357460000000003e+01, 9.4257840000000002e+01, + 1.2500000000000000e+02, 6.1299999999999997e+01, 1.0000000000000000e+02, + 1.0000000000000000e+02, 1.4500000000000000e+02, 1.4500000000000000e+02, +-1.0000000000000000e+00, 1.0000000000000000e+00, 9.0590469999999996e+01, + 1.0582863000000000e+02, 6.2000000000000002e+00, 6.0000000000000000e+00, + 9.7000000000000000e+01, 2.8500000000000000e+01, 4.0000000000000000e+00, + 3.6000000000000001e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.8678200000000004e+01, 9.3617050000000006e+01, 1.6000000000000000e+01, + 8.1999999999999993e+00, 9.9000000000000000e+01, 8.0000000000000000e+01, + 1.2000000000000000e+01, 9.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.0062830000000005e+01, 9.9224010000000007e+01, + 1.0000000000000000e+02, 2.1100000000000001e+01, 1.0000000000000000e+02, + 1.0000000000000000e+02, 1.1400000000000000e+02, 1.1680000000000000e+02, +-1.0000000000000000e+00, 1.0000000000000000e+00, 7.4697360000000003e+01, + 8.3801220000000001e+01, -8.1999999999999993e+00, 2.0000000000000000e+00, + 9.0000000000000000e+01, 2.3999999999999999e+00, -1.2000000000000000e+01, +-1.4800000000000001e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 7.9194209999999998e+01, 9.0175110000000004e+01, 4.3000000000000000e+01, + 8.0000000000000000e+00, 1.0000000000000000e+02, 9.5000000000000000e+01, + 9.0000000000000000e+00, 2.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, 7.8568219999999997e+01, 8.5996200000000002e+01, +-1.2500000000000000e+01, 1.0000000000000000e+00, 9.6500000000000000e+01, + 4.0000000000000000e+00, -1.8000000000000000e+01, -2.1899999999999999e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.2922240000000002e+01, + 8.6963380000000001e+01, 6.5000000000000000e+01, 1.2500000000000000e+01, + 1.0000000000000000e+02, 9.8000000000000000e+01, 4.9000000000000000e+01, + 3.7000000000000000e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.2592740000000006e+01, 9.3147599999999997e+01, -1.2000000000000000e+01, + 1.0000000000000000e+00, 9.6500000000000000e+01, 4.0000000000000000e+00, +-1.8000000000000000e+01, -2.1899999999999999e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 7.6506460000000004e+01, 7.8210250000000002e+01, + 7.9000000000000000e+01, 1.2000000000000000e+01, 1.0000000000000000e+02, + 9.5000000000000000e+01, 6.8000000000000000e+01, 6.1000000000000000e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.8357460000000003e+01, + 9.4257840000000002e+01, 1.2500000000000000e+02, 6.1299999999999997e+01, + 1.0000000000000000e+02, 1.0000000000000000e+02, 1.4500000000000000e+02, + 1.4500000000000000e+02, -1.0000000000000000e+00, 1.0000000000000000e+00, + 9.0590469999999996e+01, 1.0582863000000000e+02, 6.2000000000000002e+00, + 6.0000000000000000e+00, 9.7000000000000000e+01, 2.8500000000000000e+01, + 4.0000000000000000e+00, 3.6000000000000001e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.8678200000000004e+01, 9.3617050000000006e+01, + 1.6000000000000000e+01, 8.1999999999999993e+00, 9.9000000000000000e+01, + 8.0000000000000000e+01, 1.2000000000000000e+01, 9.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, 8.0062830000000005e+01, + 9.9224010000000007e+01, 1.0000000000000000e+02, 2.1100000000000001e+01, + 1.0000000000000000e+02, 1.0000000000000000e+02, 1.1400000000000000e+02, + 1.1680000000000000e+02, -1.0000000000000000e+00, 1.0000000000000000e+00, + 7.4697360000000003e+01, 8.3801220000000001e+01, -8.1999999999999993e+00, + 2.0000000000000000e+00, 9.0000000000000000e+01, 2.3999999999999999e+00, +-1.2000000000000000e+01, -1.4800000000000001e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 7.9194209999999998e+01, 9.0175110000000004e+01, + 4.3000000000000000e+01, 8.0000000000000000e+00, 1.0000000000000000e+02, + 9.5000000000000000e+01, 9.0000000000000000e+00, 2.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, 7.8568219999999997e+01, + 8.5996200000000002e+01, -1.2500000000000000e+01, 1.0000000000000000e+00, + 9.6500000000000000e+01, 4.0000000000000000e+00, -1.8000000000000000e+01, +-2.1899999999999999e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.2922240000000002e+01, 8.6963380000000001e+01, 6.5000000000000000e+01, + 1.2500000000000000e+01, 1.0000000000000000e+02, 9.8000000000000000e+01, + 4.9000000000000000e+01, 3.7000000000000000e+01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 8.2592740000000006e+01, 9.3147599999999997e+01, +-1.2000000000000000e+01, 1.0000000000000000e+00, 9.6500000000000000e+01, + 4.0000000000000000e+00, -1.8000000000000000e+01, -2.1899999999999999e+01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 7.6506460000000004e+01, + 7.8210250000000002e+01, 7.9000000000000000e+01, 1.2000000000000000e+01, + 1.0000000000000000e+02, 9.5000000000000000e+01, 6.8000000000000000e+01, + 6.1000000000000000e+01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 8.8357460000000003e+01, 9.4257840000000002e+01, 1.2500000000000000e+02, + 6.1299999999999997e+01, 1.0000000000000000e+02, 1.0000000000000000e+02, + 1.4500000000000000e+02, 1.4500000000000000e+02, -1.0000000000000000e+00, + 1.0000000000000000e+00, 9.0590469999999996e+01, 1.0582863000000000e+02, + 6.2000000000000002e+00, 6.0000000000000000e+00, 9.7000000000000000e+01, + 2.8500000000000000e+01, 4.0000000000000000e+00, 3.6000000000000001e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, -1.2000000000000000e-01, +-3.8000000000000000e-01, -5.0000000000000000e-01, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, +-4.7000000000000000e+01, -8.6999999999999993e+00, -9.0000000000000000e+01, +-5.0000000000000000e+01, -1.0000000000000000e+01, -1.0000000000000000e+01, +-9.3000000000000000e+01, -8.9000000000000000e+01, 1.0000000000000000e+00, +-1.0000000000000000e+00, -4.7000000000000000e+01, -8.6999999999999993e+00, +-9.0000000000000000e+01, -5.0000000000000000e+01, -1.0000000000000000e+01, +-1.0000000000000000e+01, -8.9000000000000000e+01, -8.5000000000000000e+01, + 1.0000000000000000e+00, -1.0000000000000000e+00, -4.7000000000000000e+01, +-8.6999999999999993e+00, -9.0000000000000000e+01, -5.0000000000000000e+01, +-1.0000000000000000e+01, -1.0000000000000000e+01, -9.1000000000000000e+01, +-8.8000000000000000e+01, -1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 5.0000000000000000e-01, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, -4.7000000000000000e+01, +-8.6999999999999993e+00, -9.0000000000000000e+01, -5.0000000000000000e+01, +-1.0000000000000000e+01, -1.0000000000000000e+01, -9.3000000000000000e+01, +-8.9000000000000000e+01, 1.0000000000000000e+00, -1.0000000000000000e+00, +-4.7000000000000000e+01, -8.6999999999999993e+00, -9.0000000000000000e+01, +-5.0000000000000000e+01, -1.0000000000000000e+01, -1.0000000000000000e+01, +-8.9000000000000000e+01, -8.5000000000000000e+01, 1.0000000000000000e+00, +-1.0000000000000000e+00, -4.7000000000000000e+01, -8.6999999999999993e+00, +-9.0000000000000000e+01, -5.0000000000000000e+01, -1.0000000000000000e+01, +-1.0000000000000000e+01, -9.1000000000000000e+01, -8.8000000000000000e+01, +-1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 5.0000000000000000e-01, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, 1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, 1.0000000000000000e+00, +-1.0000000000000000e+00, -4.7000000000000000e+01, -8.6999999999999993e+00, +-9.0000000000000000e+01, -5.0000000000000000e+01, -1.0000000000000000e+01, +-1.0000000000000000e+01, -9.3000000000000000e+01, -8.9000000000000000e+01, + 1.0000000000000000e+00, -1.0000000000000000e+00, -4.7000000000000000e+01, +-8.6999999999999993e+00, -9.0000000000000000e+01, -5.0000000000000000e+01, +-1.0000000000000000e+01, -1.0000000000000000e+01, -8.9000000000000000e+01, +-8.5000000000000000e+01, 1.0000000000000000e+00, -1.0000000000000000e+00, +-4.7000000000000000e+01, -8.6999999999999993e+00, -9.0000000000000000e+01, +-5.0000000000000000e+01, -1.0000000000000000e+01, -1.0000000000000000e+01, +-9.1000000000000000e+01, -8.8000000000000000e+01, -1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, +-1.0000000000000000e+00, -1.0000000000000000e+00, -1.0000000000000000e+00, + 1.0000000000000000e+00, -1.0000000000000000e+00, -4.7000000000000000e+01, +-8.6999999999999993e+00, -9.0000000000000000e+01, -5.0000000000000000e+01, +-1.0000000000000000e+01, -1.0000000000000000e+01, -9.3000000000000000e+01, +-8.9000000000000000e+01, 1.0000000000000000e+00, -1.0000000000000000e+00, +-4.7000000000000000e+01, -8.6999999999999993e+00, -9.0000000000000000e+01, +-5.0000000000000000e+01, -1.0000000000000000e+01, -1.0000000000000000e+01, +-8.9000000000000000e+01, -8.5000000000000000e+01, 1.0000000000000000e+00, +-1.0000000000000000e+00, -4.7000000000000000e+01, -8.6999999999999993e+00, +-9.0000000000000000e+01, -5.0000000000000000e+01, -1.0000000000000000e+01, +-1.0000000000000000e+01, -9.1000000000000000e+01, -8.8000000000000000e+01, +-1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 1.0000000000000000e+00, 5.0000000000000000e-01, -1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 1.0000000000000000e+00, + 5.0000000000000000e-01, -1.0000000000000000e+00, 5.0000000000000000e-01, +-1.0000000000000000e+00, 1.0000000000000000e+00, 5.0000000000000000e-01}; + +real_t g[] = {+0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, -2e+00, -2e+00, -2e+00, -2e+00, -2e+00, -2e+00, -2e+00, + -2e+00, +0e+00, -2e+00, +0e+00, +2e-03, +2e-03, +2e-03, +2e-03, +2e-03, + +2e-03, +1e-03, +2e-03, +2e-03, +2e-03, +0e+00, -2e-03, -2e-03, -2e-03, + -2e-03, -2e-03, -2e-03, -1e-03, -2e-03, -2e-03, -2e-03, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +2e-03, + +2e-03, +2e-03, +2e-03, +2e-03, +2e-03, +1e-03, +2e-03, +2e-03, +2e-03, + +0e+00, -2e-03, -2e-03, -2e-03, -2e-03, -2e-03, -2e-03, -1e-03, -2e-03, + -2e-03, -2e-03, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +2e-03, +2e-03, +2e-03, +2e-03, +2e-03, +2e-03, + +1e-03, +2e-03, +2e-03, +2e-03, +0e+00, -2e-03, -2e-03, -2e-03, -2e-03, + -2e-03, -2e-03, -1e-03, -2e-03, -2e-03, -2e-03, +0e+00, +0e+00, +0e+00, + +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +1e-01, +1e-01, + +1e-01, +1e-01, +1e-01, +1e-01, +1e-01, +1e-01, +1e-01, +1e-01, +0e+00, + -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, -1e-01, + -1e-01, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, +0e+00, + +0e+00}; + +real_t lb[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -Inf, 0, -Inf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, + 10, 5, 0, 10, 0, 2, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 5, 10, 5, 0, 10, 0, 5, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 10, 5, 0, 10, 0, 5, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +real_t ub[] = {Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, 0, 92, 39, 87, 29, 0, 20, 0, 28, 20, 71, Inf, 130, 45, 53, 55, 75, + 112, 0, 73, 480, 154, 121, 50, 30, 77, 20, 0, 18, 0, 5, 20, 71, Inf, Inf, + Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, 130, 55, 93, 60, 75, 115, 0, 67, + 480, 154, 121, 50, 20, 37, 15, 0, 15, 0, 8, 20, 71, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, Inf, Inf, Inf, 130, 55, 93, 60, 75, 105, 0, 67, 4980, 154, 110, + 50, 20, 37, 15, 0, 25, 0, 8, 20, 71, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, 20, 20, 20, 20, 0, 20, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf}; + +real_t lbA[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -Inf, -Inf, + -Inf, -Inf, -Inf, -Inf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0}; + +real_t ubA[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, + Inf, Inf, Inf, Inf}; + +long H_nnz = sizeof(H_val) / sizeof(real_t); +long A_nnz = sizeof(A_val) / sizeof(real_t); diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_runAllOqpExamples.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_runAllOqpExamples.cpp new file mode 100644 index 0000000..6197891 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_runAllOqpExamples.cpp @@ -0,0 +1,177 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_runAllOqpExamples.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2013-2017 + * + * Use qpOASES for solving all QP sequences of the Online QP Benchmark + * Collection. In order to run it, you have to download all examples + * from http://www.qpOASES.org/onlineQP/. + */ + + + +#include +#include + + +/** Example for qpOASES main function using the OQP interface. */ +int main( ) +{ + USING_NAMESPACE_QPOASES + + /* 1) Define benchmark arguments. */ + BooleanType isSparse = BT_FALSE; + BooleanType useHotstarts; + + Options options; + options.setToMPC(); + options.printLevel = PL_LOW; + + int_t maxAllowedNWSR; + real_t maxNWSR, avgNWSR, maxCPUtime, avgCPUtime; + real_t maxStationarity, maxFeasibility, maxComplementarity; + + const int_t numBenchmarks = 4; //5 + const char *benchmarkPath[numBenchmarks]; + benchmarkPath[0] = "../testing/cpp/data/oqp/chain80/"; + benchmarkPath[1] = "../testing/cpp/data/oqp/chain80w/"; + benchmarkPath[2] = "../testing/cpp/data/oqp/diesel/"; + benchmarkPath[3] = "../testing/cpp/data/oqp/crane/"; + //benchmarkPath[4] = "../testing/cpp/data/oqp/CDU/"; + + + /* 2) Run all benchmarks in a loop */ + for ( int_t ii=0; ii<2*numBenchmarks; ++ii ) + { + if ( ii%2 == 0 ) + useHotstarts = BT_FALSE; + else + useHotstarts = BT_TRUE; + + maxAllowedNWSR = 1000; + maxNWSR = 0.0; + avgNWSR = 0.0; + maxCPUtime = 1000.0; /* seconds */ + avgCPUtime = 0.0; /* seconds */ + maxStationarity = 0.0; + maxFeasibility = 0.0; + maxComplementarity = 0.0; + + if ( runOqpBenchmark( benchmarkPath[ii/2], + isSparse,useHotstarts, + options,maxAllowedNWSR, + maxNWSR,avgNWSR,maxCPUtime,avgCPUtime, + maxStationarity,maxFeasibility,maxComplementarity + ) != SUCCESSFUL_RETURN ) + { + myPrintf( "Something went wrong when running benchmark!\n" ); + return TEST_DATA_NOT_FOUND; + } + + /* 3) Print results. */ + printf( "\n\n" ); + if ( useHotstarts == BT_FALSE ) + printf( "OQP Benchmark Results for %s (cold-starts):\n", benchmarkPath[ii/2] ); + else + printf( "OQP Benchmark Results for %s (hot-starts):\n", benchmarkPath[ii/2] ); + + printf( "===========================================================================\n\n" ); + printf( "maximum CPU time: %.2f milliseconds\n",1000.0*maxCPUtime ); + printf( "average CPU time: %.2f milliseconds\n",1000.0*avgCPUtime ); + printf( "\n" ); + printf( "maximum iterations: %.1f\n",maxNWSR ); + printf( "average iterations: %.1f\n",avgNWSR ); + printf( "\n" ); + printf( "maximum violation stationarity: %.3e\n",maxStationarity ); + printf( "maximum violation feasibility: %.3e\n",maxFeasibility ); + printf( "maximum violation complementarity: %.3e\n",maxComplementarity ); + printf( "\n" ); + + QPOASES_TEST_FOR_TOL( maxStationarity, 1e-9 ); + QPOASES_TEST_FOR_TOL( maxFeasibility, 2e-11 ); + QPOASES_TEST_FOR_TOL( maxComplementarity, 2e-10 ); + + switch( ii ) + { + case 0: + /* chain80 (cold) */ + QPOASES_TEST_FOR_TRUE( maxNWSR <= 62.5 ); + QPOASES_TEST_FOR_TRUE( avgNWSR <= 7.5 ); + break; + + case 1: + /* chain80 (hot) */ + QPOASES_TEST_FOR_TRUE( maxNWSR <= 19.5 ); + QPOASES_TEST_FOR_TRUE( avgNWSR <= 2.4 ); + break; + + case 2: + /* chain80w (cold) */ + QPOASES_TEST_FOR_TRUE( maxNWSR <= 84.5 ); + QPOASES_TEST_FOR_TRUE( avgNWSR <= 10.1 ); + break; + + case 3: + /* chain80w (hot) */ + QPOASES_TEST_FOR_TRUE( maxNWSR <= 16.5 ); + QPOASES_TEST_FOR_TRUE( avgNWSR <= 2.7 ); + break; + + case 4: + /* diesel (cold) */ + QPOASES_TEST_FOR_TRUE( maxNWSR <= 26.5 ); + QPOASES_TEST_FOR_TRUE( avgNWSR <= 0.5 ); + break; + + case 5: + /* diesel (hot) */ + QPOASES_TEST_FOR_TRUE( maxNWSR <= 22.5 ); + QPOASES_TEST_FOR_TRUE( avgNWSR <= 0.3 ); + break; + + case 6: + /* crane (cold) */ + QPOASES_TEST_FOR_TRUE( maxNWSR <= 64.5 ); + QPOASES_TEST_FOR_TRUE( avgNWSR <= 44.0 ); + break; + + case 7: + /* crane (hot) */ + QPOASES_TEST_FOR_TRUE( maxNWSR <= 42.5 ); + QPOASES_TEST_FOR_TRUE( avgNWSR <= 0.4 ); + break; + } + } + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_sebastien1.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_sebastien1.cpp new file mode 100644 index 0000000..7c41a64 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_sebastien1.cpp @@ -0,0 +1,74 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_sebastien1.cpp + * \author Sebastien B. + * \version 3.2 + * \date 2007-2017 + * + * Example that caused troubles in an earlier release. + */ + + + +#include +#include + + +/** qpOASES main function defining a unit test. */ +int main( ) +{ + REFER_NAMESPACE_QPOASES real_t solution[2] = {0.0f, 0.0f}; + REFER_NAMESPACE_QPOASES real_t expectedFirst[2] = {0.5f, -1.5f}; + + REFER_NAMESPACE_QPOASES real_t H[2*2] = {1.0f, 0.0f, 0.0f, 0.5f}; + REFER_NAMESPACE_QPOASES real_t g[2] = {1.5f, 1.0f}; + + REFER_NAMESPACE_QPOASES real_t A[1*2] = {1.0f, 1.0f}; + REFER_NAMESPACE_QPOASES real_t lbA[1] = {-1.0f}; + REFER_NAMESPACE_QPOASES real_t ubA[1] = {2.0f}; + + REFER_NAMESPACE_QPOASES real_t lb[2] = {0.5f, -2.0f}; + REFER_NAMESPACE_QPOASES real_t ub[2] = {5.0f, 2.0f}; + + REFER_NAMESPACE_QPOASES QProblem example(2, 1); + REFER_NAMESPACE_QPOASES Options options = example.getOptions(); + //options.enableFarBounds = REFER_NAMESPACE_QPOASES BT_FALSE; + example.setOptions(options); + example.setPrintLevel(REFER_NAMESPACE_QPOASES PL_NONE); + + // Solve first QP. + REFER_NAMESPACE_QPOASES int_t nWSR = 10; + QPOASES_TEST_FOR_TRUE( example.init(H, g, A, lb, ub, lbA, ubA, nWSR, NULL) == REFER_NAMESPACE_QPOASES SUCCESSFUL_RETURN ); + QPOASES_TEST_FOR_TRUE( example.isSolved() == REFER_NAMESPACE_QPOASES BT_TRUE ); + example.getPrimalSolution(solution); + + printf( "\nxOpt = [ %e, %e ];\n\n", solution[0],solution[1] ); + + for( REFER_NAMESPACE_QPOASES uint_t i=0; i<2; i++ ) + QPOASES_TEST_FOR_NEAR( solution[i],expectedFirst[i] ); + + return TEST_PASSED; +} diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_smallSchur.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_smallSchur.cpp new file mode 100644 index 0000000..de4c8f5 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_smallSchur.cpp @@ -0,0 +1,141 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_smallSchur.cpp + * \author Dennis Janka + * \version 3.2 + * \date 2007-2017 + * + */ + + + +#include +#include + +int main( ) +{ + USING_NAMESPACE_QPOASES + + int_t i; + const int_t m = 200; + const int_t n = 2*m + 1; + + /* problem data */ + sparse_int_t H_jc[n+1], H_ir[n], A_jc[n+1], A_ir[m]; + real_t H_val[n], A_val[m], g[n], lb[n], ub[n], lbA[m], ubA[m]; + for (i = 0; i < n+1; i++) H_jc[i] = i; + for (i = 0; i < n; i++) H_ir[i] = i; + for (i = 0; i < n; i++) H_val[i] = 2.0; + for (i = 0; i < m; i++) A_jc[i] = i; + for (i = m; i < n+1; i++) A_jc[i] = m; + for (i = 0; i < m; i++) A_ir[i] = i; + for (i = 0; i < m; i++) A_val[i] = 1.0; + for (i = 0; i < n; i++) g[i] = 0.0; + for (i = 0; i < n; i++) lb[i] = -1.0; + for (i = 0; i < n; i++) ub[i] = 1.0; + for (i = 0; i < m; i++) lbA[i] = 0.5; + for (i = 0; i < m; i++) ubA[i] = 0.5; + + int_t nWSR; + real_t errP, errD, tic, toc; + real_t *xref = new real_t[n]; + real_t *yref = new real_t[n+m]; + real_t *x = new real_t[n]; + real_t *y = new real_t[n+m]; + + Options options; + options.setToDefault(); + options.printLevel = PL_TABULAR; + options.initialStatusBounds = ST_UPPER; + /* options.enableEqualities = BT_FALSE; */ + + /* create sparse matrices */ + SymSparseMat *H = new SymSparseMat(n, n, H_ir, H_jc, H_val); + SparseMatrix *A = new SparseMatrix(m, n, A_ir, A_jc, A_val); + + H->createDiagInfo(); + + /* solve with dense matrices */ + nWSR = 1000; + QProblem qpD(n, m); + qpD.setOptions(options); + tic = getCPUtime(); + qpD.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qpD.getPrimalSolution(xref); + qpD.getDualSolution(yref); + + fprintf(stdFile, "Solved problem with dense LA in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + + /* solve with sparse matrices (Schur complement) */ + #ifndef SOLVER_NONE + nWSR = 10000; + SQProblemSchur qp(n, m); + // qp.setOptions(options); + tic = getCPUtime(); + qp.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0); + toc = getCPUtime(); + qp.getPrimalSolution(x); + qp.getDualSolution(y); + + fprintf(stdFile, "Solved problem with Schur complement approach in %d iterations, %.3f seconds.\n", (int)nWSR, toc-tic); + #endif /* SOLVER_NONE */ + + /* check distance of solutions */ + errP = 0.0; + #ifndef SOLVER_NONE + for (i = 0; i < n; i++) + if (getAbs(x[i] - xref[i]) > errP) + errP = getAbs(x[i] - xref[i]); + #endif /* SOLVER_NONE */ + fprintf(stdFile, "Primal error: %9.2e\n", errP); + + errD = 0.0; + #ifndef SOLVER_NONE + for (i = 0; i < n+m; i++) + if (getAbs(y[i] - yref[i]) > errD) + errD = getAbs(y[i] - yref[i]); + #endif /* SOLVER_NONE */ + fprintf(stdFile, "Dual error: %9.2e\n", errD); + + delete H; + delete A; + + delete[] y; + delete[] x; + delete[] yref; + delete[] xref; + + QPOASES_TEST_FOR_TOL( errP,1e-12 ); + QPOASES_TEST_FOR_TOL( errD,1e-12 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/cpp/test_vanBarelsUnboundedQP.cpp b/locomotion/src/third_party/qpOASES/testing/cpp/test_vanBarelsUnboundedQP.cpp new file mode 100644 index 0000000..d2de457 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/cpp/test_vanBarelsUnboundedQP.cpp @@ -0,0 +1,69 @@ +/* + * This file is part of qpOASES. + * + * qpOASES -- An Implementation of the Online Active Set Strategy. + * Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, + * Christian Kirches et al. All rights reserved. + * + * qpOASES is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * qpOASES is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with qpOASES; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +/** + * \file testing/cpp/test_vanBarelsUnboundedQP.cpp + * \author Hans Joachim Ferreau + * \version 3.2 + * \date 2007-2017 + * + * Example that causes troubles when hotstarting. + */ + + + +#include +#include + +#include + + + +int main( ) +{ + USING_NAMESPACE_QPOASES + + real_t H[2*2] = { 1.0, 0.0, 0.0, 0.0 }; + real_t g[2] = { 1.5, 1.0 }; + + Options options; + //options.enableFarBounds = BT_FALSE; + + QProblemB qp(2); + qp.setOptions( options ); + + int_t iter = 10; + qp.init( H,g,0,0,iter ); + + real_t xOpt[2]; + qp.getPrimalSolution( xOpt ); + print( xOpt,2 ); + + return TEST_PASSED; +} + + +/* + * end of file + */ diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/generateExample.m b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/generateExample.m new file mode 100644 index 0000000..9476d7e --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/generateExample.m @@ -0,0 +1,25 @@ +function [ qpData ] = generateExample( nV,nC, isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC, seed, givenH,givenA ) + + if ( nargin < 11 ) + givenA = []; + if ( nargin < 10 ) + givenH = []; + end + end + + qpFeatures = setupQpFeaturesStruct( ); + + qpFeatures.nV = nV; + qpFeatures.nC = nC; + + qpFeatures.isSparseH = isSparseH; + qpFeatures.isSparseA = isSparseA; + + qpFeatures.hasLowerB = hasLowerB; + qpFeatures.hasUpperB = hasUpperB; + qpFeatures.hasLowerC = hasLowerC; + qpFeatures.hasUpperC = hasUpperC; + + qpData = generateRandomQp( qpFeatures,seed, givenH,givenA ); + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/generateRandomQp.m b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/generateRandomQp.m new file mode 100644 index 0000000..3fd4fd3 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/generateRandomQp.m @@ -0,0 +1,110 @@ +function [ qpData ] = generateRandomQp( qpFeatures,randSeed, givenH,givenA ) + + if ( nargin < 4 ) + givenA = []; + if ( nargin < 3 ) + givenH = []; + end + end + + if ( isoctave == 0 ) + if ( nargin < 2 ) + s = RandStream( 'mt19937ar', 'Seed','shuffle' ); + RandStream.setGlobalStream(s); + else + s = RandStream( 'mt19937ar', 'Seed',randSeed ); + RandStream.setGlobalStream(s); + end + end + + + qpData = setupQpDataStruct( ); + qpData.nV = qpFeatures.nV; + qpData.nC = qpFeatures.nC; + + + % generate random optimal primal solution + xFeas = rand( qpFeatures.nV,1 ); + + % generate random optimal dual solution + %yOpt = zeros( qpFeatures.nV+qpFeatures.nC,1 ); + + if ( isempty(givenH) > 0 ) + + switch ( qpFeatures.hessianType ) + + case 0 + qpData.H = 100 * rand( qpData.nV,qpData.nV ) - 50; + qpData.H = qpData.H' * qpData.H / 2; + + case 1 + qpData.H = 100 * rand( qpData.nV,round(qpData.nV/2) ) - 50; + qpData.H = qpData.H' * qpData.H / 2; + + case 2 + qpData.H = eye( qpData.nV ); + + case 3 + qpData.H = zeros( qpData.nV,qpData.nV ); + + end + + else + qpData.H = givenH; + end + + qpData.g = 1000 * rand( qpFeatures.nV,1 ) - 500; + + if ( isempty(givenA) > 0 ) + + if ( qpFeatures.nC > 0 ) + qpData.Ain = 100 * rand( qpData.nC,qpData.nV ) - 50; + else + qpData.Ain = []; + end + + else + qpData.Ain = givenA; + end + + if ( qpFeatures.makeInfeas > 0 ) + alpha = -0.1; + beta = -0.001; + else + alpha = 1; + beta = 1; + end + + if ( qpFeatures.hasLowerB > 0 ) + qpData.lb = xFeas - 3*rand( qpData.nV,1 ); + else + qpData.lb = []; + end + + if ( qpFeatures.hasUpperB > 0 ) + qpData.ub = xFeas + alpha*3*rand( qpData.nV,1 ); + else + qpData.ub = []; + end + + if ( ( qpFeatures.hasLowerC > 0 ) && ( qpData.nC > 0 ) ) + qpData.lbA = qpData.Ain*xFeas - 100*rand( qpData.nC,1 ); + else + qpData.lbA = []; + end + + if ( ( qpFeatures.hasUpperC > 0 ) && ( qpData.nC > 0 ) ) + qpData.ubA = qpData.Ain*xFeas + beta*100*rand( qpData.nC,1 ); + else + qpData.ubA = []; + end + + if ( qpFeatures.isSparseH > 0 ) + qpData.H = sparse( qpData.H ); + end + + if ( qpFeatures.isSparseA > 0 ) + qpData.Ain = sparse( qpData.Ain ); + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/getKktResidual.m b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/getKktResidual.m new file mode 100644 index 0000000..55b17a0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/getKktResidual.m @@ -0,0 +1,134 @@ +function [kkt,stat,feas,cmpl] = getKktResidual( H,g,A,lb,ub,lbA,ubA, x,y ) + + % Tolerance for dual variables considered zero. + dualActiveTolerance = 1.0e3 * eps; + + % Initialize residuals + stat = 0.0; + feas = 0.0; + cmpl = 0.0; + + if ( isempty(H) == 0 ) + nV = size( H,1 ); + else + nV = size( g,2 ); + end + + if ( isempty(A) == 0 ) + nC = size( A,1 ); + else + nC = 0; + end + + + %% check stationarity + for i=1:nV + + % g term and variable bounds dual term + if ( isempty(g) == 0 ) + sum = g(i) - y(i); + else + sum = 0 - y(i); + end + + % H*x term + if ( isempty(H) == 0 ) + sum = sum + H(i,:) * x; + end + + % A'*y term + if ( isempty(A) == 0 ) + sum = sum - A(:,i)' * y(nV+1:nV+nC); + end + + % update stat + if (abs(sum) > stat) + stat = abs(sum); + end + + end + + %% check primal feasibility and complementarity + % variable bounds + for i=1:nV + + % feasibility + if ( isempty(lb) == 0 ) + if (lb(i) - x(i) > feas) + feas = lb(i) - x(i); + end + end + + if ( isempty(ub) == 0 ) + if (x(i) - ub(i) > feas) + feas = x(i) - ub(i); + end + end + + % complementarity + prod = 0.0; + + if ( isempty(lb) == 0 ) + if (y(i) > dualActiveTolerance) % lower bound + prod = (x(i) - lb(i)) * y(i); + end + end + + if ( isempty(ub) == 0 ) + if (y(i) < -dualActiveTolerance) % upper bound + prod = (x(i) - ub(i)) * y(i); + end + end + + if (abs(prod) > cmpl) + cmpl = abs(prod); + end + + end + + % A*x bounds + for i=1:nC + + % compute sum = (A*x)_i + sum = 0.0; + if ( isempty(A) == 0 ) + sum = sum + A(i,:) * x; + end + + % feasibility + if ( isempty(lbA) == 0 ) + if (lbA(i) - sum > feas) + feas = lbA(i) - sum; + end + end + + if ( isempty(ubA) == 0 ) + if (sum - ubA(i) > feas) + feas = sum - ubA(i); + end + end + + % complementarity + prod = 0.0; + + if ( isempty(lbA) == 0 ) + if (y(nV+i) > dualActiveTolerance) % lower bound + prod = (sum - lbA(i)) * y(nV+i); + end + end + + if ( isempty(ubA) == 0 ) + if (y(nV+i) < -dualActiveTolerance) % upper bound + prod = (sum - ubA(i)) * y(nV+i); + end + end + + if (abs(prod) > cmpl) + cmpl = abs(prod); + end + + end + + kkt = max( [stat,feas,cmpl] ); + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/isoctave.m b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/isoctave.m new file mode 100644 index 0000000..e4726d4 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/isoctave.m @@ -0,0 +1,21 @@ + +% ISOCTAVE True if the operating environment is octave. +% Usage: t=isoctave(); +% +% Returns 1 if the operating environment is octave, otherwise +% 0 (Matlab) +% +% --------------------------------------------------------------- +function t=isoctave() +%ISOCTAVE True if the operating environment is octave. +% Usage: t=isoctave(); +% +% Returns 1 if the operating environment is octave, otherwise +% 0 (Matlab) + +if exist('OCTAVE_VERSION') + % Only Octave has this variable. + t=1; +else + t=0; +end; diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/setupQpDataStruct.m b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/setupQpDataStruct.m new file mode 100644 index 0000000..93d9e3c --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/setupQpDataStruct.m @@ -0,0 +1,18 @@ +function [ qpData ] = setupQpDataStruct( ) + + qpData = struct( 'H', [], ... % Hessian matrix + 'g', [], ... % gradient vector + 'Aeq', [], ... % equality constraints matrix + 'beq', [], ... % equality constraints vector + 'lb', [], ... % lower bound vector + 'ub', [], ... % upper bound vector + 'Ain', [], ... % inequality constraints matrix + 'lbA', [], ... % lower constraints vector + 'ubA', [], ... % upper constraints vector + 'x0', [], ... % primal initial guess + 'options', [], ... % QP solver options + 'nV', 0, ... % number of QP variables + 'nC', 0 ... % number of constraints + ); + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/setupQpFeaturesStruct.m b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/setupQpFeaturesStruct.m new file mode 100644 index 0000000..903a891 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/auxFiles/setupQpFeaturesStruct.m @@ -0,0 +1,21 @@ +function [ qpFeatures ] = setupQpFeaturesStruct( ) + + qpFeatures = struct( 'nV', 0, ... + 'nIB', 0, ... + 'nEB', 0, ... + 'nC', 0, ... + 'nIC', 0, ... + 'nEC', 0, ... + 'nActB', 0, ... + 'nActC', 0, ... + 'hasLowerB', 0, ... + 'hasUpperB', 0, ... + 'hasLowerC', 0, ... + 'hasUpperC', 0, ... + 'isSparseH', 0, ... + 'isSparseA', 0, ... + 'makeInfeas', 0, ... + 'hessianType', 0 ... % 0 = pos def; 1 = pos sem def; 2 = id; 3 = zero + ); + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/data/fetch_matlab_data b/locomotion/src/third_party/qpOASES/testing/matlab/data/fetch_matlab_data new file mode 100755 index 0000000..aaac94b --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/data/fetch_matlab_data @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: testing/matlab/data/fetch_matlab_data +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2014-2017 + + +svn export https://projects.coin-or.org/svn/qpOASES/misc/testingdata/matlab . --force diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/runAllTests.m b/locomotion/src/third_party/qpOASES/testing/matlab/runAllTests.m new file mode 100644 index 0000000..f17b0a0 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/runAllTests.m @@ -0,0 +1,152 @@ +function [ successFlag ] = runAllTests( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 1; + + curWarnLevel = warning; + warning('off'); + + % add sub-folders to Matlab path + setupTestingPaths(); + + clc; + + %% run interface tests + fprintf( 'Running qpOASES interface tests... ' ) + successFlag = updateSuccessFlag( successFlag, runInterfaceTest( 10,20, doPrint,42 ) ); + + fprintf( 'Running qpOASES_sequence interface tests... ' ) + successFlag = updateSuccessFlag( successFlag, runInterfaceSeqTest( 8,5, doPrint,42 ) ); + + + %% run functional tests + fprintf( 'Running tests with random QPs having identity Hessian... ' ) + successFlag = updateSuccessFlag( successFlag, runRandomIdHessian( 12,12, doPrint,4242 ) ); + + fprintf( 'Running tests with random QPs having zero Hessian... ' ) + successFlag = updateSuccessFlag( successFlag, runRandomZeroHessian( 11,41, doPrint,4242 ) ); + + fprintf( 'Running qpOASES passing an empty Hessian matrix argument... ' ) + successFlag = updateSuccessFlag( successFlag, runEmptyHessianTests( doPrint ) ); + + fprintf( 'Running alternativeX0 test... ' ) + successFlag = updateSuccessFlag( successFlag, runAlternativeX0Test( 50,300,doPrint,4242 ) ); + + fprintf( 'Running testAPrioriKnownSeq1... ' ) + successFlag = updateSuccessFlag( successFlag, runTestAPrioriKnownSeq1( doPrint ) ); + + fprintf( 'Running testSeq... ' ) + successFlag = updateSuccessFlag( successFlag, runTestSeq( doPrint ) ); + + fprintf( 'Running testSparse... ' ) + successFlag = updateSuccessFlag( successFlag, runTestSparse( doPrint ) ); + + fprintf( 'Running testSparse2... ' ) + successFlag = updateSuccessFlag( successFlag, runTestSparse2( doPrint ) ); + + fprintf( 'Running testSparse3... ' ) + successFlag = updateSuccessFlag( successFlag, runTestSparse3( doPrint ) ); + + fprintf( 'Running testSparse4... ' ) + successFlag = updateSuccessFlag( successFlag, runTestSparse4( doPrint ) ); + + fprintf( 'Running simpleSpringExample... ' ) + successFlag = updateSuccessFlag( successFlag, runSimpleSpringExample( doPrint ) ); + + fprintf( 'Running vanBarelsUnboundedQP... ' ) + successFlag = updateSuccessFlag( successFlag, runVanBarelsUnboundedQP( doPrint ) ); + + fprintf( 'Running alexInfeas1... ' ) + successFlag = updateSuccessFlag( successFlag, runAlexInfeas1( doPrint ) ); + + %fprintf( 'Running alexInfeas2... ' ) + %successFlag = updateSuccessFlag( successFlag, runAlexInfeas2( doPrint ) ); + + %fprintf( 'Running QAP8... ' ) + %successFlag = updateSuccessFlag( successFlag, runQAP( doPrint ) ); + + fprintf( 'Running testWorkingSetLI... ' ) + successFlag = updateSuccessFlag( successFlag, runTestWorkingSetLI( doPrint ) ); + + fprintf( 'Running runExternalCholeskyTests... ' ) + successFlag = updateSuccessFlag( successFlag, runExternalCholeskyTests( doPrint ) ); + + fprintf( 'Running EXAMPEL1... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkEXAMPLE1( 10,doPrint ) ); + + fprintf( 'Running EXAMPLE1A... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkEXAMPLE1A( 10,doPrint ) ); + + fprintf( 'Running EXAMPLE1B... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkEXAMPLE1B( 10,doPrint ) ); + + fprintf( 'Running CHAIN1... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkCHAIN1( 20,doPrint ) ); + + fprintf( 'Running CHAIN1A... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkCHAIN1A( 20,doPrint ) ); + + fprintf( 'Running CRANE1... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkCRANE1( 100,doPrint ) ); + + fprintf( 'Running CRANE2... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkCRANE2( 100,doPrint ) ); + + fprintf( 'Running CRANE3... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkCRANE3( 100,doPrint ) ); + + fprintf( 'Running EQUALITY1... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkEQUALITY1( 100,doPrint ) ); + + fprintf( 'Running EQUALITY2... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkEQUALITY2( 3200,doPrint ) ); + + %fprintf( 'Running IDHESSIAN1... ' ); + %successFlag = updateSuccessFlag( successFlag, runBenchmarkIDHESSIAN1( 1200,doPrint ) ); + + fprintf( 'Running DIESEL... ' ); + successFlag = updateSuccessFlag( successFlag, runBenchmarkDIESEL( 230,doPrint ) ); + + fprintf( 'Running QSHARE1B... ' ) + successFlag = updateSuccessFlag( successFlag, runQSHARE1B( doPrint ) ); + + + + %% display results + disp( ' ' ); + + if ( successFlag == 0 ) + disp( 'At least one test failed!' ); + else + disp( 'All available tests passed successfully!' ); + end + + warning( curWarnLevel ); + +end + + +function [ newSuccessFlag ] = updateSuccessFlag( curSuccessFlag,curResult ) + + switch ( curResult ) + + case 0 + newSuccessFlag = 0; + fprintf( 'failed!\n' ); + + case 1 + newSuccessFlag = curSuccessFlag; + fprintf( 'passed!\n' ); + + case -1 + newSuccessFlag = curSuccessFlag; + fprintf( 'problem data missing!\n' ); + + otherwise + error( 'Unknown success flag!' ); + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/setupTestingPaths.m b/locomotion/src/third_party/qpOASES/testing/matlab/setupTestingPaths.m new file mode 100644 index 0000000..6373d11 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/setupTestingPaths.m @@ -0,0 +1,14 @@ +function [] = setupTestingPaths( ) + + addpath(genpath(pwd)); + addpath(genpath([pwd 'auxFiles'])); + addpath(genpath([pwd 'data'])); + addpath(genpath([pwd 'tests'])); + + if isoctave + addpath('../../interfaces/octave/'); + else + addpath('../../interfaces/matlab/'); + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlexInfeas1.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlexInfeas1.m new file mode 100644 index 0000000..d1977ed --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlexInfeas1.m @@ -0,0 +1,30 @@ +function [ successFlag ] = runAlexInfeas1( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + try + data = load( 'alexInfeas1.mat' ); + catch + successFlag = -1; + return; + end + + options1 = qpOASES_options( 'default', 'printLevel',-2*doPrint ); + + [x1,dummy,exitflag1] = qpOASES( data.H,data.g,data.A, ... + data.lb,data.ub,data.lbA,data.ubA, options1 ); %#ok<*NASGU> + + % should return "QP infeasible" + if ( exitflag1 == -2 ) + successFlag = 1; + else + if ( doPrint > 0 ) + disp( [data.lbA data.A*x1 data.ubA] ); + end + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlexInfeas2.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlexInfeas2.m new file mode 100644 index 0000000..730a01c --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlexInfeas2.m @@ -0,0 +1,35 @@ +function [ successFlag ] = runAlexInfeas2( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + try + data = load( 'alexInfeas2.mat' ); + catch + successFlag = -1; + return; + end + + options1 = qpOASES_options( 'default', 'printLevel',-2*doPrint,... + 'maxIter',7000, 'enableFlippingBounds',0,... + 'terminationTolerance',1e7*eps); + + options2 = qpOASES_options( 'MPC', 'printLevel',-2*doPrint,... + 'maxIter',3000, 'terminationTolerance',1e8*eps ); + + [x1,dummy,exitflag1] = qpOASES( data.H,data.g,data.A, ... + data.lb,data.ub,data.lbA,data.ubA, options1 ); %#ok<*NASGU> + + % should return "QP infeasible" + if ( exitflag1 == -2 ) + successFlag = 1; + else + if ( doPrint > 0 ) + %disp( [data.lbA data.A*x1 data.ubA] ); + end + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlternativeX0Test.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlternativeX0Test.m new file mode 100644 index 0000000..3178ed2 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runAlternativeX0Test.m @@ -0,0 +1,84 @@ +function [ successFlag ] = runAlternativeX0Test( nV,nC, doPrint,seed ) + + if ( nargin < 4 ) + seed = 4242; + if ( nargin < 3 ) + doPrint = 0; + if ( nargin < 2 ) + nC = 300; + if ( nargin < 1 ) + nV = 50; + end + end + end + end + + successFlag = 1; + TOL = eps; + + qpData = generateExample( nV,nC, 0,0, 0,1,1,1, seed ); + + H = qpData.H; + g = qpData.g; + A = [qpData.Aeq;qpData.Ain]; + lb = qpData.lb; + ub = qpData.ub; + lbA = [qpData.beq;qpData.lbA]; + ubA = [qpData.beq;qpData.ubA]; + + x0 = nV*rand( nV,1 ); + + options = qpOASES_options( 'default', 'printLevel',2*doPrint ); + auxInput = qpOASES_auxInput( 'x0',x0 ); + + [ x1,f1,e1,i1,l1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],x0 ); + [ x2,f2,e2,i2,l2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x3,f3,e3,i3,l3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,x0 ); + [ x4,f4,e4,i4,l4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + + if ( ( norm(x1-x2) > TOL ) || ... + ( norm(x1-x3) > TOL ) || ... + ( norm(x1-x4) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in x') + end + successFlag = 0; + end + + if ( ( norm(f1-f2) > TOL ) || ... + ( norm(f1-f3) > TOL ) || ... + ( norm(f1-f4) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in fval') + end + successFlag = 0; + end + + if ( ( norm(e1-e2) > TOL ) || ... + ( norm(e1-e3) > TOL ) || ... + ( norm(e1-e4) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in exitflag') + end + successFlag = 0; + end + + if ( ( norm(i1-i2) > TOL ) || ... + ( norm(i1-i3) > TOL ) || ... + ( norm(i1-i4) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in iter') + end + successFlag = 0; + end + + if ( ( norm(l1-l2) > TOL ) || ... + ( norm(l1-l3) > TOL ) || ... + ( norm(l1-l4) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in lambda') + end + successFlag = 0; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCHAIN1.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCHAIN1.m new file mode 100644 index 0000000..4aa70b1 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCHAIN1.m @@ -0,0 +1,60 @@ +function [ successFlag ] = runBenchmarkCHAIN1( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkCHAIN1.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + iter = zeros(1,nP); + + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + %options = qpOASES_options( 'maxIter',nWSR ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda,ws] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + %disp(ws') + else + [x,obj,status,nWSRout,lambda,ws] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + %disp(ws') + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + iter(:,i) = nWSRout; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 9e-13 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCHAIN1A.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCHAIN1A.m new file mode 100644 index 0000000..65311f6 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCHAIN1A.m @@ -0,0 +1,61 @@ +function [ successFlag ] = runBenchmarkCHAIN1A( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkCHAIN1A.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + %options = qpOASES_options( 'reliable', 'maxIter',500,'printLevel',1 ); +% ,'enableRamping',0,'enableFlippingBounds',0,'enableFullLITests',0,'enableDriftCorrection',0 + + + for jj=1:1 + + for i=1:nP + %disp(i); + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),lb(:,i),ub(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),[],lb(:,i),ub(:,i),[],[], x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + end + + if ( ( maxViolation < 1e-14 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE1.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE1.m new file mode 100644 index 0000000..4243ccf --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE1.m @@ -0,0 +1,55 @@ +function [ successFlag ] = runBenchmarkCRANE1( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkCRANE1.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 3e-9 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE2.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE2.m new file mode 100644 index 0000000..7f7d47f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE2.m @@ -0,0 +1,56 @@ +function [ successFlag ] = runBenchmarkCRANE2( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkCRANE2.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + %options = qpOASES_options( 'maxIter',nWSR ); + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'm',QP,H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 1e-11 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE3.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE3.m new file mode 100644 index 0000000..80caac9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkCRANE3.m @@ -0,0 +1,55 @@ +function [ successFlag ] = runBenchmarkCRANE3( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + try + load 'benchmarkCRANE3.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + %options = qpOASES_options( 'maxIter',nWSR ); + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 5e-11 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkDIESEL.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkDIESEL.m new file mode 100644 index 0000000..ad6c585 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkDIESEL.m @@ -0,0 +1,59 @@ +function [ successFlag ] = runBenchmarkDIESEL( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + try + load 'benchmarkDIESEL.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + nEC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + iter = zeros(1,nP); + + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + %options = qpOASES_options( 'maxIter',nWSR ); + %options = qpOASES_options( 'maxIter',nWSR, 'initialStatusBounds',0 ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + iter(:,i) = nWSRout; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 6e-13 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEQUALITY1.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEQUALITY1.m new file mode 100644 index 0000000..b304b42 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEQUALITY1.m @@ -0,0 +1,56 @@ +function [ successFlag ] = runBenchmarkEQUALITY1( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkEQUALITY1.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + %options = qpOASES_options( 'maxIter',nWSR ); + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 4e-15 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEQUALITY2.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEQUALITY2.m new file mode 100644 index 0000000..bd7c48d --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEQUALITY2.m @@ -0,0 +1,60 @@ +function [ successFlag ] = runBenchmarkEQUALITY2( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkEQUALITY2.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + %H = H; + %lbA(65:320) = lbA(65:320) - 0.000000000; + %ubA(65:320) = ubA(65:320) + 0.000000000; + + options = qpOASES_options( 'maxIter',nWSR, 'enableEqualities',1, 'printLevel',2*doPrint ); + %options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',-2 ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 3e-7 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1.m new file mode 100644 index 0000000..7706aff --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1.m @@ -0,0 +1,56 @@ +function [ successFlag ] = runBenchmarkEXAMPLE1( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkEXAMPLE1.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + %options = qpOASES_options( 'maxIter',nWSR ); + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 1e-12 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1A.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1A.m new file mode 100644 index 0000000..ba91b9e --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1A.m @@ -0,0 +1,56 @@ +function [ successFlag ] = runBenchmarkEXAMPLE1A( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkEXAMPLE1A.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + %options = qpOASES_options( 'maxIter',nWSR ); + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + + for i=1:2 + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H(:,:,i),g(:,i),A(:,:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'm',QP,H(:,:,i),g(:,i),A(:,:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H(:,:,i),g(:,i),A(:,:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 3e-13 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1B.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1B.m new file mode 100644 index 0000000..36e933f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkEXAMPLE1B.m @@ -0,0 +1,56 @@ +function [ successFlag ] = runBenchmarkEXAMPLE1B( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkEXAMPLE1B.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + %options = qpOASES_options( 'maxIter',nWSR ); + options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2*doPrint ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),lb(:,i),ub(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),options ); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),[],lb(:,i),ub(:,i),[],[], x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 3e-12 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkIDHESSIAN1.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkIDHESSIAN1.m new file mode 100644 index 0000000..d97797f --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runBenchmarkIDHESSIAN1.m @@ -0,0 +1,59 @@ +function [ successFlag ] = runBenchmarkIDHESSIAN1( nWSR,doPrint ) + + if ( nargin < 2 ) + doPrint = 0; + end + + successFlag = 0; + maxViolation = 0; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkIDHESSIAN1.mat'; + catch + successFlag = -1; + return; + end + + if ( exist( 'A','var' ) ) + [nC,nV] = size(A); + else + nC = 0; + end + [nV,nP] = size(g); + + xOpt = zeros(nV,nP); + yOpt = zeros(nV+nC,nP); + objOpt = zeros(1,nP); + + options = qpOASES_options( 'maxIter',nWSR, 'printLevel',-2*doPrint ); + %options = qpOASES_options( 'fast','maxIter',nWSR, 'printLevel',2 ); + + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i)-1e-11,ubA(:,i)+1e-11,options ); + %disp(status); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i)-1e-11,ubA(:,i)+1e-11,options ); + %disp(status); + end + + [ maxViolationTMP ] = getKktResidual( H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i), x,lambda ); + maxViolation = max( [maxViolation,maxViolationTMP] ); + + xOpt(:,i) = x; + yOpt(:,i) = lambda; + objOpt(:,i) = obj; + end + + qpOASES_sequence( 'c',QP ); + + if ( ( maxViolation < 8e-6 ) && ( status == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runEmptyHessianTests.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runEmptyHessianTests.m new file mode 100644 index 0000000..46ade51 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runEmptyHessianTests.m @@ -0,0 +1,261 @@ +function [ successFlag ] = runEmptyHessianTests( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 1; + + TOL = 100*eps; + + options = qpOASES_options( 'maxIter',100, 'enableEqualities',1, 'printLevel',-2*doPrint ); + auxInput0 = qpOASES_auxInput( 'hessianType',0 ); + auxInput1 = qpOASES_auxInput( 'hessianType',1 ); + auxInputErr = qpOASES_auxInput( 'hessianType',2 ); + + + load 'benchmarkEXAMPLE1.mat'; + + %% test qpOASES with zero Hessian + [ x1,obj1,status1,nWSRout1,lambda1 ] = qpOASES( 0*H,g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options ); + [ x2,obj2,status2,nWSRout2,lambda2 ] = qpOASES( [],g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options ); + [ x3,obj3,status3,nWSRout3,lambda3 ] = qpOASES( [],g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options,auxInput0 ); + [ x4,obj4,status4,nWSRout4,lambda4 ] = qpOASES( [],g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options,auxInputErr ); + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) || ( status3 ~= 0 ) || ( status4 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) || ( norm(x1-x3) > TOL ) || ( norm(x1-x4) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) || ( norm(obj1-obj3) > TOL ) || ( norm(obj1-obj4) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) || ( norm(lambda1-lambda3) > TOL ) || ( norm(lambda1-lambda4) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + + + %% test qpOASES_sequence with zero Hessian + [QP,x0,obj0,status0,nWSRout0,lambda0] = qpOASES_sequence( 'i',0*H,g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options ); %#ok + [x1,obj1,status1,nWSRout1,lambda1] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),lbA(:,2),ubA(:,2),options ); + qpOASES_sequence( 'c',QP ); + + [QP,x0,obj0,status0,nWSRout0,lambda0] = qpOASES_sequence( 'i',[],g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options ); %#ok + [x2,obj2,status2,nWSRout2,lambda2] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),lbA(:,2),ubA(:,2),options ); + qpOASES_sequence( 'c',QP ); + + [QP,x0,obj0,status0,nWSRout0,lambda0] = qpOASES_sequence( 'i',[],g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options,auxInput0 ); %#ok + [x3,obj3,status3,nWSRout3,lambda3] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),lbA(:,2),ubA(:,2),options ); + qpOASES_sequence( 'c',QP ); + + [QP,x0,obj0,status0,nWSRout0,lambda0] = qpOASES_sequence( 'i',[],g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options,auxInputErr ); %#ok + [x4,obj4,status4,nWSRout4,lambda4] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),lbA(:,2),ubA(:,2),options ); + qpOASES_sequence( 'c',QP ); + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) || ( status3 ~= 0 ) || ( status4 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) || ( norm(x1-x3) > TOL ) || ( norm(x1-x4) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) || ( norm(obj1-obj3) > TOL ) || ( norm(obj1-obj4) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) || ( norm(lambda1-lambda3) > TOL ) || ( norm(lambda1-lambda4) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + + + %% test qpOASES with ID Hessian + [ x1,obj1,status1,nWSRout1,lambda1 ] = qpOASES( eye(2),g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options ); + [ x2,obj2,status2,nWSRout2,lambda2 ] = qpOASES( [],g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options,auxInput1 ); + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(nWSRout1-nWSRout2) > 0.5 ) + if doPrint + disp( 'error in numer of iterations' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + + + %% test qpOASES_sequence with ID Hessian + [QP,x0,obj0,status0,nWSRout0,lambda0] = qpOASES_sequence( 'i',eye(2),g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options ); %#ok + [x1,obj1,status1,nWSRout1,lambda1] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),lbA(:,2),ubA(:,2),options ); + qpOASES_sequence( 'c',QP ); + + [QP,x0,obj0,status0,nWSRout0,lambda0] = qpOASES_sequence( 'i',[],g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options,auxInput1 ); %#ok + [x2,obj2,status2,nWSRout2,lambda2] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),lbA(:,2),ubA(:,2),options ); + qpOASES_sequence( 'c',QP ); + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(nWSRout1-nWSRout2) > 0.5 ) + if doPrint + disp( 'error in numer of iterations' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + + + load 'benchmarkEXAMPLE1B.mat'; + + %% test qpOASES (simply bounded) with zero Hessian + [ x1,obj1,status1,nWSRout1,lambda1 ] = qpOASES( 0*H,g(:,1),lb(:,1),ub(:,1),options ); + [ x2,obj2,status2,nWSRout2,lambda2 ] = qpOASES( [],g(:,1),lb(:,1),ub(:,1),options ); + [ x3,obj3,status3,nWSRout3,lambda3 ] = qpOASES( [],g(:,1),lb(:,1),ub(:,1),options,auxInput0 ); + [ x4,obj4,status4,nWSRout4,lambda4 ] = qpOASES( [],g(:,1),lb(:,1),ub(:,1),options,auxInputErr ); + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) || ( status3 ~= 0 ) || ( status4 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) || ( norm(x1-x3) > TOL ) || ( norm(x1-x4) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) || ( norm(obj1-obj3) > TOL ) || ( norm(obj1-obj4) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) || ( norm(lambda1-lambda3) > TOL ) || ( norm(lambda1-lambda4) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + + + %% test qpOASES (simply bounded) with ID Hessian + [ x1,obj1,status1,nWSRout1,lambda1 ] = qpOASES( eye(2),g(:,1),lb(:,1),ub(:,1),options ); + [ x2,obj2,status2,nWSRout2,lambda2 ] = qpOASES( [],g(:,1),lb(:,1),ub(:,1),options,auxInput1 ); + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(nWSRout1-nWSRout2) > 0.5 ) + if doPrint + disp( 'error in numer of iterations' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runExternalCholeskyTests.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runExternalCholeskyTests.m new file mode 100644 index 0000000..2434478 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runExternalCholeskyTests.m @@ -0,0 +1,214 @@ +function [ successFlag ] = runExternalCholeskyTests( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 1; + + TOL = 1e4*eps; + + load 'benchmarkCHAIN1.mat'; + + options = qpOASES_options( 'MPC', 'printLevel',2*doPrint ); + auxInput = qpOASES_auxInput( 'R',chol(H) ); + + %% test qpOASES + [ x1,obj1,status1,nWSRout1,lambda1,auxOut1 ] = qpOASES( H,g(:,10),A,lb(:,10),ub(:,10),lbA(:,10),ubA(:,10),options ); + [ x2,obj2,status2,nWSRout2,lambda2,auxOut2 ] = qpOASES( H,g(:,10),A,lb(:,10),ub(:,10),lbA(:,10),ubA(:,10),options,auxInput ); + + if doPrint + disp( ['Runtime without R: ', num2str(auxOut1.cpuTime),'s'] ) + disp( ['Runtime with R: ', num2str(auxOut2.cpuTime),'s'] ) + disp( ' ' ); + end + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(nWSRout1-nWSRout2) > 0.5 ) + if doPrint + disp( 'error in numer of iterations' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + + + %% test qpOASES_sequence + [QP,x0,obj0,status0,nWSRout0,lambda0,auxOut1] = qpOASES_sequence( 'i',H,g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options ); + [x1,obj1,status1,nWSRout1,lambda1] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),lbA(:,2),ubA(:,2),options ); + qpOASES_sequence( 'c',QP ); + + [QP,x0,obj0,status0,nWSRout0,lambda0,auxOut2] = qpOASES_sequence( 'i',H,g(:,1),A,lb(:,1),ub(:,1),lbA(:,1),ubA(:,1),options,auxInput ); + [x2,obj2,status2,nWSRout2,lambda2] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),lbA(:,2),ubA(:,2),options ); + qpOASES_sequence( 'c',QP ); + + if doPrint + disp( ['Runtime without R: ', num2str(auxOut1.cpuTime),'s'] ) + disp( ['Runtime with R: ', num2str(auxOut2.cpuTime),'s'] ) + disp( ' ' ) + end + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(nWSRout1-nWSRout2) > 0.5 ) + if doPrint + disp( 'error in numer of iterations' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + + + %% test simply bounded QP + load 'benchmarkCHAIN1A.mat'; + + options = qpOASES_options( 'MPC', 'printLevel',0*doPrint ); + auxInput = qpOASES_auxInput( 'R',chol(H) ); + + %% test qpOASES + [ x1,obj1,status1,nWSRout1,lambda1,auxOut1 ] = qpOASES( H,g(:,10),lb(:,10),ub(:,10),options ); + [ x2,obj2,status2,nWSRout2,lambda2,auxOut2 ] = qpOASES( H,g(:,10),lb(:,10),ub(:,10),options,auxInput ); + + if doPrint + disp( ['Runtime without R: ', num2str(auxOut1.cpuTime),'s'] ) + disp( ['Runtime with R: ', num2str(auxOut2.cpuTime),'s'] ) + disp( ' ' ); + end + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(nWSRout1-nWSRout2) > 0.5 ) + if doPrint + disp( 'error in numer of iterations' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + + %% test qpOASES_sequence + [QP,x0,obj0,status0,nWSRout0,lambda0,auxOut1] = qpOASES_sequence( 'i',H,g(:,1),lb(:,1),ub(:,1),options ); + [x1,obj1,status1,nWSRout1,lambda1] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),options ); + qpOASES_sequence( 'c',QP ); + + [QP,x0,obj0,status0,nWSRout0,lambda0,auxOut2] = qpOASES_sequence( 'i',H,g(:,1),lb(:,1),ub(:,1),options,auxInput ); + [x2,obj2,status2,nWSRout2,lambda2] = qpOASES_sequence( 'h',QP,g(:,2),lb(:,2),ub(:,2),options ); + qpOASES_sequence( 'c',QP ); + + if doPrint + disp( ['Runtime without R: ', num2str(auxOut1.cpuTime),'s'] ) + disp( ['Runtime with R: ', num2str(auxOut2.cpuTime),'s'] ) + disp( ' ' ) + end + + if ( status1 ~= 0 ) || ( status2 ~= 0 ) + if doPrint + disp( 'error' ); + end + successFlag = 0; + end + + if ( norm(x1-x2) > TOL ) + if doPrint + disp( 'error in primal solution' ); + end + successFlag = 0; + end + + if ( norm(obj1-obj2) > TOL ) + if doPrint + disp( 'error in objective function value' ); + end + successFlag = 0; + end + + if ( norm(nWSRout1-nWSRout2) > 0.5 ) + if doPrint + disp( 'error in numer of iterations' ); + end + successFlag = 0; + end + + if ( norm(lambda1-lambda2) > TOL ) + if doPrint + disp( 'error in dual solution' ); + end + successFlag = 0; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runInterfaceSeqTest.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runInterfaceSeqTest.m new file mode 100644 index 0000000..88c06ec --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runInterfaceSeqTest.m @@ -0,0 +1,436 @@ +function [ successFlag ] = runInterfaceSeqTest( nV,nC, doPrint,seed ) + + if ( nargin < 4 ) + seed = 42; + if ( nargin < 3 ) + doPrint = 1; + if ( nargin < 2 ) + nC = 10; + if ( nargin < 1 ) + nV = 5; + end + end + end + end + + successFlag = 1; + + for isSparseH=0:1 + for isSparseA=0:1 + successFlag = runSeveralInterfaceSeqTests( successFlag, nV,nC,isSparseH,isSparseA, doPrint,seed ); + end + end + +end + + + +function [ successFlag ] = runSeveralInterfaceSeqTests( successFlag, nV,nC, isSparseH,isSparseA, doPrint,seed ) + + %% test without or empty A matrix + for hasA=0:1 + for changeMat=0:hasA % cannot change matrices if QProblemB object is instantiated + for hasLowerB=0:1 + for hasUpperB=0:1 + for hasOptions=0:2 + for hasX0=0:2 + for hasWS=0:2 + curSuccessFLAG = runSingleInterfaceSeqTest( nV,0,hasA,isSparseH,isSparseA, hasLowerB,hasUpperB,0,0,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ); + successFlag = min( successFlag,curSuccessFLAG ); + end + end + end + end + end + end + end + + %% test with non-empty A matrix + for hasLowerB=0:1 + for hasUpperB=0:1 + for hasLowerC=0:1 + for hasUpperC=0:1 + for hasOptions=0:2 + for hasX0=0:2 + for hasWS=0:2 + for changeMat=0:1 + curSuccessFLAG = runSingleInterfaceSeqTest( nV,nC,1,isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ); + successFlag = min( successFlag,curSuccessFLAG ); + end + end + end + end + end + end + end + end + +end + + +function [ successFlag ] = runSingleInterfaceSeqTest( nV,nC,hasA,isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ) + + successFlag = 0; + + qpData1 = generateExample( nV,nC, isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC, seed ); + if ( changeMat > 0 ) + qpData2 = generateExample( nV,nC, isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC, seed+1 ); + else + qpData2 = generateExample( nV,nC, isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC, seed+1,qpData1.H,qpData1.Ain ); + end + + if ( changeMat == 0 ) + string = 'Testing qpOASES_sequence( ''i/h/c'',H'; + else + string = 'Testing qpOASES_sequence( ''i/m/c'',H'; + end + + if ( isSparseH > 0 ) + string = [string,'s,g']; + else + string = [string,'d,g']; + end + + if ( nC > 0 ) + if ( isSparseA > 0 ) + string = [string,',As']; + else + string = [string,',Ad']; + end + else + if ( hasA > 0 ) + string = [string,',[]']; + end + end + + if ( hasLowerB > 0 ) + string = [string,',lb']; + else + string = [string,',[]']; + end + + if ( hasUpperB > 0 ) + string = [string,',ub']; + else + string = [string,',[]']; + end + + if ( hasLowerC > 0 ) + string = [string,',lbA']; + else + if ( hasA > 0 ) + string = [string,',[] ']; + end + end + + if ( hasUpperC > 0 ) + string = [string,',ubA']; + else + if ( hasA > 0 ) + string = [string,',[] ']; + end + end + + switch ( hasOptions ) + case 1 + string = [string,',opt']; + + case 2 + string = [string,',[] ']; + + case 0 + if ( ( hasX0 > 0 ) || ( hasWS > 0 ) ) + string = [string,',[] ']; + end + end + + switch ( hasX0 ) + case 1 + string = [string,',{x0']; + + case 2 + string = [string,',{[]']; + + case 0 + if ( hasWS > 0 ) + string = [string,',{[]']; + end + end + + switch ( hasWS ) + case 1 + string = [string,',WS}']; + + case 2 + string = [string,',[]}']; + end + + string = [string,' )... ']; + if ( doPrint > 0 ) + disp( string ); + end + + curSuccessFlag = callQpOasesSeq( qpData1,qpData2,hasA,hasOptions,hasX0,hasWS,changeMat ); + if ( curSuccessFlag > 0 ) + string = [string,'pass!']; + successFlag = 1; + else + string = [string,'fail!']; + end + + if ( doPrint > 0 ) + disp( string ); + if ( curSuccessFlag == 0 ) + pause(0.1); + end + end + +end + +function [ successFlag ] = callQpOasesSeq( qpData1,qpData2,hasA,hasOptions,hasX0,hasWS,changeMat, doPrint ) + + if ( nargin < 8 ) + doPrint = 1; + end + + %TOL = 1e-15; + KKTTOL = 1e-6; + + successFlag = 0; + + H1 = qpData1.H; + g1 = qpData1.g; + A1 = [qpData1.Aeq;qpData1.Ain]; + lb1 = qpData1.lb; + ub1 = qpData1.ub; + lbA1 = [qpData1.beq;qpData1.lbA]; + ubA1 = [qpData1.beq;qpData1.ubA]; + + if ( changeMat > 0 ) + H2 = qpData2.H; + else + H2 = H1; + end + g2 = qpData2.g; + if ( changeMat > 0 ) + A2 = [qpData2.Aeq;qpData2.Ain]; + else + A2 = A1; + end + lb2 = qpData2.lb; + ub2 = qpData2.ub; + lbA2 = [qpData2.beq;qpData2.lbA]; + ubA2 = [qpData2.beq;qpData2.ubA]; + + [nV,dummy] = size(H1); %#ok + [nC,dummy] = size(A1); %#ok + + if ( hasWS > 0 ) + if ( hasWS == 1 ) + wsB = 0 * ones( nV,1 ); + wsC = 0 * ones( nC,1 ); + else + wsB = []; + wsC = []; + end + + if ( hasX0 > 0 ) + if ( hasX0 == 1 ) + x0 = -1e-3 * ones( nV,1 ); + else + x0 = []; + end + + auxInput = qpOASES_auxInput( 'x0',x0,'guessedWorkingSetB',wsB,'guessedWorkingSetC',wsC ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); %#ok + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); %#ok + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); %#ok + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); %#ok + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); %#ok + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); %#ok + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); %#ok + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); %#ok + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); %#ok + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); %#ok + qpOASES_sequence( 'c',QP ); + end + end + + else % hasX0 == 0 + + %auxInput = qpOASES_auxInput( 'guessedWorkingSetB',wsB,'guessedWorkingSetC',wsC ); + auxInput = qpOASES_auxInput( 'guessedWorkingSetB',wsB ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); %#ok + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); %#ok + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); %#ok + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); %#ok + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); %#ok + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); %#ok + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,[] ); %#ok + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,[] ); %#ok + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); %#ok + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); %#ok + qpOASES_sequence( 'c',QP ); + end + end + + end % hasX0 + + else % hasWS == 0 + + if ( hasX0 > 0 ) + if ( hasX0 == 1 ) + x0 = -1e-3 * ones( nV,1 ); + else + x0 = []; + end + + auxInput = qpOASES_auxInput( 'x0',x0 ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); %#ok + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); %#ok + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); %#ok + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); %#ok + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); %#ok + qpOASES_sequence( 'c',QP ); + end + + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); %#ok + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); %#ok + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); %#ok + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); %#ok + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); %#ok + qpOASES_sequence( 'c',QP ); + end + end + + else % hasX0 == 0 + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options ); %#ok + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); %#ok + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); %#ok + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options ); %#ok + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); %#ok + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1 ); %#ok + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); %#ok + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); %#ok + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1 ); %#ok + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); %#ok + qpOASES_sequence( 'c',QP ); + end + end + + end % hasX0 + + end % hasWS + + + kktTol1 = getKktResidual( H1,g1,A1,lb1,ub1,lbA1,ubA1, x1,l1 ); + + if ( changeMat > 0 ) + kktTol2 = getKktResidual( H2,g2,A2,lb2,ub2,lbA2,ubA2, x2,l2 ); + else + kktTol2 = getKktResidual( H1,g2,A1,lb2,ub2,lbA2,ubA2, x2,l2 ); + end + + if ( ( kktTol1 <= KKTTOL ) && ( e1 >= 0 ) && ( kktTol2 <= KKTTOL ) && ( e2 >= 0 ) ) + successFlag = 1; + else + if ( doPrint > 0 ) + if ( ( kktTol1 > KKTTOL ) || ( kktTol2 > KKTTOL ) ) + disp( ['kkt error: ',num2str(kktTol1),'/',num2str(kktTol2)] ) + else + disp('exitflag<0') + end + end + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runInterfaceTest.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runInterfaceTest.m new file mode 100644 index 0000000..55a5c7b --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runInterfaceTest.m @@ -0,0 +1,462 @@ +function [ successFlag ] = runInterfaceTest( nV,nC, doPrint,seed ) + + if ( nargin < 4 ) + seed = 42; + if ( nargin < 3 ) + doPrint = 1; + if ( nargin < 2 ) + nC = 10; + if ( nargin < 1 ) + nV = 5; + end + end + end + end + + successFlag = 1; + + for isSparseH=0:1 + for isSparseA=0:1 + successFlag = runSeveralInterfaceTests( successFlag, nV,nC,isSparseH,isSparseA, doPrint,seed ); + end + end + +end + + + +function [ successFLAG ] = runSeveralInterfaceTests( successFLAG, nV,nC, isSparseH,isSparseA, doPrint,seed ) + + %% test without or empty A matrix + for hasA=0:1 + for hasLowerB=0:1 + for hasUpperB=0:1 + for hasOptions=0:2 + for hasX0=0:1 + for hasWS=0:2 + if ( ( hasWS ~= 2 ) || ( hasA ~= 0 ) || ( hasOptions == 1 ) || ( hasX0 ~= 0 ) ) + curSuccessFLAG = runSingleInterfaceTest( nV,0,hasA,isSparseH,isSparseA, hasLowerB,hasUpperB,0,0,hasOptions,hasX0,hasWS, doPrint,seed ); + successFLAG = min( successFLAG,curSuccessFLAG ); + end + end + end + end + end + end + end + + %% test with non-empty A matrix + for hasLowerB=0:1 + for hasUpperB=0:1 + for hasLowerC=0:1 + for hasUpperC=0:1 + for hasOptions=0:2 + for hasX0=0:1 + for hasWS=0:2 + curSuccessFLAG = runSingleInterfaceTest( nV,nC,1,isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC,hasOptions,hasX0,hasWS, doPrint,seed ); + successFLAG = min( successFLAG,curSuccessFLAG ); + end + end + end + end + end + end + end + +end + + +function [ successFLAG ] = runSingleInterfaceTest( nV,nC,hasA,isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC,hasOptions,hasX0,hasWS, doPrint,seed ) + + successFLAG = 0; + + qpData = generateExample( nV,nC, isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC, seed ); + + string = 'Testing qpOASES( H'; + + if ( isSparseH > 0 ) + string = [string,'s,g']; + else + string = [string,'d,g']; + end + + if ( nC > 0 ) + if ( isSparseA > 0 ) + string = [string,',As']; + else + string = [string,',Ad']; + end + else + if ( hasA > 0 ) + string = [string,',[]']; + end + end + + if ( hasLowerB > 0 ) + string = [string,',lb']; + else + string = [string,',[]']; + end + + if ( hasUpperB > 0 ) + string = [string,',ub']; + else + string = [string,',[]']; + end + + if ( hasLowerC > 0 ) + string = [string,',lbA']; + else + if ( hasA > 0 ) + string = [string,',[] ']; + end + end + + if ( hasUpperC > 0 ) + string = [string,',ubA']; + else + if ( hasA > 0 ) + string = [string,',[] ']; + end + end + + switch ( hasOptions ) + case 1 + string = [string,',opt']; + + case 2 + string = [string,',[] ']; + + case 0 + if ( ( hasX0 > 0 ) || ( hasWS > 0 ) ) + string = [string,',[] ']; + end + end + + switch ( hasX0 ) + case 1 + string = [string,',{x0']; + + case 2 + string = [string,',{[]']; + + case 0 + if ( hasWS > 0 ) + string = [string,',{[]']; + end + end + + switch ( hasWS ) + case 1 + string = [string,',WS}']; + + case 2 + string = [string,',[]}']; + end + + string = [string,' )... ']; + if ( doPrint > 0 ) + %disp( string ); + end + + curSuccessFlag = callQpOases( qpData,hasA,hasOptions,hasX0,hasWS, 1 ); + if ( curSuccessFlag > 0 ) + string = [string,'pass!']; + successFLAG = 1; + else + string = [string,'fail!']; + end + + if ( doPrint > 0 ) + disp( string ); + if ( curSuccessFlag == 0 ) + pause; + end + end + +end + +function [ successFLAG ] = callQpOases( qpData,hasA,hasOptions,hasX0,hasWS, doPrint ) + + if ( nargin < 6 ) + doPrint = 1; + end + + TOL = 1e-15; + KKTTOL = 1e-6; + + successFLAG = 0; + + H = qpData.H; + g = qpData.g; + A = [qpData.Aeq;qpData.Ain]; + lb = qpData.lb; + ub = qpData.ub; + lbA = [qpData.beq;qpData.lbA]; + ubA = [qpData.beq;qpData.ubA]; + + [nV,dummy] = size(H); %#ok + [nC,dummy] = size(A); %#ok + + if ( hasWS > 0 ) + if ( hasWS == 1 ) + wsB = 0 * ones( nV,1 ); + wsC = 0 * ones( nC,1 ); + else + wsB = []; + wsC = []; + end + + if ( hasX0 > 0 ) + if ( hasX0 == 1 ) + x0 = -1e-3 * ones( nV,1 ); + else + x0 = []; + end + + auxInput = qpOASES_auxInput( 'x0',x0,'guessedWorkingSetB',wsB,'guessedWorkingSetC',wsC ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ x1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x2,f2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); %#ok + else + [ x1 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x2,f2 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,lb,ub,options,auxInput ); %#ok + end + else + if ( hasA > 0 ) + [ x1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x2,f2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); %#ok + else + [ x1 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x2,f2 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,lb,ub,[],auxInput ); %#ok + end + end + + else % hasX0 == 0 + + %auxInput = qpOASES_auxInput( 'guessedWorkingSetB',wsB,'guessedWorkingSetC',wsC ); + auxInput = qpOASES_auxInput( 'guessedWorkingSetC',wsC ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ x1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x2,f2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); %#ok + else + [ x1 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x2,f2 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,lb,ub,options,auxInput ); %#ok + end + else + if ( hasA > 0 ) + [ x1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x2,f2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); %#ok + else + [ x1 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x2,f2 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,lb,ub,[],auxInput ); %#ok + end + end + + end % hasX0 + + else % hasWS == 0 + + if ( hasX0 > 0 ) + if ( hasX0 == 1 ) + x0 = -1e-3 * ones( nV,1 ); + else + x0 = []; + end + + auxInput = qpOASES_auxInput( 'x0',x0 ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ x1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x2,f2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); %#ok + else + [ x1 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x2,f2 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,lb,ub,options,auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,lb,ub,options,auxInput ); %#ok + end + + else + if ( hasA > 0 ) + [ x1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x2,f2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,[],auxInput ); %#ok + else + [ x1 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x2,f2 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x3,f3,e3 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,lb,ub,[],auxInput ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,lb,ub,[],auxInput ); %#ok + end + end + + else % hasX0 == 0 + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ x1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options ); + [ x2,f2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options ); + [ x3,f3,e3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,A,lb,ub,lbA,ubA,options ); %#ok + else + [ x1 ] = qpOASES( H,g,lb,ub,options ); + [ x2,f2 ] = qpOASES( H,g,lb,ub,options ); + [ x3,f3,e3 ] = qpOASES( H,g,lb,ub,options ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,lb,ub,options ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,lb,ub,options ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,lb,ub,options ); %#ok + end + else + if ( hasA > 0 ) + [ x1 ] = qpOASES( H,g,A,lb,ub,lbA,ubA ); + [ x2,f2 ] = qpOASES( H,g,A,lb,ub,lbA,ubA ); + [ x3,f3,e3 ] = qpOASES( H,g,A,lb,ub,lbA,ubA ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,A,lb,ub,lbA,ubA ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,A,lb,ub,lbA,ubA ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,A,lb,ub,lbA,ubA ); %#ok + else + [ x1 ] = qpOASES( H,g,lb,ub ); + [ x2,f2 ] = qpOASES( H,g,lb,ub ); + [ x3,f3,e3 ] = qpOASES( H,g,lb,ub ); + [ x4,f4,e4,i4 ] = qpOASES( H,g,lb,ub ); + [ x5,f5,e5,i5,l5 ] = qpOASES( H,g,lb,ub ); + [ x6,f6,e6,i6,l6,w6 ] = qpOASES( H,g,lb,ub ); %#ok + end + end + + end % hasX0 + + end % hasWS + + % check whether all calls lead to same optimal solution + % independent from output arguments + if ( ( norm(x1-x2) > TOL ) || ... + ( norm(x1-x3) > TOL ) || ... + ( norm(x1-x4) > TOL ) || ... + ( norm(x1-x5) > TOL ) || ... + ( norm(x1-x6) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in x') + end + return; + end + + if ( ( norm(f2-f3) > TOL ) || ... + ( norm(f2-f4) > TOL ) || ... + ( norm(f2-f5) > TOL ) || ... + ( norm(f2-f6) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in fval') + end + return; + end + + if ( ( norm(e3-e4) > TOL ) || ... + ( norm(e3-e5) > TOL ) || ... + ( norm(e3-e6) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in exitflag') + end + return; + end + + if ( ( norm(i4-i5) > TOL ) || ... + ( norm(i4-i6) > TOL ) ) + if ( doPrint > 0 ) + disp('diff in iter') + end + return; + end + + if ( norm(l5-l6) > TOL ) + if ( doPrint > 0 ) + disp('diff in lambda') + end + return; + end + + + kktTol = getKktResidual( H,g,A,lb,ub,lbA,ubA, x6,l6 ); + + if ( ( kktTol <= KKTTOL ) && ( e6 >= 0 ) ) + successFLAG = 1; + else + if ( doPrint > 0 ) + disp( ['kkt error: ',num2str(kktTol)] ) + end + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runQAP8.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runQAP8.m new file mode 100644 index 0000000..58660d9 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runQAP8.m @@ -0,0 +1,37 @@ +function [ successFlag ] = runQAP8( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + try + load 'QAP8.mat'; + catch + successFlag = -1; + return; + end + + options = qpOASES_options('default', 'maxIter',30000, 'printLevel',-2*doPrint ); + tic + [x, fval, status, nWSRout, y] = qpOASES(sparse(QP.H), QP.f, ... + sparse(QP.C), QP.lb, QP.ub, QP.cl, QP.cu, options); + t = toc; + + if ( doPrint > 0 ) + disp( ['solution time: ',num2str(t),' seconds'] ); + end + + if ( ( status == 0 ) && ( nWSRout < 23200 ) ) + successFlag = 1; + end + + % check error and print + if doPrint + [stat, feas, cmpl] = qpresidual(S.B, S.b1, S.C, S.cl1, S.cu1, x, -y); + fprintf( '%d iters in %.3fs to tolerance %.2e\n', nWSRout, t, max([stat,feas,cmpl]) ); + fprintf( 'Status: %d\n', status ); + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runQSHARE1B.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runQSHARE1B.m new file mode 100644 index 0000000..c1ba1e2 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runQSHARE1B.m @@ -0,0 +1,44 @@ +function [ successFlag ] = runQSHARE1B( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + try + load 'QSHARE1B.mat'; + catch + successFlag = -1; + return; + end + + options = qpOASES_options('default', 'maxIter',600, 'maxCpuTime',2.0, 'printLevel',-2*doPrint ); + auxInput = qpOASES_auxInput( 'hessianType',[] ); + tic + [xD,fvalD,exitflagD,iterD,lambdaD] = qpOASES( H,g,A,lb,ub,lbA,ubA,options,auxInput ); + tD = toc; + kktD = getKktResidual( H,g,A,lb,ub,lbA,ubA, xD,lambdaD ); + + if ( doPrint > 0 ) + disp( ['dense kkt tol: ',num2str(kktD, '%.3e')] ); + disp( ['dense solution time: ',num2str(tD),' seconds'] ); + disp( ['dense #iterations: ',num2str(iterD),] ); + end + + tic + [xS,fvalS,exitflagS,iterS,lambdaS] = qpOASES( sparse(H),g,sparse(A),lb,ub,lbA,ubA,options ); + tS = toc; + kktS = getKktResidual( H,g,A,lb,ub,lbA,ubA, xS,lambdaS ); + + if ( doPrint > 0 ) + disp( ['sparse kkt tol: ',num2str(kktS, '%.3e')] ); + disp( ['sparse solution time: ',num2str(tS),' seconds'] ); + disp( ['sparse #iterations: ',num2str(iterS),] ); + end + + if ( ( exitflagD == 0 ) && ( kktD < 1e-6 ) && ( exitflagS == 0 ) && ( kktS < 1e-6 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runRandomIdHessian.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runRandomIdHessian.m new file mode 100644 index 0000000..81199f7 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runRandomIdHessian.m @@ -0,0 +1,435 @@ +function [ successFlag ] = runRandomIdHessian( nV,nC, doPrint,seed ) + + if ( nargin < 4 ) + seed = 42; + if ( nargin < 3 ) + doPrint = 1; + if ( nargin < 2 ) + nC = 10; + if ( nargin < 1 ) + nV = 5; + end + end + end + end + + successFlag = 1; + + for isSparseH=0:1 + for isSparseA=0:1 + successFlag = runSeveralIdSeqTests( successFlag, nV,nC,isSparseH,isSparseA, doPrint,seed ); + end + end + +end + + +function [ successFlag ] = runSeveralIdSeqTests( successFlag, nV,nC, isSparseH,isSparseA, doPrint,seed ) + + %% test without or empty A matrix + for hasA=0:1 + for changeMat=0:hasA % cannot change matrices if QProblemB object is instantiated + for hasLowerB=0:1 + for hasUpperB=0:1 + for hasOptions=0:1 + for hasX0=0:2 + for hasWS=0:2 + curSuccessFLAG = runSingleIdSeqTest( nV,0,hasA,isSparseH,isSparseA, hasLowerB,hasUpperB,0,0,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ); + successFlag = min( successFlag,curSuccessFLAG ); + end + end + end + end + end + end + end + + %% test with non-empty A matrix + for hasLowerB=0:1 + for hasUpperB=0:1 + for hasLowerC=0:1 + for hasUpperC=0:1 + for hasOptions=0:1 + for hasX0=0:2 + for hasWS=0:2 + for changeMat=0:1 + curSuccessFLAG = runSingleIdSeqTest( nV,nC,1,isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ); + successFlag = min( successFlag,curSuccessFLAG ); + end + end + end + end + end + end + end + end + +end + + +function [ successFlag ] = runSingleIdSeqTest( nV,nC,hasA,isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ) + + successFlag = 0; + + qpFeatures = setupQpFeaturesStruct( ); + + qpFeatures.nV = nV; + qpFeatures.nC = nC; + + qpFeatures.isSparseH = isSparseH; + qpFeatures.isSparseA = isSparseA; + + qpFeatures.hasLowerB = hasLowerB; + qpFeatures.hasUpperB = hasUpperB; + qpFeatures.hasLowerC = hasLowerC; + qpFeatures.hasUpperC = hasUpperC; + + qpFeatures.hessianType = 2; + + qpData1 = generateRandomQp( qpFeatures,seed ); + qpData2 = generateRandomQp( qpFeatures,seed ); + + if ( changeMat == 0 ) + string = 'Testing qpOASES_sequence( ''i/h/c'',ID'; + else + string = 'Testing qpOASES_sequence( ''i/m/c'',ID'; + end + + if ( isSparseH > 0 ) + string = [string,'s,g']; + else + string = [string,'d,g']; + end + + if ( nC > 0 ) + if ( isSparseA > 0 ) + string = [string,',As']; + else + string = [string,',Ad']; + end + else + if ( hasA > 0 ) + string = [string,',[]']; + end + end + + if ( hasLowerB > 0 ) + string = [string,',lb']; + else + string = [string,',[]']; + end + + if ( hasUpperB > 0 ) + string = [string,',ub']; + else + string = [string,',[]']; + end + + if ( hasLowerC > 0 ) + string = [string,',lbA']; + else + if ( hasA > 0 ) + string = [string,',[] ']; + end + end + + if ( hasUpperC > 0 ) + string = [string,',ubA']; + else + if ( hasA > 0 ) + string = [string,',[] ']; + end + end + + switch ( hasOptions ) + case 1 + string = [string,',opt']; + + case 2 + string = [string,',[] ']; + + case 0 + if ( ( hasX0 > 0 ) || ( hasWS > 0 ) ) + string = [string,',[] ']; + end + end + + switch ( hasX0 ) + case 1 + string = [string,',{x0']; + + case 2 + string = [string,',{[]']; + + case 0 + if ( hasWS > 0 ) + string = [string,',{[]']; + end + end + + switch ( hasWS ) + case 1 + string = [string,',WS}']; + + case 2 + string = [string,',[]}']; + end + + string = [string,' )... ']; + if ( doPrint > 0 ) + %disp( string ); + end + + curSuccessFlag = callQpOasesSeq( qpData1,qpData2,hasA,hasOptions,hasX0,hasWS,changeMat,doPrint ); + if ( curSuccessFlag > 0 ) + string = [string,'pass!']; + successFlag = 1; + else + string = [string,'fail!']; + end + + if ( doPrint > 0 ) + disp( string ); + if ( curSuccessFlag == 0 ) + pause; + end + end + +end + + + +function [ successFlag ] = callQpOasesSeq( qpData1,qpData2,hasA,hasOptions,hasX0,hasWS,changeMat, doPrint ) + + if ( nargin < 8 ) + doPrint = 1; + end + + TOL = 1e-15; + KKTTOL = 1e-6; + + successFlag = 0; + + H1 = qpData1.H; + g1 = qpData1.g; + A1 = [qpData1.Aeq;qpData1.Ain]; + lb1 = qpData1.lb; + ub1 = qpData1.ub; + lbA1 = [qpData1.beq;qpData1.lbA]; + ubA1 = [qpData1.beq;qpData1.ubA]; + + H2 = qpData2.H; + g2 = qpData2.g; + A2 = [qpData2.Aeq;qpData2.Ain]; + lb2 = qpData2.lb; + ub2 = qpData2.ub; + lbA2 = [qpData2.beq;qpData2.lbA]; + ubA2 = [qpData2.beq;qpData2.ubA]; + + [nV,dummy] = size(H1); + [nC,dummy] = size(A1); + + if ( hasWS > 0 ) + if ( hasWS == 1 ) + wsB = 0 * ones( nV,1 ); + wsC = 0 * ones( nC,1 ); + else + wsB = []; + wsC = []; + end + + if ( hasX0 > 0 ) + if ( hasX0 == 1 ) + x0 = -1e-3 * ones( nV,1 ); + else + x0 = []; + end + + auxInput = qpOASES_auxInput( 'x0',x0,'guessedWorkingSetB',wsB,'guessedWorkingSetC',wsC ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); + qpOASES_sequence( 'c',QP ); + end + end + + else % hasX0 == 0 + + auxInput = qpOASES_auxInput( 'guessedWorkingSetB',wsB,'guessedWorkingSetC',wsC ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,[] ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,[] ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); + qpOASES_sequence( 'c',QP ); + end + end + + end % hasX0 + + else % hasWS == 0 + + if ( hasX0 > 0 ) + if ( hasX0 == 1 ) + x0 = -1e-3 * ones( nV,1 ); + else + x0 = []; + end + + auxInput = qpOASES_auxInput( 'x0',x0 ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); + qpOASES_sequence( 'c',QP ); + end + + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); + qpOASES_sequence( 'c',QP ); + end + end + + else % hasX0 == 0 + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options(); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1 ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1 ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); + qpOASES_sequence( 'c',QP ); + end + end + + end % hasX0 + + end % hasWS + + + kktTol1 = getKktResidual( H1,g1,A1,lb1,ub1,lbA1,ubA1, x1,l1 ); + + if ( changeMat > 0 ) + kktTol2 = getKktResidual( H2,g2,A2,lb2,ub2,lbA2,ubA2, x2,l2 ); + else + kktTol2 = getKktResidual( H1,g2,A1,lb2,ub2,lbA2,ubA2, x2,l2 ); + end + + if ( ( kktTol1 <= KKTTOL ) && ( e1 >= 0 ) && ( kktTol2 <= KKTTOL ) && ( e2 >= 0 ) ) + successFlag = 1; + else + if ( doPrint > 0 ) + disp( ['kkt error: ',num2str(kktTol1),'/',num2str(kktTol2)] ) + end + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runRandomZeroHessian.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runRandomZeroHessian.m new file mode 100644 index 0000000..5fc4b91 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runRandomZeroHessian.m @@ -0,0 +1,433 @@ +function [ successFlag ] = runRandomZeroHessian( nV,nC, doPrint,seed ) + + if ( nargin < 4 ) + seed = 42; + if ( nargin < 3 ) + doPrint = 1; + if ( nargin < 2 ) + nC = 10; + if ( nargin < 1 ) + nV = 5; + end + end + end + end + + successFlag = 1; + + for isSparseH=0:1 + for isSparseA=0:1 + successFlag = runSeveralIdSeqTests( successFlag, nV,nC,isSparseH,isSparseA, doPrint,seed ); + end + end + +end + + +function [ successFlag ] = runSeveralIdSeqTests( successFlag, nV,nC, isSparseH,isSparseA, doPrint,seed ) + + %% test without or empty A matrix + % { + for hasA=0:1 + for changeMat=0:hasA % cannot change matrices if QProblemB object is instantiated + for hasOptions=1:1 + for hasX0=0:2 + for hasWS=0:2 + curSuccessFLAG = runSingleIdSeqTest( nV,0,hasA,isSparseH,isSparseA, 1,1,0,0,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ); + successFlag = min( successFlag,curSuccessFLAG ); + end + end + end + end + end + %} + + %% test with non-empty A matrix + for hasLowerC=0:1 + for hasUpperC=0:1 + for hasOptions=1:1 + for hasX0=0:2 + for hasWS=0:2 + for changeMat=0:1 + curSuccessFLAG = runSingleIdSeqTest( nV,nC,1,isSparseH,isSparseA, 1,1,hasLowerC,hasUpperC,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ); + successFlag = min( successFlag,curSuccessFLAG ); + end + end + end + end + end + end + +end + + +function [ successFlag ] = runSingleIdSeqTest( nV,nC,hasA,isSparseH,isSparseA, hasLowerB,hasUpperB,hasLowerC,hasUpperC,hasOptions,hasX0,hasWS,changeMat, doPrint,seed ) + + successFlag = 0; + + qpFeatures = setupQpFeaturesStruct( ); + + qpFeatures.nV = nV; + qpFeatures.nC = nC; + + qpFeatures.isSparseH = isSparseH; + qpFeatures.isSparseA = isSparseA; + + qpFeatures.hasLowerB = hasLowerB; + qpFeatures.hasUpperB = hasUpperB; + qpFeatures.hasLowerC = hasLowerC; + qpFeatures.hasUpperC = hasUpperC; + + qpFeatures.hessianType = 3; + + qpData1 = generateRandomQp( qpFeatures,seed ); + qpData2 = generateRandomQp( qpFeatures,seed ); + + if ( changeMat == 0 ) + string = 'Testing qpOASES_sequence( ''i/h/c'',0'; + else + string = 'Testing qpOASES_sequence( ''i/m/c'',0'; + end + + if ( isSparseH > 0 ) + string = [string,'s,g']; + else + string = [string,'d,g']; + end + + if ( nC > 0 ) + if ( isSparseA > 0 ) + string = [string,',As']; + else + string = [string,',Ad']; + end + else + if ( hasA > 0 ) + string = [string,',[]']; + end + end + + if ( hasLowerB > 0 ) + string = [string,',lb']; + else + string = [string,',[]']; + end + + if ( hasUpperB > 0 ) + string = [string,',ub']; + else + string = [string,',[]']; + end + + if ( hasLowerC > 0 ) + string = [string,',lbA']; + else + if ( hasA > 0 ) + string = [string,',[] ']; + end + end + + if ( hasUpperC > 0 ) + string = [string,',ubA']; + else + if ( hasA > 0 ) + string = [string,',[] ']; + end + end + + switch ( hasOptions ) + case 1 + string = [string,',opt']; + + case 2 + string = [string,',[] ']; + + case 0 + if ( ( hasX0 > 0 ) || ( hasWS > 0 ) ) + string = [string,',[] ']; + end + end + + switch ( hasX0 ) + case 1 + string = [string,',{x0']; + + case 2 + string = [string,',{[]']; + + case 0 + if ( hasWS > 0 ) + string = [string,',{[]']; + end + end + + switch ( hasWS ) + case 1 + string = [string,',WS}']; + + case 2 + string = [string,',[]}']; + end + + string = [string,' )... ']; + if ( doPrint > 0 ) + %disp( string ); + end + + %try + curSuccessFlag = callQpOasesSeq( qpData1,qpData2,hasA,hasOptions,hasX0,hasWS,changeMat,doPrint ); + %catch + %curSuccessFlag = 0; + %end + if ( curSuccessFlag > 0 ) + string = [string,'pass!']; + successFlag = 1; + else + string = [string,'fail!']; + end + + if ( doPrint > 0 ) + disp( string ); + if ( curSuccessFlag == 0 ) + %pause; + end + end + +end + + + +function [ successFlag ] = callQpOasesSeq( qpData1,qpData2,hasA,hasOptions,hasX0,hasWS,changeMat, doPrint ) + + if ( nargin < 8 ) + doPrint = 1; + end + + TOL = 1e-15; + KKTTOL = 1e-6; + + successFlag = 0; + + H1 = qpData1.H; + g1 = qpData1.g; + A1 = [qpData1.Aeq;qpData1.Ain]; + lb1 = qpData1.lb; + ub1 = qpData1.ub; + lbA1 = [qpData1.beq;qpData1.lbA]; + ubA1 = [qpData1.beq;qpData1.ubA]; + + H2 = qpData2.H; + g2 = qpData2.g; + A2 = [qpData2.Aeq;qpData2.Ain]; + lb2 = qpData2.lb; + ub2 = qpData2.ub; + lbA2 = [qpData2.beq;qpData2.lbA]; + ubA2 = [qpData2.beq;qpData2.ubA]; + + [nV,dummy] = size(H1); + [nC,dummy] = size(A1); + + if ( hasWS > 0 ) + if ( hasWS == 1 ) + wsB = 0 * ones( nV,1 ); + wsC = 0 * ones( nC,1 ); + else + wsB = []; + wsC = []; + end + + if ( hasX0 > 0 ) + if ( hasX0 == 1 ) + x0 = -1e-3 * ones( nV,1 ); + else + x0 = []; + end + + auxInput = qpOASES_auxInput( 'x0',x0,'guessedWorkingSetB',wsB,'guessedWorkingSetC',wsC ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options( 'fast' ); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); + qpOASES_sequence( 'c',QP ); + end + end + + else % hasX0 == 0 + + auxInput = qpOASES_auxInput( 'guessedWorkingSetB',wsB,'guessedWorkingSetC',wsC ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options( 'fast' ); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,[] ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,[] ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); + qpOASES_sequence( 'c',QP ); + end + end + + end % hasX0 + + else % hasWS == 0 + + if ( hasX0 > 0 ) + if ( hasX0 == 1 ) + x0 = -1e-3 * ones( nV,1 ); + else + x0 = []; + end + + auxInput = qpOASES_auxInput( 'x0',x0 ); + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options( 'fast' ); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options,auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options,auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); + qpOASES_sequence( 'c',QP ); + end + + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,[],auxInput ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,[],auxInput ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); + qpOASES_sequence( 'c',QP ); + end + end + + else % hasX0 == 0 + + if ( hasOptions > 0 ) + if ( hasOptions == 1 ) + options = qpOASES_options( 'fast' ); + else + options = []; + end + + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1,options ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2,options ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2,options ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1,options ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,options ); + qpOASES_sequence( 'c',QP ); + end + else + if ( hasA > 0 ) + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,A1,lb1,ub1,lbA1,ubA1 ); + if ( changeMat > 0 ) + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'm',QP,H2,g2,A2,lb2,ub2,lbA2,ubA2 ); + else + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2,lbA2,ubA2 ); + end + qpOASES_sequence( 'c',QP ); + else + [ QP,x1,f1,e1,i1,l1,w1 ] = qpOASES_sequence( 'i',H1,g1,lb1,ub1 ); + [ x2,f2,e2,i2,l2,w2 ] = qpOASES_sequence( 'h',QP,g2,lb2,ub2 ); + qpOASES_sequence( 'c',QP ); + end + end + + end % hasX0 + + end % hasWS + + + kktTol1 = getKktResidual( H1,g1,A1,lb1,ub1,lbA1,ubA1, x1,l1 ); + + if ( changeMat > 0 ) + kktTol2 = getKktResidual( H2,g2,A2,lb2,ub2,lbA2,ubA2, x2,l2 ); + else + kktTol2 = getKktResidual( H1,g2,A1,lb2,ub2,lbA2,ubA2, x2,l2 ); + end + + if ( ( kktTol1 <= KKTTOL ) && ( e1 >= 0 ) && ( kktTol2 <= KKTTOL ) && ( e2 >= 0 ) ) + successFlag = 1; + else + if ( doPrint > 0 ) + disp( ['kkt error: ',num2str(kktTol1),'/',num2str(kktTol2)] ) + end + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runSimpleSpringExample.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runSimpleSpringExample.m new file mode 100644 index 0000000..2f494a6 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runSimpleSpringExample.m @@ -0,0 +1,34 @@ +function [ successFlag ] = runSimpleSpringExample( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + % parameter + k1 = 100; + k2 = 100; + + m = 1; + g = 9.81; + + % QP data + H = [ k1,0; 0,k2 ]; + g = [ m*g; 0 ]; + + lb = [ 0; 0 ]; + ub = [ 1; 1 ]; + + A = [ 1,1 ]; + lbA = 1; + ubA = 1; + + options = qpOASES_options( 'default', 'printLevel',2*doPrint ); + [x,fval,exitflag,iter] = qpOASES( H,g,A,lb,ub,lbA,ubA,options ); + + if ( ( exitflag == 0 ) && ( iter < 5 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestAPrioriKnownSeq1.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestAPrioriKnownSeq1.m new file mode 100644 index 0000000..7f963cd --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestAPrioriKnownSeq1.m @@ -0,0 +1,87 @@ +function [ successFlag ] = runTestAPrioriKnownSeq1( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 1; + TOL = eps; + + clear H g A lb ub lbA ubA; + + try + load 'benchmarkCRANE1.mat'; + catch + successFlag = -1; + return; + end + + [nC,nV] = size(A); + [nV,nP] = size(g); + + xOptSeq = zeros(nV,nP); + objOptSeq = zeros(1,nP); + statusSeq = zeros(1,nP); + iterSeq = zeros(1,nP); + yOptSeq = zeros(nV+nC,nP); + + options = qpOASES_options( 'fast','maxIter',100, 'printLevel',2*doPrint ); + + for i=1:nP + %disp(i); + + if ( i == 1 ) + [QP,x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'i',H,g(:,i),A,lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + else + [x,obj,status,nWSRout,lambda] = qpOASES_sequence( 'h',QP,g(:,i),lb(:,i),ub(:,i),lbA(:,i),ubA(:,i),options ); + end + + xOptSeq(:,i) = x; + objOptSeq(:,i) = obj; + statusSeq(:,i) = status; + iterSeq(:,i) = nWSRout; + yOptSeq(:,i) = lambda; + + end + + qpOASES_sequence( 'c',QP ); + + + [xOptAPKSeq,objOptAPKSeq,statusAPKSeq,iterAPKSeq,yOptAPKSeq] = qpOASES( H,g,A,lb,ub,lbA,ubA,options ); + + if ( norm( xOptSeq-xOptAPKSeq ) > TOL ) + successFlag = 0; + if ( doPrint > 0 ) + disp( 'xOpt error' ) + end + end + + if ( norm( objOptSeq-objOptAPKSeq ) > TOL ) + successFlag = 0; + if ( doPrint > 0 ) + disp( 'objOpt error' ) + end + end + + if ( sum( statusSeq~=statusAPKSeq ) > 0 ) + successFlag = 0; + if ( doPrint > 0 ) + disp( 'status error' ) + end + end + + if ( sum( iterSeq~=iterAPKSeq ) > 0 ) + successFlag = 0; + if ( doPrint > 0 ) + disp( 'iter error' ) + end + end + + if ( norm( yOptSeq-yOptAPKSeq ) > TOL ) + successFlag = 0; + if ( doPrint > 0 ) + disp( 'yOpt error' ) + end + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSeq.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSeq.m new file mode 100644 index 0000000..00c4fe8 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSeq.m @@ -0,0 +1,104 @@ +function [ successFlag ] = runTestSeq( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 1; + + + % test case constants + m = 50; + n = 100; + nMajSeq = 8; + nMinSeq = 4; + nSeq = nMajSeq * nMinSeq; + p = 2; % interpolation monomial power + fldim = 5; % feedback law dimension + + % generate start and end problem + Ls = sprand(n, n, 0.03); + Hs = Ls' * Ls + 1e-8 * eye(n); + As = sprand(m, n, 0.05); + + % negative (!) definite Hessian + Le = sprand(n, n, 0.03); + He = -Le' * Le; + Ae = sprand(m, n, 0.05); + + lbAs = -rand(m,1); + ubAs = rand(m,1); + ubs = ones(n,1); + lbs = -ones(n,1); + gs = 10*rand(n,1); + + lbAe = -rand(m,1); + ubAe = rand(m,1); + ube = ones(n,1); + lbe = -ones(n,1); + ge = 10*rand(n,1); + + % monomial interpolation + tmaj = 1 - (1:1/(1-nMajSeq):0).^p; + for i = 1:nMajSeq + tau = tmaj(i); + H{i} = (1-tau) * Hs + tau * He; + A{i} = (1-tau) * As + tau * Ae; + end + t = 1 - (1:1/(1-nSeq):0).^p; + for i = 1:nSeq + tau = t(i); + lbA{i} = (1-tau) * lbAs + tau * lbAe; + ubA{i} = (1-tau) * ubAs + tau * ubAe; + lb{i} = (1-tau) * lbs + tau * lbe; + ub{i} = (1-tau) * ubs + tau * ube; + g{i} = (1-tau) * gs + tau * ge; + end + + x = zeros(n,1); + + if ~exist('cumIters', 'var') + cumIters = zeros(nSeq, 1); + end + + % solve sequence of QPs + if ( doPrint > 0 ) + fprintf('%3s %5s\n', 'seq', 'iters') + end + + for i = 1:nSeq + if i == 1 + [QP, x, fval, exitflag, iter, lambda] = qpOASES_sequence('i', ... + H{i}, g{i}, A{i}, lb{i}, ub{i}, lbA{i}, ubA{i}, x); + else + if mod(i-1, nMinSeq) == 0 + j = (i-1) / nMinSeq + 1; + [x, fval, exitflag, iter, lambda] = qpOASES_sequence('m', QP, ... + H{j}, g{i}, A{j}, lb{i}, ub{i}, lbA{i}, ubA{i}); + else + [x, fval, exitflag, iter, lambda] = qpOASES_sequence('h', QP, ... + g{i}, lb{i}, ub{i}, lbA{i}, ubA{i}); + end + end + + if ( doPrint > 0 ) + fprintf('%3d %5d\n', i, iter) + end + + cumIters(i) = cumIters(i) + iter; + + if ( exitflag ~= 0 ) + successFlag = 0; + end + end + + % solve EQP + V0 = zeros(n, fldim); + Lambda = eye(m, fldim); + [X, Y] = qpOASES_sequence('e', QP, V0, V0, V0, Lambda, Lambda); + FL = X(1:fldim,:); + + % clear + qpOASES_sequence('c', QP) + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse.m new file mode 100644 index 0000000..272c689 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse.m @@ -0,0 +1,33 @@ +function [ successFlag ] = runTestSparse( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + + m = 50; + n = 100; + + L = sprand(n, n, 0.03); + H = L' * L; + A = sprand(m, n, 0.05); + + lbA = -rand(m,1); + ubA = rand(m,1); + ub = ones(n,1); + lb = -ones(n,1); + g = 10*rand(n,1); + + options = qpOASES_options( 'default', 'printLevel',2*doPrint ); + + [x1,dummy1,exitflag1,iter1] = qpOASES(full(H), g, full(A), lb, ub, lbA, ubA, options); + [x2,dummy1,exitflag2,iter2] = qpOASES(H, g, A, lb, ub, lbA, ubA, options); + + if ( ( exitflag1 == 0 ) && ( exitflag2 == 0 ) && ( iter1 == iter2 ) ... + && ( norm(x1-x2) < 1e-10 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse2.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse2.m new file mode 100644 index 0000000..fc1f816 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse2.m @@ -0,0 +1,33 @@ +function [ successFlag ] = runTestSparse2( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + + m = 50; + n = 100; + + L = sprand(n, n, 0.03); + H = L' * L; + A = sprand(m, n, 0.05); + + lbA = -rand(m,1); + ubA = rand(m,1); + ub = ones(n,1); + lb = -ones(n,1); + g = 10*rand(n,1); + + options = qpOASES_options( 'default', 'printLevel',2*doPrint ); + + [QP,dummy1,dummy2,exitflag1] = qpOASES_sequence( 'i', H, g, A, lb, ub, lbA, ubA, options ); + [dummy1,dummy2,exitflag2] = qpOASES_sequence( 'h',QP, g*2, lb, ub, lbA, ubA ); + qpOASES_sequence( 'c',QP ); + + if ( ( exitflag1 == 0 ) && ( exitflag2 == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse3.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse3.m new file mode 100644 index 0000000..c4f870c --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse3.m @@ -0,0 +1,39 @@ +function [ successFlag ] = runTestSparse3( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + + m = 50; + n = 100; + + L = sprand(n, n, 0.03); + H = L' * L; + A = sprand(m, n, 0.05); + + lbA = -rand(m,1); + ubA = rand(m,1); + ub = ones(n,1); + lb = -ones(n,1); + g = 10*rand(n,1); + + options = qpOASES_options( 'default', 'printLevel',2*doPrint ); + + + [QP,dummy1,dummy2,exitflag1] = qpOASES_sequence( 'i', H, g, A, lb, ub, lbA, ubA, options ); + + L = sprand(n, n, 0.03); + H = L' * L; + A = sprand(m, n, 0.05); + + [dummy1,dummy2,exitflag2] = qpOASES_sequence( 'm',QP, H, g*2, A, lb, ub, lbA, ubA ); + qpOASES_sequence( 'c',QP ); + + if ( ( exitflag1 == 0 ) && ( exitflag2 == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse4.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse4.m new file mode 100644 index 0000000..7c468e4 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestSparse4.m @@ -0,0 +1,29 @@ +function [ successFlag ] = runTestSparse4( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + + n = 100; + + L = sprand(n, n, 0.03); + H = L' * L; + + ub = ones(n,1); + lb = -ones(n,1); + g = 10*rand(n,1); + + options = qpOASES_options( 'default', 'printLevel',2*doPrint ); + + [QP,dummy1,dummy2,exitflag1] = qpOASES_sequence( 'i', H, g, lb, ub, options ); + [dummy1,dummy2,exitflag2] = qpOASES_sequence( 'h',QP, g*2, lb, ub ); + qpOASES_sequence( 'c',QP ); + + if ( ( exitflag1 == 0 ) && ( exitflag2 == 0 ) ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestWorkingSetLI.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestWorkingSetLI.m new file mode 100644 index 0000000..3cdfeb4 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runTestWorkingSetLI.m @@ -0,0 +1,50 @@ +function [ successFlag ] = runTestWorkingSetLI( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 1; + + qpFeatures = setupQpFeaturesStruct( ); + + qpFeatures.nV = 20; + qpFeatures.nC = 100; + + qpFeatures.isSparseH = 0; + qpFeatures.isSparseA = 0; + + qpFeatures.hasLowerB = 1; + qpFeatures.hasUpperB = 1; + qpFeatures.hasLowerC = 1; + qpFeatures.hasUpperC = 1; + + qpFeatures.makeInfeas = 1; + + options = qpOASES_options( 'default', 'printLevel',2*doPrint, 'initialStatusBounds',0 ); + + exitflag = 0; + counter = 0; + + while ( ( exitflag ~= -42 ) && ( counter < 100 ) ) + + counter = counter+1; + + qpData = generateRandomQp( qpFeatures ); + B = [ eye( qpFeatures.nV ); qpData.Ain ]; + + [x,dummy1,exitflag,dummy2,dummy3,auxOutput] = qpOASES( qpData.H,qpData.g,qpData.Ain, ... + qpData.lb,qpData.ub,qpData.lbA,qpData.ubA, options ); %#ok<*NASGU> + + WS = [auxOutput.workingSetB; auxOutput.workingSetC]; + nAct = sum( WS~=0 ); + Bact = B( WS~=0,: ); + + if ( nAct ~= rank(Bact) ) + successFlag = 0; + return; + end + + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/matlab/tests/runVanBarelsUnboundedQP.m b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runVanBarelsUnboundedQP.m new file mode 100644 index 0000000..9198342 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/matlab/tests/runVanBarelsUnboundedQP.m @@ -0,0 +1,25 @@ +function [ successFlag ] = runVanBarelsUnboundedQP( doPrint ) + + if ( nargin < 1 ) + doPrint = 0; + end + + successFlag = 0; + + try + data = load( 'vanBarelsUnboundedQP.mat' ); + catch + successFlag = -1; + return; + end + + options1 = qpOASES_options( 'default', 'printLevel',-1*doPrint ); + + [dummy1,dummy2,exitflag1,iter1] = qpOASES( data.H,data.g,data.lb,data.ub,options1 ); %#ok<*NASGU> + + % should return "QP unbounded" + if ( exitflag1 == -3 ) + successFlag = 1; + end + +end diff --git a/locomotion/src/third_party/qpOASES/testing/runUnitTests b/locomotion/src/third_party/qpOASES/testing/runUnitTests new file mode 100755 index 0000000..09c9f10 --- /dev/null +++ b/locomotion/src/third_party/qpOASES/testing/runUnitTests @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +## +## This file is part of qpOASES. +## +## qpOASES -- An Implementation of the Online Active Set Strategy. +## Copyright (C) 2007-2017 by Hans Joachim Ferreau, Andreas Potschka, +## Christian Kirches et al. All rights reserved. +## +## qpOASES is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## qpOASES is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with qpOASES; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## + + + +## +## Filename: testing/runUnitTests +## Author: Hans Joachim Ferreau +## Version: 3.2 +## Date: 2014-2017 + +# defining colors for output +red='\e[0;31m' +green='\e[0;32m' +NC='\e[0m' # No Color + +# runs a number of examples to detect malfunctioning of the code + +function runTest { + echo -n "Running unit test $2 $3... " + + $2 $3 > dummy.txt; + retVal=$?; + rm -rf dummy.txt; + + if [ $retVal == 0 ]; then + echo -e "${green}passed!${NC}" + else + if [ $retVal == 99 ]; then + echo "problem data missing!" + else + echo -e "${red}failed!${NC}" + counter=$[counter+1]; + fi + fi +} + + +cd ..; +make testing; +cd testing; + +counter=0; + +# run unit tests +runTest $counter ../bin/test_matrices; +runTest $counter ../bin/test_matrices2; +runTest $counter ../bin/test_matrices3; +runTest $counter ../bin/test_indexlist; + +runTest $counter ../bin/test_example1; +runTest $counter ../bin/test_example1a; +runTest $counter ../bin/test_example1b; +runTest $counter ../bin/test_example2; +runTest $counter ../bin/test_example4; +runTest $counter ../bin/test_example5; +runTest $counter ../bin/test_exampleLP; +runTest $counter ../bin/test_qrecipe; +runTest $counter ../bin/test_qrecipeSchur; +runTest $counter ../bin/test_smallSchur; +runTest $counter ../bin/test_infeasible1; +runTest $counter ../bin/test_hs268; + +runTest $counter ../bin/test_example6; +runTest $counter ../bin/test_example7; +runTest $counter ../bin/test_sebastien1; +runTest $counter ../bin/test_vanBarelsUnboundedQP; +runTest $counter ../bin/test_janick1; +runTest $counter ../bin/test_janick2; +runTest $counter ../bin/test_constraintProduct1; +runTest $counter ../bin/test_constraintProduct2; +runTest $counter ../bin/test_guessedWS1; +runTest $counter ../bin/test_externalChol1; +runTest $counter ../bin/test_gradientShift; +runTest $counter ../bin/test_runAllOqpExamples; + +runTest $counter ../bin/test_bench Odd; +runTest $counter ../bin/test_bench Ods; +#runTest $counter ../bin/test_bench Ord; +#runTest $counter ../bin/test_bench Ors; +runTest $counter ../bin/test_bench Omd; +#runTest $counter ../bin/test_bench Oms; + + +if [ $counter == 0 ]; then + echo -e "${green}All available tests passed successfully!${NC}" +else + echo -e "${red}$counter test(s) failed!${NC}" + exit 1 +fi

pU)H=q^Gc;c-LZ9mLVm2`bcHRWXtm)vcjW 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�E2iShqK3>8#)(Q<{3f<)UNLP(M+ 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 sA=1 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