liblbfgs简介
liblbfgs是L-BFGS算法的C語言實現,用于求解非線性優化問題。
liblbfgs的主頁:http://www.chokkan.org/software/liblbfgs/
下載鏈接(見上面的主頁鏈接):
- https://github.com/downloads/chokkan/liblbfgs/liblbfgs-1.10.tar.gz?用于Linux平臺
- https://github.com/chokkan/liblbfgs?
用于Windows平臺
Linux下用gcc 編譯
解壓文件,進入目錄,可參照 軟件包里面的說明文檔,命令依次如下:
./configure
make
make install
編譯后的目錄文件:
C源碼文件在lib,include和?sample?三個文件夾里,而主文件在’sample’ 里,其目錄如下:
其中沒有文件后綴名的文件sample就是最終的可執行文件,運行:?
Windows下用visual studio編譯
只需要把幾個C/C++源碼文件加入到項目即可,其余的文件一律棄之不用,如下圖所示的VS項目文件的目錄,我們只要?4?個頭文件?arithmetic_ansi.h,?arithmetic_sse_double.h,?arithmetic_sse_float.h,lbfgs.h?和三個源文件?
lbfgs.c,?sample.c,?sample.cpp。
主函數文件(包含main函數)是?sample.c(用c語言寫的),和?sample.cpp(用C++寫成,封裝成一個類)。一個VS項目里只能有一個main函數,所以每次運行要禁用二者中的一個。
需要注意的是頭文件中的?arithmetic_ansi.h,?arithmetic_sse_double.h,?arithmetic_sse_float.h,三個頭文件只能用一個,選擇哪個由’lbfgs.cpp’中一段代碼控制,該段代碼如下:
默認情況下?USE_SSE、__SSE2__、__SSE__?都沒有定義,L-BFGS_FLOAT?在?lbfgs.h中定義。由此可知默認情況下采用的是?arithmetic_ansi.h?。
若要采用?arithmetic_sse_double.h,經查L-BFGS_FLOAT?被定義為 64,所以再定義其它兩個變量,如下:
SSE2到底是什么東西呢?插入一段相關介紹:
SSE2(Streaming SIMD Extensions 2):指令集,擴展了SSE指令集,并可完全取代MMX。SSE2指令集是Intel公司在SSE指令集的基礎上發展起來的。相比于SSE,SSE2使用了144個新增指令,擴展了MMX技術和SSE技術,提高了諸如MPEG-2、MP3、3D圖形等應用程序的運行性能。在整數處理方面,隨MMX技術引進的SIMD整數指令從64位擴展到了128 位,使SIMD整數類型操作的執行效率成倍提高;在浮點數處理方面,雙精度浮點SIMD指令允許以 SIMD格式同時執行兩個浮點操作,提供雙精度操作支持有助于加速內容創建、財務、工程和科學應用。除SSE2指令之外,最初的SSE指令也得到增強,通過支持多種數據類型(例如雙字、四字)的算術運算,支持靈活、動態范圍更廣的計算功能。
可見引入?arithmetic_sse_double.h?或?arithmetic_sse_float.h?是為了提高浮點數的運算速度,改善程序性能。
main函數分析
main函數里給出了一個用L-BFGS算法進行非線性優化的例子,貼出main函數的代碼:
<code class="language-c hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "lbfgs.h"</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//注意lbfgsfloatval_t在lbfgs.h里定義,32位機上是float,64位機上是double。</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//evaluate定義要優化的非線性函數fx及其梯度g</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> lbfgsfloatval_t evaluate( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *instance,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> lbfgsfloatval_t *x,lbfgsfloatval_t *g,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> lbfgsfloatval_t step) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i;lbfgsfloatval_t fx = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i < n;i += <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>) {lbfgsfloatval_t t1 = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span> - x[i];lbfgsfloatval_t t2 = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10.0</span> * (x[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] - x[i] * x[i]);g[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20.0</span> * t2;g[i] = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.0</span> * (x[i] * g[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] + t1);fx += t1 * t1 + t2 * t2;}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> fx; }<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//progress函數每次迭代結束就執行一次,打印迭代信息</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> progress(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *instance,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> lbfgsfloatval_t *x,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> lbfgsfloatval_t *g,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> lbfgsfloatval_t fx,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> lbfgsfloatval_t xnorm,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> lbfgsfloatval_t gnorm,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> lbfgsfloatval_t step,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> k,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> ls) {<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Iteration %d:\n"</span>, k);<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" fx = %f,"</span>, fx);<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" xnorm = %f, gnorm = %f, step = %f\n"</span>, xnorm, gnorm, step);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; }<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#define N 100 <span class="hljs-comment" style="box-sizing: border-box;">//參數個數</span></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *argv[]) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i, ret = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;lbfgsfloatval_t fx;lbfgsfloatval_t *x = lbfgs_malloc(N); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//x是長度為N的數組</span>lbfgs_parameter_t param;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (x == NULL) {<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"ERROR: Failed to allocate a memory block for variables.\n"</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* Initialize the variables. */</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i < N;i += <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>) {x[i] = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.2</span>;x[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>;}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* Initialize the parameters for the L-BFGS optimization. */</span>lbfgs_parameter_init(¶m);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*param.linesearch = LBFGS_LINESEARCH_BACKTRACKING;*/</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*Start the L-BFGS optimization; this will invoke the callback functionsevaluate() and progress() when necessary.*/</span>ret = lbfgs(N, x, &fx, evaluate, progress, NULL, ¶m);<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"算法收斂后的函數取值 fx = %f\n"</span>, fx, x[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], x[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]);<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"最終的解(長度為100個浮點數的數組):"</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<N;i++) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i%<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span>);}<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%2.2lf "</span>,x[i]);}lbfgs_free(x); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//釋放參數數組所占的內存</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li></ul>非線性函數f(x)?及其 梯度?g(x)?的定義如下:
<code class="language-c hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i < n;i += <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>) {lbfgsfloatval_t t1 = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span> - x[i];lbfgsfloatval_t t2 = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10.0</span> * (x[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] - x[i] * x[i]);g[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20.0</span> * t2;g[i] = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.0</span> * (x[i] * g[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] + t1);fx += t1 * t1 + t2 * t2; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>可知輸入參數 有100個,即數組?x,函數f(x)定義如下
f(x)=∑i=0,2,4,...,N?2(1?xi)2+(10(xi+1?x2i))2
其奇數位置 (i=1,3,5,...) 的參數的梯度?
200(xi+1?x2i)
其偶數位置? (i=0,2,4,6,...) 的參數的梯度?
?2(1?xi)?400?xi?(xi+1?x2i)
python 封裝liblbfgs
- pylbfgs 用Python封裝的 liblbfgs?
https://github.com/larsmans/pylbfgs - PyLBFGS?
https://github.com/sseemayer/PyLBFGS/blob/master/test.py
總結
以上是生活随笔為你收集整理的liblbfgs简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rust开发环境_Rust 环境搭建
- 下一篇: 计算机直线的绘制实验报告,dda画直线实