Last active
October 26, 2016 10:11
-
-
Save mdavezac/21b39888fe877aa39dd805984f961a89 to your computer and use it in GitHub Desktop.
Short talk describing the sopt (https://github.com/basp-group/sopt) compressed sensing library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "slide" | |
} | |
}, | |
"source": [ | |
"# Sopt, a compressed sensing library\n", | |
"\n", | |
"- General algorithms for general convex minimization problems\n", | |
"- C++11\n", | |
"- Open source\n", | |
"- version controlled\n", | |
"- Unit-tested\n", | |
"- Continuously tested\n", | |
"- Now has a [shop-talk](https://gist.github.com/mdavezac/21b39888fe877aa39dd805984f961a89)! downloadable at http://bit.ly/2e9T8Md" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "slide" | |
} | |
}, | |
"source": [ | |
"# The technical bits" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"## Where to get it\n", | |
"\n", | |
"Available on github (https://github.com/basp-group/sopt)\n", | |
"under the GPL2:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"Cloning into 'sopt'...\n" | |
] | |
} | |
], | |
"source": [ | |
"%%bash\n", | |
"[ ! -e sopt ] && git clone https://github.com/basp-group/sopt" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"sopt:\r\n", | |
"CMakeLists.txt README.md \u001b[34mcpp\u001b[m\u001b[m/ \u001b[34mmatlab\u001b[m\u001b[m/\r\n", | |
"LICENSE.txt \u001b[34mcmake_files\u001b[m\u001b[m/ \u001b[34mimages\u001b[m\u001b[m/ \u001b[34mpython\u001b[m\u001b[m/\r\n", | |
"\r\n", | |
"sopt/cpp:\r\n", | |
"CMakeLists.txt \u001b[34mexamples\u001b[m\u001b[m/ \u001b[34msopt\u001b[m\u001b[m/ \u001b[34mtools_for_tests\u001b[m\u001b[m/\r\n", | |
"\u001b[34mbenchmarks\u001b[m\u001b[m/ \u001b[34mregressions\u001b[m\u001b[m/ \u001b[34mtests\u001b[m\u001b[m/\r\n" | |
] | |
} | |
], | |
"source": [ | |
"ls sopt sopt/cpp" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"## installation and testing" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"-- The CXX compiler identification is AppleClang 8.0.0.8000038\n", | |
"-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++\n", | |
"-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -- works\n", | |
"-- Detecting CXX compiler ABI info\n", | |
"-- Detecting CXX compiler ABI info - done\n", | |
"-- Detecting CXX compile features\n", | |
"-- Detecting CXX compile features - done\n", | |
"-- [GreatCMakeCookOff] not found. Will attempt to clone it.\n", | |
"-- Found Git: /usr/local/bin/git (found version \"2.10.1\") \n", | |
"-- [GreatCMakeCookOff] downloaded to /Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/build/external/src/GreatCMakeCookOff\n", | |
"-- Performing Test has_std_cpp11\n", | |
"-- Performing Test has_std_cpp11 - Success\n", | |
"-- Performing Test has_std_cpp0x\n", | |
"-- Performing Test has_std_cpp0x - Success\n", | |
"-- Checking C++11 support for \"unique_ptr\"\n", | |
"-- Checking C++11 support for \"unique_ptr\" -- works\n", | |
"-- Checking C++11 support for \"nullptr\" (N2431)\n", | |
"-- Checking C++11 support for \"nullptr\" (N2431) -- works\n", | |
"-- Checking C++11 support for \"override\"\n", | |
"-- Checking C++11 support for \"override\" -- works\n", | |
"-- Checking C++11 support for \"constructor_delegate\"\n", | |
"-- Checking C++11 support for \"constructor_delegate\" -- works\n", | |
"-- Found Eigen3\n", | |
"-- Found spdlog\n", | |
"-- Found TIFF: /usr/local/lib/libtiff.dylib (found version \"4.0.6\") \n", | |
"-- Try OpenMP CXX flag = [-fopenmp=libomp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [ ]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [-fopenmp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [/openmp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [-Qopenmp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [-openmp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [-xopenmp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [+Oopenmp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [-qsmp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Try OpenMP CXX flag = [-mp]\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED\n", | |
"-- Performing Test OpenMP_FLAG_DETECTED - Failed\n", | |
"-- Could NOT find OpenMP (missing: OpenMP_CXX_FLAGS) \n", | |
"-- Could not find OpenMP. Compiling without.\n", | |
"-- Found Catch: /Users/mdavezac/spack/opt/spack/darwin-sierra-x86_64/clang-8.0.0-apple/Catch-1.3.0-ktlhhdjh6f4nwlu5kopq2olx344r22ht/include \n", | |
"-- Configuring done\n", | |
"-- Generating done\n", | |
"-- Build files have been written to: /Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/build\n", | |
"Scanning dependencies of target lookup_dependencies\n", | |
"[ 0%] Built target lookup_dependencies\n", | |
"Scanning dependencies of target common_catch_main_object\n", | |
"[ 3%] Building CXX object cpp/tests/CMakeFiles/common_catch_main_object.dir/common_catch_main.cc.o\n", | |
"Scanning dependencies of target sopt\n", | |
"[ 12%] Building CXX object cpp/sopt/CMakeFiles/sopt.dir/wavelets/wavelets.cc.o\n", | |
"[ 12%] Building CXX object cpp/sopt/CMakeFiles/sopt.dir/utilities.cc.o\n", | |
"[ 12%] Building CXX object cpp/sopt/CMakeFiles/sopt.dir/wavelets/wavelet_data.cc.o\n", | |
"[ 16%] Linking CXX shared library libsopt.dylib\n", | |
"[ 16%] Built target sopt\n", | |
"[ 16%] Built target common_catch_main_object\n", | |
"Scanning dependencies of target test_conjugate_gradient\n", | |
"Scanning dependencies of target test_linear_transform\n", | |
"Scanning dependencies of target test_proximal\n", | |
"Scanning dependencies of target test_sara\n", | |
"[ 29%] Building CXX object cpp/tests/CMakeFiles/test_proximal.dir/proximal.cc.o\n", | |
"[ 29%] Building CXX object cpp/tests/CMakeFiles/test_conjugate_gradient.dir/conjugate_gradient.cc.o\n", | |
"[ 29%] Building CXX object cpp/tests/CMakeFiles/test_sara.dir/sara.cc.o\n", | |
"[ 29%] Building CXX object cpp/tests/CMakeFiles/test_linear_transform.dir/linear_transform.cc.o\n", | |
"Scanning dependencies of target test_sdmm_warm_start\n", | |
"Scanning dependencies of target test_padmm_warm_start\n", | |
"Scanning dependencies of target test_padmm\n", | |
"Scanning dependencies of target test_reweighted\n", | |
"[ 35%] Building CXX object cpp/tests/CMakeFiles/test_padmm.dir/padmm.cc.o\n", | |
"[ 35%] Building CXX object cpp/tests/CMakeFiles/test_sdmm_warm_start.dir/sdmm_warm_start.cc.o\n", | |
"[ 38%] Building CXX object cpp/tests/CMakeFiles/test_padmm_warm_start.dir/padmm_warm_start.cc.o\n", | |
"[ 41%] Building CXX object cpp/tests/CMakeFiles/test_reweighted.dir/reweighted.cc.o\n", | |
"[ 45%] Linking CXX executable test_reweighted\n", | |
"[ 45%] Built target test_reweighted\n", | |
"Scanning dependencies of target test_maths\n", | |
"[ 48%] Building CXX object cpp/tests/CMakeFiles/test_maths.dir/maths.cc.o\n", | |
"[ 51%] Linking CXX executable test_linear_transform\n", | |
"[ 51%] Built target test_linear_transform\n", | |
"Scanning dependencies of target test_wavelets\n", | |
"[ 54%] Building CXX object cpp/tests/CMakeFiles/test_wavelets.dir/wavelets.cc.o\n", | |
"[ 58%] Linking CXX executable test_padmm_warm_start\n", | |
"[ 58%] Built target test_padmm_warm_start\n", | |
"Scanning dependencies of target test_power_method\n", | |
"[ 61%] Building CXX object cpp/tests/CMakeFiles/test_power_method.dir/power_method.cc.o\n", | |
"[ 64%] Linking CXX executable test_conjugate_gradient\n", | |
"[ 64%] Built target test_conjugate_gradient\n", | |
"[ 67%] Linking CXX executable test_sdmm_warm_start\n", | |
"Scanning dependencies of target test_sdmm\n", | |
"[ 70%] Building CXX object cpp/tests/CMakeFiles/test_sdmm.dir/sdmm.cc.o\n", | |
"[ 70%] Built target test_sdmm_warm_start\n", | |
"Scanning dependencies of target test_wrapper\n", | |
"[ 74%] Building CXX object cpp/tests/CMakeFiles/test_wrapper.dir/wrapper.cc.o\n", | |
"[ 77%] Linking CXX executable test_padmm\n", | |
"[ 77%] Built target test_padmm\n", | |
"[ 80%] Linking CXX executable test_wrapper\n", | |
"[ 83%] Linking CXX executable test_proximal\n", | |
"[ 83%] Built target test_wrapper\n", | |
"[ 83%] Built target test_proximal\n", | |
"[ 87%] Linking CXX executable test_maths\n", | |
"[ 87%] Built target test_maths\n", | |
"[ 90%] Linking CXX executable test_sara\n", | |
"[ 90%] Built target test_sara\n", | |
"[ 93%] Linking CXX executable test_wavelets\n", | |
"[ 96%] Linking CXX executable test_power_method\n", | |
"[ 96%] Built target test_wavelets\n", | |
"[ 96%] Built target test_power_method\n", | |
"[100%] Linking CXX executable test_sdmm\n", | |
"[100%] Built target test_sdmm\n" | |
] | |
} | |
], | |
"source": [ | |
"%%bash\n", | |
"mkdir -p sopt/build && cd sopt/build\n", | |
"cmake -DCMAKE_BUILD_TYPE=Release -Dexamples=OFF ..\n", | |
"make -j 8" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Running tests...\n", | |
"Test project /Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/build\n", | |
" Start 1: test_wavelets\n", | |
" 1/14 Test #1: test_wavelets .................... Passed 0.28 sec\n", | |
" Start 2: test_sara\n", | |
" 2/14 Test #2: test_sara ........................ Passed 0.05 sec\n", | |
" Start 3: test_maths\n", | |
" 3/14 Test #3: test_maths ....................... Passed 0.01 sec\n", | |
" Start 4: test_wrapper\n", | |
" 4/14 Test #4: test_wrapper ..................... Passed 0.00 sec\n", | |
" Start 5: test_conjugate_gradient\n", | |
" 5/14 Test #5: test_conjugate_gradient .......... Passed 0.00 sec\n", | |
" Start 6: test_linear_transform\n", | |
" 6/14 Test #6: test_linear_transform ............ Passed 0.00 sec\n", | |
" Start 7: test_sdmm\n", | |
" 7/14 Test #7: test_sdmm ........................ Passed 0.08 sec\n", | |
" Start 8: test_sdmm_warm_start\n", | |
" 8/14 Test #8: test_sdmm_warm_start ............. Passed 0.01 sec\n", | |
" Start 9: test_proximal\n", | |
" 9/14 Test #9: test_proximal .................... Passed 0.01 sec\n", | |
" Start 10: seeded_proximal\n", | |
"10/14 Test #10: seeded_proximal .................. Passed 0.01 sec\n", | |
" Start 11: test_padmm\n", | |
"11/14 Test #11: test_padmm ....................... Passed 0.01 sec\n", | |
" Start 12: test_padmm_warm_start\n", | |
"12/14 Test #12: test_padmm_warm_start ............ Passed 0.01 sec\n", | |
" Start 13: test_reweighted\n", | |
"13/14 Test #13: test_reweighted .................. Passed 0.01 sec\n", | |
" Start 14: test_power_method\n", | |
"14/14 Test #14: test_power_method ................ Passed 0.00 sec\n", | |
"\n", | |
"100% tests passed, 0 tests failed out of 14\n", | |
"\n", | |
"Label Time Summary:\n", | |
"catch = 0.47 sec (14 tests)\n", | |
"\n", | |
"Total Test time (real) = 0.48 sec\n" | |
] | |
} | |
], | |
"source": [ | |
"%%bash\n", | |
"cd sopt/build && make test" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"## How we know it works\n", | |
"\n", | |
"- Each functional bit of code is unit-tested" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"CMakeLists.txt padmm.cc sara.cc\r\n", | |
"common_catch_main.cc padmm_warm_start.cc sdmm.cc\r\n", | |
"conjugate_gradient.cc power_method.cc sdmm_warm_start.cc\r\n", | |
"linear_transform.cc proximal.cc wavelets.cc\r\n", | |
"maths.cc reweighted.cc wrapper.cc\r\n" | |
] | |
} | |
], | |
"source": [ | |
"ls sopt/cpp/tests" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"```cpp\n", | |
"TEST_CASE(\"Projector on positive quadrant\", \"[utility][project]\") {\n", | |
" using namespace sopt;\n", | |
"\n", | |
" SECTION(\"Real matrix\") {\n", | |
" Image<> input = Image<>::Ones(5, 5) + Image<>::Random(5, 5) * 0.55;\n", | |
" input(1, 1) *= -1;\n", | |
" input(3, 2) *= -1;\n", | |
"\n", | |
" auto const expr = positive_quadrant(input);\n", | |
" CHECK(expr(1, 1) == Approx(0));\n", | |
" CHECK(expr(3, 2) == Approx(0));\n", | |
" }\n", | |
"}\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"\n", | |
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", | |
"test_maths is a Catch v1.3.0 host application.\n", | |
"Run with -? for options\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Projector on positive quadrant\n", | |
" Real matrix\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:11\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:22: \n", | |
"PASSED:\n", | |
" CHECK( expr(1, 1) == Approx(0) )\n", | |
"with expansion:\n", | |
" 0.0 == Approx( 0.0 )\n", | |
"with messages:\n", | |
" input := 0.450009 0.690855 0.871852 1.03267 0.909235\n", | |
" 0.594692 -0.501749 1.02136 1.18826 1.20545\n", | |
" 1.28117 1.19675 1.36406 0.458468 1.09787\n", | |
" 0.954515 1.19723 -0.488029 0.871757 1.47348\n", | |
" 1.03604 1.47816 0.508808 0.523526 1.38078\n", | |
" expr := 0.450009 0.690855 0.871852 1.03267 0.909235\n", | |
" 0.594692 0 1.02136 1.18826 1.20545\n", | |
" 1.28117 1.19675 1.36406 0.458468 1.09787\n", | |
" 0.954515 1.19723 0 0.871757 1.47348\n", | |
" 1.03604 1.47816 0.508808 0.523526 1.38078\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:23: \n", | |
"PASSED:\n", | |
" CHECK( expr(3, 2) == Approx(0) )\n", | |
"with expansion:\n", | |
" 0.0 == Approx( 0.0 )\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:26: \n", | |
"PASSED:\n", | |
" CHECK( value(1, 1) == Approx(0) )\n", | |
"with expansion:\n", | |
" 0.0 == Approx( 0.0 )\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:27: \n", | |
"PASSED:\n", | |
" CHECK( value(3, 2) == Approx(0) )\n", | |
"with expansion:\n", | |
" 0.0 == Approx( 0.0 )\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:30: \n", | |
"PASSED:\n", | |
" CHECK( value.isApprox(input) )\n", | |
"with expansion:\n", | |
" true\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Projector on positive quadrant\n", | |
" Complex matrix\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:11\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:41: \n", | |
"PASSED:\n", | |
" CHECK( expr.imag().isApprox(Image<>::Zero(5, 5)) )\n", | |
"with expansion:\n", | |
" true\n", | |
"with messages:\n", | |
" input := (1.02962,-0.448839) (0.811058,0.145902) (0.529954,0.144798)\n", | |
" (0.633158,-0.0148309) (0.993374,-0.257241)\n", | |
" (1.16931,-0.0924007) (-1.28205,0.540141) (1.42318,-0.250019) (1\n", | |
" .43742,0.450129) (0.549806,0.492541)\n", | |
" (1.22131,0.451353) (0.851873,-0.278257) (0.930053,0.293144) (0\n", | |
" .516621,0.445118) (0.531124,0.000777804)\n", | |
" (1.28842,-0.261302) (1.53081,0.244926) (-0.975505,-0.288448) (1\n", | |
" .00498,0.0179212) (0.872556,-0.24521)\n", | |
" (0.502211,0.25969) (1.27869,0.16667) (0.752398,-0.154809) (0\n", | |
" .800936,0.535306) (1.4552,0.0327221)\n", | |
" expr := (1.02962,0) (0.811058,0) (0.529954,0) (0.633158,0) (0.993374,0)\n", | |
" (1.16931,0) (0,0) (1.42318,0) (1.43742,0) (0.549806,0)\n", | |
" (1.22131,0) (0.851873,0) (0.930053,0) (0.516621,0) (0.531124,0)\n", | |
" (1.28842,0) (1.53081,0) (0,0) (1.00498,0) (0.872556,0)\n", | |
" (0.502211,0) (1.27869,0) (0.752398,0) (0.800936,0) (1.4552,0)\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:44: \n", | |
"PASSED:\n", | |
" CHECK( value.real()(1, 1) == Approx(0) )\n", | |
"with expansion:\n", | |
" 0.0 == Approx( 0.0 )\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:45: \n", | |
"PASSED:\n", | |
" CHECK( value.real()(3, 2) == Approx(0) )\n", | |
"with expansion:\n", | |
" 0.0 == Approx( 0.0 )\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:48: \n", | |
"PASSED:\n", | |
" CHECK( value.real().isApprox(input.real()) )\n", | |
"with expansion:\n", | |
" true\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:49: \n", | |
"PASSED:\n", | |
" CHECK( value.imag().isApprox(0e0 * input.real()) )\n", | |
"with expansion:\n", | |
" true\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Weighted l1 norm\n", | |
" Real valued\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:53\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:60: \n", | |
"PASSED:\n", | |
" CHECK( sopt::l1_norm(input, weight) == Approx(5 + 12 + 21 + 32) )\n", | |
"with expansion:\n", | |
" 70.0 == Approx( 70.0 )\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Weighted l1 norm\n", | |
" Complex valued\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:53\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:66: \n", | |
"PASSED:\n", | |
" CHECK( sopt::l1_norm(input, weight) == Approx(std::sqrt(2) * (5 + 12 + 21 + 32)) )\n", | |
"with expansion:\n", | |
" 98.9949493661 == Approx( 98.9949493661 )\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Soft threshhold\n", | |
" Single-valued threshhold\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:70\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:76: \n", | |
"PASSED:\n", | |
" CHECK( sopt::soft_threshhold(input, 1.1e1)(0) == Approx(0) )\n", | |
"with expansion:\n", | |
" 0.0 == Approx( 0.0 )\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:77: \n", | |
"PASSED:\n", | |
" CHECK( not(sopt::soft_threshhold(input, 1.1e1)(1) == Approx(0)) )\n", | |
"with expansion:\n", | |
" true\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:85: \n", | |
"PASSED:\n", | |
" CHECK( (b - a) == Approx(2 * (c - b)) )\n", | |
"with expansion:\n", | |
" 4.5 == Approx( 4.5 )\n", | |
"with messages:\n", | |
" b - a := 4.5\n", | |
" c - b := 2.25\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Soft threshhold\n", | |
" Multi-values threshhold\n", | |
" Real input\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:70\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:96: \n", | |
"PASSED:\n", | |
" CHECK( actual(0) == 0e0 )\n", | |
"with expansion:\n", | |
" 0.0 == 0.0\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:97: \n", | |
"PASSED:\n", | |
" CHECK( actual(1) == input(1) - threshhold(1) )\n", | |
"with expansion:\n", | |
" 9.0 == 9.0\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:98: \n", | |
"PASSED:\n", | |
" CHECK( actual(2) == input(2) + threshhold(2) )\n", | |
"with expansion:\n", | |
" -29.0 == -29.0\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:99: \n", | |
"PASSED:\n", | |
" CHECK( actual(3) == input(3) - threshhold(3) )\n", | |
"with expansion:\n", | |
" 35.5 == 35.5\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:101: \n", | |
"PASSED:\n", | |
" CHECK_THROWS_AS( soft_threshhold(input, threshhold.head(2)) )\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Soft threshhold\n", | |
" Multi-values threshhold\n", | |
" Complex input\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:70\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:105: \n", | |
"PASSED:\n", | |
" CHECK( actual(0) == 0e0 )\n", | |
"with expansion:\n", | |
" (0,0) == 0.0\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:106: \n", | |
"PASSED:\n", | |
" CHECK( actual(1) == input(1) - threshhold(1) )\n", | |
"with expansion:\n", | |
" (9,0) == 9.0\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:107: \n", | |
"PASSED:\n", | |
" CHECK( actual(2) == input(2) + threshhold(2) )\n", | |
"with expansion:\n", | |
" (-29,0) == -29.0\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:108: \n", | |
"PASSED:\n", | |
" CHECK( actual(3) == input(3) - threshhold(3) )\n", | |
"with expansion:\n", | |
" (35.5,0) == 35.5\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:110: \n", | |
"PASSED:\n", | |
" CHECK_THROWS_AS( soft_threshhold(input, threshhold.head(2)) )\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Sampling\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:115\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:123: \n", | |
"PASSED:\n", | |
" CHECK( down.size() == 4 )\n", | |
"with expansion:\n", | |
" 4 == 4\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:124: \n", | |
"PASSED:\n", | |
" CHECK( down(0) == input(1) )\n", | |
"with expansion:\n", | |
" 946997239 (0x387207f7)\n", | |
" ==\n", | |
" 946997239 (0x387207f7)\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:125: \n", | |
"PASSED:\n", | |
" CHECK( down(1) == input(3) )\n", | |
"with expansion:\n", | |
" 561597601 (0x21794ca1)\n", | |
" ==\n", | |
" 561597601 (0x21794ca1)\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:126: \n", | |
"PASSED:\n", | |
" CHECK( down(2) == input(6) )\n", | |
"with expansion:\n", | |
" -804521730 == -804521730\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:127: \n", | |
"PASSED:\n", | |
" CHECK( down(3) == input(5) )\n", | |
"with expansion:\n", | |
" 703982291 (0x29f5ead3)\n", | |
" ==\n", | |
" 703982291 (0x29f5ead3)\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:131: \n", | |
"PASSED:\n", | |
" CHECK( up(1) == input(1) )\n", | |
"with expansion:\n", | |
" 946997239 (0x387207f7)\n", | |
" ==\n", | |
" 946997239 (0x387207f7)\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:132: \n", | |
"PASSED:\n", | |
" CHECK( up(3) == input(3) )\n", | |
"with expansion:\n", | |
" 561597601 (0x21794ca1)\n", | |
" ==\n", | |
" 561597601 (0x21794ca1)\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:133: \n", | |
"PASSED:\n", | |
" CHECK( up(6) == input(6) )\n", | |
"with expansion:\n", | |
" -804521730 == -804521730\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:134: \n", | |
"PASSED:\n", | |
" CHECK( up(5) == input(5) )\n", | |
"with expansion:\n", | |
" 703982291 (0x29f5ead3)\n", | |
" ==\n", | |
" 703982291 (0x29f5ead3)\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:139: \n", | |
"PASSED:\n", | |
" CHECK( up == t_Vector::Zero(up.size()) )\n", | |
"with expansion:\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" ==\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
" 0\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Relative variation\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:142\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:146: \n", | |
"PASSED:\n", | |
" CHECK( not relvar(input) )\n", | |
"with expansion:\n", | |
" true\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:147: \n", | |
"PASSED:\n", | |
" CHECK( relvar(input) )\n", | |
"with expansion:\n", | |
" true\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:148: \n", | |
"PASSED:\n", | |
" CHECK( relvar(input + relvar.epsilon() * 0.5 / 6. * sopt::Array<>::Random(6)) )\n", | |
"with expansion:\n", | |
" true\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:149: \n", | |
"PASSED:\n", | |
" CHECK( not relvar(input + relvar.epsilon() * 1.1 * sopt::Array<>::Ones(6)) )\n", | |
"with expansion:\n", | |
" true\n", | |
"\n", | |
"-------------------------------------------------------------------------------\n", | |
"Standard deviation\n", | |
"-------------------------------------------------------------------------------\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:152\n", | |
"...............................................................................\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:160: \n", | |
"PASSED:\n", | |
" CHECK( std::abs(sopt::standard_deviation(input) - stddev) < 1e-8 )\n", | |
"with expansion:\n", | |
" 0.0 < 0.00000001\n", | |
"\n", | |
"/Users/mdavezac/workspaces/bico/src/soptshoptalk/sopt/cpp/tests/maths.cc:161: \n", | |
"PASSED:\n", | |
" CHECK( std::abs(sopt::standard_deviation(input.matrix()) - stddev) < 1e-8 )\n", | |
"with expansion:\n", | |
" 0.0 < 0.00000001\n", | |
"\n", | |
"===============================================================================\n", | |
"All tests passed (41 assertions in 6 test cases)\n", | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"%%bash\n", | |
"sopt/build/cpp/tests/test_maths -s" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"## How we know it works\n", | |
"\n", | |
"- Each functional bit of code is unit-tested\n", | |
"- Continuously tested:\n", | |
"\n", | |
"![](jenkins.png)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "slide" | |
} | |
}, | |
"source": [ | |
"## Learning how to use it\n", | |
"\n", | |
"- take a look at the tests!\n", | |
"- take a look at this [talk](https://gist.github.com/mdavezac/21b39888fe877aa39dd805984f961a89)!\n", | |
"- examples! wow!" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"collapsed": false, | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"CMakeLists.txt \u001b[34mproximal_admm\u001b[m\u001b[m/\r\n", | |
"conjugate_gradient.cc sara.cc\r\n", | |
"l1_norm.cc \u001b[34msdmm\u001b[m\u001b[m/\r\n", | |
"l1_proximal.cc soft_threshhold.cc\r\n", | |
"positive_quadrant_projection.cc wavelets.cc\r\n" | |
] | |
} | |
], | |
"source": [ | |
"ls sopt/cpp/examples" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"```cpp\n", | |
"#include <sopt/maths.h>\n", | |
"#include <sopt/types.h>\n", | |
"\n", | |
"int main(int, char const **) {\n", | |
" sopt::Matrix<int> input(2, 2), weights(2, 2);\n", | |
" input << 1, -2, 3, -4;\n", | |
" weights << 5, 6, 7, 8;\n", | |
"\n", | |
" if(sopt::l1_norm(input, weights) != 1 * 5 + 2 * 6 + 3 * 7 + 4 * 8)\n", | |
" throw std::exception();\n", | |
"\n", | |
" return 0;\n", | |
"}\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "slide" | |
} | |
}, | |
"source": [ | |
"# Proximal Alternate Direction Method of Multipliers\n", | |
"\n", | |
"Solve $$\\min_{x\\in\\mathbb{R}^N, y\\in\\mathbb{R}^M} f(x) + g(z)\\quad\\text{s.t.}\\quad \\Phi x + z = y$$\n", | |
"\n", | |
"- $\\mathbf{L}$ is a linear transform/Measurement operator\n", | |
"- $y\\in\\mathbb{R}^M$ is a vector/target measurements\n", | |
"\n", | |
"The algorithm defines the *augmented Lagrangian* $\\mathcal{L}_\\gamma$\n", | |
"\n", | |
"$$\\mathcal{L}_\\gamma(x, y, \\lambda) = f(x) + g(z) + \\frac{\\lambda^H}{\\gamma}(\\Phi x + z - y) + \\frac{1}{2\\gamma}||\\Phi x + z - y||_2^2$$" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"### Algorithm\n", | |
"Loop until converged:\n", | |
"$$z^{(n+1)} = \\mathrm{prox}_{\\gamma g}(y - \\Phi x^{(n)} - \\lambda^{(n)})$$\n", | |
"$$x^{(n+1)} = \\mathrm{prox}_{\\frac{\\gamma}{\\nu} f}(x^{(n)}-\\mu\\Phi^Hx^{(n)} - y - z^{(n+1)})$$\n", | |
"$$\\lambda^{(n+1)} = \\lambda^{(n)} + \\beta(\\Phi x^{(n+1)} - y - z^{(n + 1)})$$" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"### Algorithm\n", | |
"Loop until converged:\n", | |
"$$z^{(n+1)} = \\mathrm{prox}_{\\gamma g}(y - \\Phi x^{(n)} - \\lambda^{(n)})$$\n", | |
"$$x^{(n+1)} = \\mathrm{prox}_{\\frac{\\gamma}{\\nu} f}(x^{(n)}-\\mu\\Phi^Hx^{(n)} - y - z^{(n+1)})$$\n", | |
"$$\\lambda^{(n+1)} = \\lambda^{(n)} + \\beta(\\Phi x^{(n+1)} - y - z^{(n + 1)})$$\n", | |
"\n", | |
"### Implementation\n", | |
"\n", | |
"```cpp\n", | |
"g_proximal(z, gamma(), -lambda - residual);\n", | |
"f_proximal(out, gamma() / nu(), out - Phi().adjoint() * (residual + lambda + z) / nu());\n", | |
"residual = Phi() * out - target();\n", | |
"lambda += lagrange_update_scale() * (residual + z);\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"collapsed": true, | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"## Usage\n", | |
"\n", | |
"Lets solve $\\min_{x} ||x||_2 + ||x - x_1||_2$.\n", | |
"\n", | |
"The solution is any point on the segment $[0, x_1]$.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"We will need a few headers:\n", | |
" \n", | |
"```cpp\n", | |
"#include <sopt/paddm.h>\n", | |
"#include <sopt/proximal.h>\n", | |
"#include <sopt/relative_variation.h>\n", | |
"#include <iostream>\n", | |
"```\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"Then we can define the proximals of `f` and `g`.\n", | |
"\n", | |
"Any function or lambda or functor with the right signature will work:\n", | |
"\n", | |
"```cpp\n", | |
"auto const prox_f = [](Vector<> &out, double gamma, Vector<> const &input) -> void {\n", | |
" auto const norm = x.stableNorm();\n", | |
" if(norm > t)\n", | |
" out = (1 - gamma / norm) * x;\n", | |
" else\n", | |
" out.fill(0); \n", | |
"};\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"Some helper functions are already defined in `sopt/proximal.h`:\n", | |
"\n", | |
"\n", | |
"```cpp\n", | |
"auto const N = 3;\n", | |
"auto const x0 = sopt::Vector<>::Random(N);\n", | |
"auto const prox_g = sopt::proximal::translate(sopt::proximal::EuclidianNorm(), -x0);\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"Then we defined the sensing operator $\\Phi$ and the target measurements $y$:\n", | |
" \n", | |
"```cpp\n", | |
"Vector<> const y = Vector<>::Zero(N);\n", | |
"Matrix<> const Phi = -Matrix<>::Identity(N, N);\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"We are now in a position to define the solver:\n", | |
"\n", | |
"```cpp\n", | |
"auto padmm = sopt::algorithm::ProximalADMM<double>(prox_f, prox_g, y)\n", | |
" .itermax(5000)\n", | |
" .is_converged(sopt::RelativeVariation<double>(1e-12))\n", | |
" .gamma(0.01)\n", | |
" .Phi(Phi);\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"And to use it:\n", | |
" \n", | |
"```cpp\n", | |
"auto const result = padmm();\n", | |
"std::cout << result.x.transpose() << std::endl;\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"`result` is a structure with the solution and information about the run:\n", | |
" \n", | |
"```cpp\n", | |
"struct {\n", | |
" //! Number of iterations\n", | |
" sopt::t_uint niters;\n", | |
" //! Wether convergence was achieved\n", | |
" bool good;\n", | |
" //! the residual from the last iteration\n", | |
" sopt::Vector<> residual;\n", | |
" //! The solution!\n", | |
" sopt::Vector<> x;\n", | |
"}\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "slide" | |
} | |
}, | |
"source": [ | |
"# Hands-on" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"## Putting the usage example in project of its own\n", | |
"\n", | |
"1. Create a CMake project that can find sopt and link to it:\n", | |
" In a new directory, create the file `CMakeLists.txt`\n", | |
" \n", | |
" ```CMake\n", | |
" cmake_minimum_required(VERSION 2.8)\n", | |
" project(Handson CXX)\n", | |
" \n", | |
" find_package(Sopt REQUIRED)\n", | |
" add_executable(main main.cc)\n", | |
" target_link_library(main sopt)\n", | |
" ```\n", | |
" \n", | |
"1. Put the example into `main.cc`:\n", | |
"\n", | |
" ```cpp\n", | |
" // headers\n", | |
" \n", | |
" int main(int, char**) {\n", | |
" // example\n", | |
" \n", | |
" return 0;\n", | |
" }\n", | |
" ```\n", | |
" \n", | |
"1. Build, compile and run:\n", | |
"\n", | |
" ```Bash\n", | |
" mkdir build\n", | |
" cd build\n", | |
" cmake ..\n", | |
" make\n", | |
" ./main\n", | |
" ```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"## Hands-on 2\n", | |
"\n", | |
"Craft yourself something new to minimize: $\\min_x f(x) + g(x)$, $f(x) = ?$, $g(x) = ?$, including this proximal\n", | |
"\n", | |
"$$h(x) = x^T\\mathcal{A}x + b^Tx + c,\\quad A\\geq 0\\quad\\mapsto\\quad\n", | |
"\\mathrm{prox}_{\\gamma h}(x) = (I + tA)^{-1}(x - tb)$$\n", | |
"\n", | |
"And solve it using Sopt's PADMM method.\n", | |
"\n", | |
"----\n", | |
"Hint: Define new functions `prox_f` and `prox_g`, use them as input to `paddmm`. " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "subslide" | |
} | |
}, | |
"source": [ | |
"## Useful and less useful extras\n", | |
"\n", | |
"1. The verbosity of the logging/output is controlled by:\n", | |
" \n", | |
" ```cpp\n", | |
" // initialize logging in main\n", | |
" sopt::logging::initialize();\n", | |
" // control verbosity: trace, debug, info, warn, critical, off\n", | |
" sopt::logging::set_level(\"warn\");\n", | |
" ```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"slideshow": { | |
"slide_type": "fragment" | |
} | |
}, | |
"source": [ | |
"2. Linear transforms and their adjoint can be specified with a matrix or two functions (mapping a vector to another)\n", | |
"\n", | |
" ```cpp\n", | |
" auto const direct = [](Vector<> &out, Vector<> const &input) {\n", | |
" out = 2 * input;\n", | |
" };\n", | |
" auto const adjoint = [](Vector<> &out, Vector<> const &input) {\n", | |
" out = 1./2. * input;\n", | |
" };\n", | |
" auto const Phi = linear_transform(direct, adjoint, {1, 1, 0});\n", | |
" ```\n", | |
" \n", | |
" The last three numbers `(a, b, c)` help determine the size of the output vector from the size of the input vector: `size(output) = size(input) * a / b + c`.\n", | |
" If the size of the output `Nout` is fixed, then `{0, 0, Nout}` will do.\n", | |
" \n", | |
" The transform can be called on a `Vector<> x` as `Phi * x` and the adjoint as `Phi.adjoint() * x`.\n", | |
" " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"1. Some known proximal and known proximal transforms (translation, etc) are available in `cpp/sopt/proximal.h`\n", | |
"1. The proximal of the $x\\mapsto ||\\Phi x||_1$ is available in `sopt/cpp/l1_norm.h` " | |
] | |
} | |
], | |
"metadata": { | |
"celltoolbar": "Slideshow", | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.12" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment