Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0084765d0b | |||
| 91f332cac1 | |||
| d2904f3379 | |||
| 1f5145a580 | |||
| 38c0f38d72 | |||
| cb3d271071 | |||
| bcafb30f35 | |||
| 4076f6803a | |||
| bbc63f3e25 | |||
| fb98a740ea | |||
| 462d3121ee | |||
| d3ebea8582 | |||
|
|
7fc787678e | ||
|
|
3b35fa16dc | ||
|
|
2cee127280 | ||
|
|
e4f94fabd2 | ||
|
|
6aa4a77c99 | ||
|
|
2fc13c1ac5 | ||
|
|
7777580e1e | ||
|
|
23b8bddc92 | ||
|
|
c16297a59e | ||
|
|
57678b188a | ||
|
|
b2a54a9812 | ||
|
|
31ef1e8ea0 | ||
|
|
2e414afe81 | ||
|
|
fb51be30d4 | ||
|
|
d83800b05c |
25
.gitignore
vendored
Normal file
25
.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
## C
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
|
||||
build/
|
||||
.DS_Store
|
||||
20
CMakeLists.txt
Normal file
20
CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.15.2)
|
||||
# 设置cxx编译器
|
||||
# 如果你使用别的编译器,请在这里修改
|
||||
set(CMAKE_C_COMPILER /usr/local/bin/gcc-9)
|
||||
set(CMAKE_CXX_COMPILER /usr/local/bin/g++-9)
|
||||
# 设置工程名称和语言
|
||||
project(LIBLBFGS VERSION 1.1.0)
|
||||
# 设置安装地址 改用homebrew安装后这一句就不需要了
|
||||
# set(CMAKE_INSTALL_PREFIX /usr/local)
|
||||
# 添加编译选项
|
||||
option(HAVE_CONFIG_H "use config.h" ON)
|
||||
option(_MSC_VER "use __msc_ver" OFF)
|
||||
option(USE_SSE "use see" OFF)
|
||||
# 加入一个头文件配置,让cmake对源码进行操作
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/config.h.in"
|
||||
"${PROJECT_SOURCE_DIR}/src/lib/config.h"
|
||||
)
|
||||
# 添加源文件地址
|
||||
add_subdirectory(src/)
|
||||
22
COPYING
22
COPYING
@@ -1,22 +0,0 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 1990 Jorge Nocedal
|
||||
Copyright (c) 2007-2010 Naoaki Okazaki
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
120
ChangeLog
120
ChangeLog
@@ -1,120 +0,0 @@
|
||||
2010-xx-xx Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.10:
|
||||
- Fixed compiling errors on Mac OS X; this patch was kindly submitted by Nic Schraudolph.
|
||||
- Reduced compiling warnings on Mac OS X; this patch was kindly submitted by Tamas Nepusz.
|
||||
|
||||
|
||||
2010-01-29 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.9:
|
||||
- Fixed a mistake in checking the validity of the parameters "ftol" and "wolfe"; this mistake was discovered by Kevin S. Van Horn.
|
||||
|
||||
|
||||
2009-07-13 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.8:
|
||||
- Accepted the patch submitted by Takashi Imamichi; the backtracking method now has three criteria for choosing the step length.
|
||||
- Updated the documentation to explain the above three criteria.
|
||||
|
||||
|
||||
2009-02-28 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.7:
|
||||
- Improved OWL-QN routines for stability.
|
||||
- Removed the support of OWL-QN method in MoreThuente algorithm
|
||||
because it accidentally fails in early stages of iterations for some
|
||||
objectives. Because of this change, the OW-LQN method must be used
|
||||
with the backtracking algorithm (LBFGS_LINESEARCH_BACKTRACKING), or
|
||||
the library returns LBFGSERR_INVALID_LINESEARCH.
|
||||
- Renamed line search algorithms as follows:
|
||||
- LBFGS_LINESEARCH_BACKTRACKING: regular Wolfe condition.
|
||||
- LBFGS_LINESEARCH_BACKTRACKING_LOOSE: regular Wolfe condition.
|
||||
- LBFGS_LINESEARCH_BACKTRACKING_STRONG: strong Wolfe condition.
|
||||
- Source code clean-up.
|
||||
|
||||
|
||||
2008-11-02 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.6:
|
||||
- Improved line-search algorithm with strong Wolfe condition, which
|
||||
was contributed by Takashi Imamichi. This routine is now default for
|
||||
LBFGS_LINESEARCH_BACKTRACKING. The previous line search algorithm
|
||||
with regular Wolfe condition is still available as
|
||||
LBFGS_LINESEARCH_BACKTRACKING_LOOSE.
|
||||
- Configurable stop index for L1-norm computation. A member variable
|
||||
lbfgs_parameter_t::orthantwise_end was added to specify the index
|
||||
number at which the library stops computing the L1 norm of the
|
||||
variables. This is useful to prevent some variables from being
|
||||
regularized by the OW-LQN method.
|
||||
- A sample program written in C++ (sample/sample.cpp).
|
||||
|
||||
|
||||
2008-07-10 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.5:
|
||||
- Configurable starting index for L1-norm computation. A member
|
||||
variable lbfgs_parameter_t::orthantwise_start was added to specify
|
||||
the index number from which the library computes the L1 norm of the
|
||||
variables.
|
||||
- Fixed a zero-division error when the initial variables have already
|
||||
been a minimizer (reported by Takashi Imamichi). In this case, the
|
||||
library returns LBFGS_ALREADY_MINIMIZED status code.
|
||||
- Defined LBFGS_SUCCESS status code as zero; removed unused constants,
|
||||
LBFGSFALSE and LBFGSTRUE.
|
||||
- Fixed a compile error in an implicit down-cast.
|
||||
|
||||
|
||||
2008-04-25 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.4:
|
||||
- Configurable line search algorithms. A member variable
|
||||
lbfgs_parameter_t::linesearch was added to choose either MoreThuente
|
||||
method (LBFGS_LINESEARCH_MORETHUENTE) or backtracking algorithm
|
||||
(LBFGS_LINESEARCH_BACKTRACKING).
|
||||
- Fixed a bug: the previous version did not compute psuedo-gradients
|
||||
properly in the line search routines for OW-LQN. This bug might quit
|
||||
an iteration process too early when the OW-LQN routine was activated
|
||||
(0 < lbfgs_parameter_t::orthantwise_c).
|
||||
- Configure script for POSIX environments.
|
||||
- SSE/SSE2 optimizations with GCC.
|
||||
- New functions lbfgs_malloc and lbfgs_free to use SSE/SSE2 routines
|
||||
transparently. It is uncessary to use these functions for libLBFGS
|
||||
built without SSE/SSE2 routines; you can still use any memory
|
||||
allocators if SSE/SSE2 routines are disabled in libLBFGS.
|
||||
|
||||
|
||||
2007-12-16 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.3:
|
||||
- An API change. An argument was added to lbfgs() function to receive
|
||||
the final value of the objective function. This argument can be set
|
||||
to NULL if the final value is unnecessary.
|
||||
- Fixed a null-pointer bug in the sample code (reported by Takashi
|
||||
Imamichi).
|
||||
- Added build scripts for Microsoft Visual Studio 2005 and GCC.
|
||||
- Added README file.
|
||||
|
||||
|
||||
2007-12-13 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.2:
|
||||
- Fixed a serious bug in orthant-wise L-BFGS. An important variable
|
||||
was used without initialization.
|
||||
- Configurable L-BFGS parameters (number of limited memories, epsilon).
|
||||
|
||||
|
||||
2007-12-01 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.1:
|
||||
- Implemented orthant-wise L-BFGS.
|
||||
- Implemented lbfgs_parameter_init() function.
|
||||
- Fixed several bugs.
|
||||
- API documentation.
|
||||
|
||||
|
||||
2007-09-20 Naoaki Okazaki <okazaki at chokkan org>
|
||||
|
||||
* libLBFGS 1.0
|
||||
- Initial release.
|
||||
|
||||
10
Makefile.am
10
Makefile.am
@@ -1,10 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
SUBDIRS = lib sample
|
||||
|
||||
docdir = $(prefix)/share/doc/@PACKAGE@
|
||||
doc_DATA = README INSTALL COPYING AUTHORS ChangeLog NEWS
|
||||
|
||||
EXTRA_DIST = \
|
||||
autogen.sh \
|
||||
lbfgs.sln
|
||||
8
README
8
README
@@ -28,6 +28,14 @@ http://www.chokkan.org/software/liblbfgs/
|
||||
Open the solution file "lbfgs.sln" and build it.
|
||||
|
||||
[GCC]
|
||||
|
||||
On top of a compiler and GNU Make, you will also need to install libtool
|
||||
and automake to build.
|
||||
|
||||
On Debian distributions, this can be installed with:
|
||||
sudo apt install libtool automake
|
||||
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install # To install libLBFGS library and header.
|
||||
|
||||
38
autogen.sh
38
autogen.sh
@@ -1,38 +0,0 @@
|
||||
#!/bin/sh
|
||||
# $Id$
|
||||
|
||||
if [ "$1" = "--force" ];
|
||||
then
|
||||
FORCE=--force
|
||||
NOFORCE=
|
||||
FORCE_MISSING=--force-missing
|
||||
else
|
||||
FORCE=
|
||||
NOFORCE=--no-force
|
||||
FORCE_MISSING=
|
||||
fi
|
||||
|
||||
libtoolize --copy $FORCE 2>&1 | sed '/^You should/d' || {
|
||||
echo "libtoolize failed!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
aclocal $FORCE || {
|
||||
echo "aclocal failed!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
autoheader $FORCE || {
|
||||
echo "autoheader failed!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
automake -a -c $NOFORCE || {
|
||||
echo "automake failed!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
autoconf $FORCE || {
|
||||
echo "autoconf failed!"
|
||||
exit 1
|
||||
}
|
||||
3
config.h.in
Normal file
3
config.h.in
Normal file
@@ -0,0 +1,3 @@
|
||||
#cmakedefine HAVE_CONFIG_H
|
||||
#cmakedefine _MSC_VER
|
||||
#cmakedefine USE_SSE
|
||||
107
configure.in
107
configure.in
@@ -1,107 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl
|
||||
dnl
|
||||
dnl Exported and configured variables:
|
||||
dnl CFLAGS
|
||||
dnl LDFLAGS
|
||||
dnl INCLUDES
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Initialization for autoconf
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_PREREQ(2.59)
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([lib/lbfgs.c])
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Initialization for automake
|
||||
dnl ------------------------------------------------------------------
|
||||
AM_INIT_AUTOMAKE(liblbfgs, 1.10)
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Checks for program
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Initialization for variables
|
||||
dnl ------------------------------------------------------------------
|
||||
CFLAGS="${ac_save_CFLAGS} -Wall"
|
||||
LDFLAGS="${ac_save_LDFLAGS}"
|
||||
INCLUDES="-I\$(top_srcdir) -I\$(top_srcdir)/include"
|
||||
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Checks for header files.
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(xmmintrin.h emmintrin.h)
|
||||
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Checks for debugging mode
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_ARG_ENABLE(
|
||||
debug,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-debug],
|
||||
[build for debugging]
|
||||
)],
|
||||
[CFLAGS="-DDEBUG -O -g ${CFLAGS}"],
|
||||
[CFLAGS="-O3 -ffast-math ${CFLAGS}"]
|
||||
)
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Checks for profiling mode
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_ARG_ENABLE(
|
||||
profile,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-profile],
|
||||
[build for profiling]
|
||||
)],
|
||||
[CFLAGS="-DPROFILE -pg ${CFLAGS}"]
|
||||
)
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Checks for SSE2 build
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_ARG_ENABLE(
|
||||
sse2,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-sse2],
|
||||
[enable SSE2 optimization routines]
|
||||
)],
|
||||
[CFLAGS="-msse2 -DUSE_SSE ${CFLAGS}"]
|
||||
)
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Checks for library functions.
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_CHECK_LIB(m, fabs)
|
||||
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Export variables
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_SUBST(CFLAGS)
|
||||
AC_SUBST(LDFLAGS)
|
||||
AC_SUBST(INCLUDES)
|
||||
|
||||
dnl ------------------------------------------------------------------
|
||||
dnl Output the configure results.
|
||||
dnl ------------------------------------------------------------------
|
||||
AC_CONFIG_FILES(Makefile lib/Makefile sample/Makefile)
|
||||
AC_OUTPUT
|
||||
1514
doc/doxyfile
1514
doc/doxyfile
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
<hr/>
|
||||
<div>
|
||||
Copyright (c) 2002-2010 by Naoaki Okazaki
|
||||
<br /><i>$datetime</i>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,13 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="author" content="Naoaki Okazaki">
|
||||
<meta name="description" content="This library implements Limited-memory Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) method.">
|
||||
<meta name="keywords" content="libLBFGS,L-BFGS,LBFGS,OWL-QN,L1,L2,norm,C,library,SSE,SSE2">
|
||||
<meta name="robots" content="index,follow">
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<title>libLBFGS: L-BFGS library written in C</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
26
lbfgs.sln
26
lbfgs.sln
@@ -1,26 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib", "lib\lib.vcxproj", "{C4405B73-A899-44BF-8681-04CE040B6705}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample", "sample\sample.vcxproj", "{B4D7D5F5-4A4E-49D5-B38A-E5673520DE66}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C4405B73-A899-44BF-8681-04CE040B6705}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C4405B73-A899-44BF-8681-04CE040B6705}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C4405B73-A899-44BF-8681-04CE040B6705}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C4405B73-A899-44BF-8681-04CE040B6705}.Release|Win32.Build.0 = Release|Win32
|
||||
{B4D7D5F5-4A4E-49D5-B38A-E5673520DE66}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B4D7D5F5-4A4E-49D5-B38A-E5673520DE66}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B4D7D5F5-4A4E-49D5-B38A-E5673520DE66}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B4D7D5F5-4A4E-49D5-B38A-E5673520DE66}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,24 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
EXTRA_DIST = \
|
||||
lib.vcxproj
|
||||
|
||||
liblbfgsincludedir = $(includedir)
|
||||
liblbfgsinclude_HEADERS = \
|
||||
../include/lbfgs.h
|
||||
|
||||
lib_LTLIBRARIES = liblbfgs.la
|
||||
|
||||
liblbfgs_la_SOURCES = \
|
||||
arithmetic_ansi.h \
|
||||
arithmetic_sse_double.h \
|
||||
arithmetic_sse_float.h \
|
||||
../include/lbfgs.h \
|
||||
lbfgs.c
|
||||
|
||||
liblbfgs_la_LDFLAGS = \
|
||||
-no-undefined \
|
||||
-release @VERSION@
|
||||
|
||||
AM_CFLAGS = @CFLAGS@
|
||||
INCLUDES = @INCLUDES@
|
||||
@@ -1,95 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C4405B73-A899-44BF-8681-04CE040B6705}</ProjectGuid>
|
||||
<RootNamespace>lib</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionName)</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionName)_debug</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Lib />
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Lib />
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="lbfgs.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="arithmetic_ansi.h" />
|
||||
<ClInclude Include="arithmetic_sse_double.h" />
|
||||
<ClInclude Include="arithmetic_sse_float.h" />
|
||||
<ClInclude Include="..\include\lbfgs.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,15 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
EXTRA_DIST = \
|
||||
sample.cpp \
|
||||
sample.vcxproj
|
||||
|
||||
noinst_PROGRAMS = sample
|
||||
|
||||
sample_SOURCES = \
|
||||
sample.c
|
||||
|
||||
sample_LDADD = ../lib/liblbfgs.la
|
||||
|
||||
AM_CFLAGS = @CFLAGS@
|
||||
INCLUDES = @INCLUDES@
|
||||
@@ -1,105 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B4D7D5F5-4A4E-49D5-B38A-E5673520DE66}</ProjectGuid>
|
||||
<RootNamespace>sample</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="sample.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\lib\lib.vcxproj">
|
||||
<Project>{c4405b73-a899-44bf-8681-04ce040b6705}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
49
src/CMakeLists.txt
Normal file
49
src/CMakeLists.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
# 设定源文件文件夹
|
||||
aux_source_directory(lib/ LIBLBFGS_SRC)
|
||||
|
||||
# 以下部分为库的编译
|
||||
# 注意目标名必须唯一 所以不能直接生成相同名称的动态库与静态库
|
||||
# 注意此处不必为目标名称添加lib前缀和相应后缀,cmake会自行添加
|
||||
add_library(lbfgs SHARED ${LIBLBFGS_SRC})
|
||||
# 首先添加静态库的生成命令
|
||||
add_library(lbfgs_static STATIC ${LIBLBFGS_SRC})
|
||||
# 设置静态库的输出名称从而获得与动态库名称相同的静态库
|
||||
set_target_properties(lbfgs_static PROPERTIES OUTPUT_NAME "lbfgs")
|
||||
# 设置输出目标属性以同时输出动态库与静态库
|
||||
set_target_properties(lbfgs PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
set_target_properties(lbfgs_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
# 设置动态库的版本号
|
||||
set_target_properties(lbfgs PROPERTIES VERSION 1.1 SOVERSION 1.1)
|
||||
# 设置库文件的输出地址
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
||||
# 库的安装命令
|
||||
install(TARGETS lbfgs lbfgs_static
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
# 头文件安装命令
|
||||
install(FILES lib/lbfgs.h DESTINATION include)
|
||||
|
||||
# 以下部分为例子程序的编译
|
||||
# 设置可执行文件的输出地址
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
# 添加可执行文件 命令行
|
||||
add_executable(lbfgs_sample sample/sample.c)
|
||||
# 为安装文件添加动态库的搜索地址
|
||||
set_target_properties(lbfgs_sample PROPERTIES INSTALL_RPATH "/usr/local/lib")
|
||||
# 链接动态库
|
||||
target_link_libraries(lbfgs_sample PUBLIC lbfgs)
|
||||
|
||||
# 添加可执行文件 命令行
|
||||
add_executable(lbfgs_sample2 sample/sample2.cpp)
|
||||
# 为安装文件添加动态库的搜索地址
|
||||
set_target_properties(lbfgs_sample2 PROPERTIES INSTALL_RPATH "/usr/local/lib")
|
||||
# 链接动态库
|
||||
target_link_libraries(lbfgs_sample2 PUBLIC lbfgs)
|
||||
|
||||
# 添加可执行文件 命令行
|
||||
add_executable(lbfgs_sample3 sample/sample3.cpp)
|
||||
# 为安装文件添加动态库的搜索地址
|
||||
set_target_properties(lbfgs_sample3 PROPERTIES INSTALL_RPATH "/usr/local/lib")
|
||||
# 链接动态库
|
||||
target_link_libraries(lbfgs_sample3 PUBLIC lbfgs)
|
||||
@@ -65,7 +65,11 @@ inline static void* vecalloc(size_t size)
|
||||
|
||||
inline static void vecfree(void *memblock)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
_aligned_free(memblock);
|
||||
#else
|
||||
free(memblock);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define vecset(x, c, n) \
|
||||
3
src/lib/config.h
Normal file
3
src/lib/config.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#define HAVE_CONFIG_H
|
||||
/* #undef _MSC_VER */
|
||||
/* #undef USE_SSE */
|
||||
@@ -70,7 +70,7 @@ licence.
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <lbfgs.h>
|
||||
#include "lbfgs.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
@@ -89,16 +89,16 @@ licence.
|
||||
#include "arithmetic_ansi.h"
|
||||
|
||||
#endif
|
||||
|
||||
//宏函数 比较几个数的大小
|
||||
#define min2(a, b) ((a) <= (b) ? (a) : (b))
|
||||
#define max2(a, b) ((a) >= (b) ? (a) : (b))
|
||||
#define max3(a, b, c) max2(max2((a), (b)), (c));
|
||||
|
||||
//回调函数数据类型
|
||||
struct tag_callback_data {
|
||||
int n;
|
||||
void *instance;
|
||||
lbfgs_evaluate_t proc_evaluate;
|
||||
lbfgs_progress_t proc_progress;
|
||||
int n; // 变量的大小
|
||||
void *instance; // 用户给出的运行实例
|
||||
lbfgs_evaluate_t proc_evaluate; // 目标函数与模型梯度计算函数指针
|
||||
lbfgs_progress_t proc_progress; // 迭代过程监控函数指针
|
||||
};
|
||||
typedef struct tag_callback_data callback_data_t;
|
||||
|
||||
@@ -106,10 +106,10 @@ struct tag_iteration_data {
|
||||
lbfgsfloatval_t alpha;
|
||||
lbfgsfloatval_t *s; /* [n] */
|
||||
lbfgsfloatval_t *y; /* [n] */
|
||||
lbfgsfloatval_t ys; /* vecdot(y, s) */
|
||||
lbfgsfloatval_t ys; /* vecdot(y, s) y与s的点积 */
|
||||
};
|
||||
typedef struct tag_iteration_data iteration_data_t;
|
||||
|
||||
// 默认的迭代参数
|
||||
static const lbfgs_parameter_t _defparam = {
|
||||
6, 1e-5, 0, 1e-5,
|
||||
0, LBFGS_LINESEARCH_DEFAULT, 40,
|
||||
@@ -118,7 +118,7 @@ static const lbfgs_parameter_t _defparam = {
|
||||
};
|
||||
|
||||
/* Forward function declarations. */
|
||||
|
||||
// 这里定义了线性搜索的函数类型模版 一下是几个具体的线性搜索函数的声明
|
||||
typedef int (*line_search_proc)(
|
||||
int n,
|
||||
lbfgsfloatval_t *x,
|
||||
@@ -174,7 +174,8 @@ static int line_search_morethuente(
|
||||
callback_data_t *cd,
|
||||
const lbfgs_parameter_t *param
|
||||
);
|
||||
|
||||
// 以上是线性搜索函数的声明
|
||||
// 试算测试步长
|
||||
static int update_trial_interval(
|
||||
lbfgsfloatval_t *x,
|
||||
lbfgsfloatval_t *fx,
|
||||
@@ -189,13 +190,13 @@ static int update_trial_interval(
|
||||
const lbfgsfloatval_t tmax,
|
||||
int *brackt
|
||||
);
|
||||
|
||||
// 计算x的L1模长
|
||||
static lbfgsfloatval_t owlqn_x1norm(
|
||||
const lbfgsfloatval_t* x,
|
||||
const int start,
|
||||
const int n
|
||||
);
|
||||
|
||||
// 计算似模长
|
||||
static void owlqn_pseudo_gradient(
|
||||
lbfgsfloatval_t* pg,
|
||||
const lbfgsfloatval_t* x,
|
||||
@@ -223,7 +224,7 @@ static int round_out_variables(int n)
|
||||
return n;
|
||||
}
|
||||
#endif/*defined(USE_SSE)*/
|
||||
|
||||
// 开辟内存空间
|
||||
lbfgsfloatval_t* lbfgs_malloc(int n)
|
||||
{
|
||||
#if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__))
|
||||
@@ -231,12 +232,12 @@ lbfgsfloatval_t* lbfgs_malloc(int n)
|
||||
#endif/*defined(USE_SSE)*/
|
||||
return (lbfgsfloatval_t*)vecalloc(sizeof(lbfgsfloatval_t) * n);
|
||||
}
|
||||
|
||||
// 释放内存空间
|
||||
void lbfgs_free(lbfgsfloatval_t *x)
|
||||
{
|
||||
vecfree(x);
|
||||
}
|
||||
|
||||
// 重置参数至默认参数
|
||||
void lbfgs_parameter_init(lbfgs_parameter_t *param)
|
||||
{
|
||||
memcpy(param, &_defparam, sizeof(*param));
|
||||
@@ -257,7 +258,9 @@ int lbfgs(
|
||||
lbfgsfloatval_t step;
|
||||
|
||||
/* Constant parameters and their default values. */
|
||||
// 若无输入参数则使用默认参数
|
||||
lbfgs_parameter_t param = (_param != NULL) ? (*_param) : _defparam;
|
||||
// m是计算海森矩阵时储存的前序向量大小
|
||||
const int m = param.m;
|
||||
|
||||
lbfgsfloatval_t *xp = NULL;
|
||||
@@ -268,6 +271,7 @@ int lbfgs(
|
||||
lbfgsfloatval_t xnorm, gnorm, beta;
|
||||
lbfgsfloatval_t fx = 0.;
|
||||
lbfgsfloatval_t rate = 0.;
|
||||
// 设置线性搜索函数为morethuente,此处line_search_morethuente为函数名
|
||||
line_search_proc linesearch = line_search_morethuente;
|
||||
|
||||
/* Construct a callback data. */
|
||||
@@ -334,11 +338,13 @@ int lbfgs(
|
||||
return LBFGSERR_INVALID_ORTHANTWISE_START;
|
||||
}
|
||||
if (param.orthantwise_end < 0) {
|
||||
// 默认设置在每个迭代都计算L1模
|
||||
param.orthantwise_end = n;
|
||||
}
|
||||
if (n < param.orthantwise_end) {
|
||||
return LBFGSERR_INVALID_ORTHANTWISE_END;
|
||||
}
|
||||
// 若|x|的参数不是0,则检查线性搜索方法
|
||||
if (param.orthantwise_c != 0.) {
|
||||
switch (param.linesearch) {
|
||||
case LBFGS_LINESEARCH_BACKTRACKING:
|
||||
@@ -362,7 +368,7 @@ int lbfgs(
|
||||
return LBFGSERR_INVALID_LINESEARCH;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化数组
|
||||
/* Allocate working space. */
|
||||
xp = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
|
||||
g = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
|
||||
@@ -373,7 +379,7 @@ int lbfgs(
|
||||
ret = LBFGSERR_OUTOFMEMORY;
|
||||
goto lbfgs_exit;
|
||||
}
|
||||
|
||||
// 初始化计算L1模的数组
|
||||
if (param.orthantwise_c != 0.) {
|
||||
/* Allocate working space for OW-LQN. */
|
||||
pg = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
|
||||
@@ -382,7 +388,7 @@ int lbfgs(
|
||||
goto lbfgs_exit;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化有限内存方法需要的空间
|
||||
/* Allocate limited memory storage. */
|
||||
lm = (iteration_data_t*)vecalloc(m * sizeof(iteration_data_t));
|
||||
if (lm == NULL) {
|
||||
@@ -392,7 +398,7 @@ int lbfgs(
|
||||
|
||||
/* Initialize the limited memory. */
|
||||
for (i = 0;i < m;++i) {
|
||||
it = &lm[i];
|
||||
it = &lm[i]; // 取it的地址为lm数组中的一个
|
||||
it->alpha = 0;
|
||||
it->ys = 0;
|
||||
it->s = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
|
||||
@@ -407,20 +413,22 @@ int lbfgs(
|
||||
if (0 < param.past) {
|
||||
pf = (lbfgsfloatval_t*)vecalloc(param.past * sizeof(lbfgsfloatval_t));
|
||||
}
|
||||
|
||||
// 到此所有初始化工作完成 下面开始迭代前的初始计算
|
||||
/* Evaluate the function value and its gradient. */
|
||||
fx = cd.proc_evaluate(cd.instance, x, g, cd.n, 0);
|
||||
fx = cd.proc_evaluate(cd.instance, x, g, cd.n, 0); // 步长为0,现在用不了
|
||||
// 若|x|参数不为0 则需要计算x的L1模与似梯度
|
||||
if (0. != param.orthantwise_c) {
|
||||
/* Compute the L1 norm of the variable and add it to the object value. */
|
||||
xnorm = owlqn_x1norm(x, param.orthantwise_start, param.orthantwise_end);
|
||||
fx += xnorm * param.orthantwise_c;
|
||||
fx += xnorm * param.orthantwise_c; // 此时fx为这两部分的和
|
||||
owlqn_pseudo_gradient(
|
||||
pg, x, g, n,
|
||||
param.orthantwise_c, param.orthantwise_start, param.orthantwise_end
|
||||
);
|
||||
); // 计算似梯度
|
||||
}
|
||||
|
||||
/* Store the initial value of the objective function. */
|
||||
// 如果param.past不为0,则pf不为NULL
|
||||
if (pf != NULL) {
|
||||
pf[0] = fx;
|
||||
}
|
||||
@@ -429,22 +437,26 @@ int lbfgs(
|
||||
Compute the direction;
|
||||
we assume the initial hessian matrix H_0 as the identity matrix.
|
||||
*/
|
||||
// 初始下降方向为梯度的反方向
|
||||
if (param.orthantwise_c == 0.) {
|
||||
vecncpy(d, g, n);
|
||||
vecncpy(d, g, n); //拷贝数组 并反号(乘-1)
|
||||
} else {
|
||||
vecncpy(d, pg, n);
|
||||
vecncpy(d, pg, n); //此时需拷贝似梯度 并反号(乘-1)
|
||||
}
|
||||
|
||||
/*
|
||||
Make sure that the initial variables are not a minimizer.
|
||||
*/
|
||||
vec2norm(&xnorm, x, n);
|
||||
vec2norm(&xnorm, x, n); // vec2norm计算数组的L2模长
|
||||
// 此段又要区别对待是否含有L1模的部分
|
||||
if (param.orthantwise_c == 0.) {
|
||||
vec2norm(&gnorm, g, n);
|
||||
} else {
|
||||
vec2norm(&gnorm, pg, n);
|
||||
}
|
||||
// 为啥要保证xnorm大于等于1?不明白
|
||||
if (xnorm < 1.0) xnorm = 1.0;
|
||||
// 如果输入x即为最优化的解 则退出
|
||||
if (gnorm / xnorm <= param.epsilon) {
|
||||
ret = LBFGS_ALREADY_MINIMIZED;
|
||||
goto lbfgs_exit;
|
||||
@@ -453,7 +465,8 @@ int lbfgs(
|
||||
/* Compute the initial step:
|
||||
step = 1.0 / sqrt(vecdot(d, d, n))
|
||||
*/
|
||||
vec2norminv(&step, d, n);
|
||||
// 计算估算的初始步长
|
||||
vec2norminv(&step, d, n); // 计算数组L2模的倒数,与注释的内容等效
|
||||
|
||||
k = 1;
|
||||
end = 0;
|
||||
@@ -472,6 +485,7 @@ int lbfgs(
|
||||
param.orthantwise_c, param.orthantwise_start, param.orthantwise_end
|
||||
);
|
||||
}
|
||||
// 线性搜索错误 此时则退回到上一次迭代的位置并退出
|
||||
if (ls < 0) {
|
||||
/* Revert to the previous point. */
|
||||
veccpy(x, xp, n);
|
||||
@@ -490,7 +504,8 @@ int lbfgs(
|
||||
|
||||
/* Report the progress. */
|
||||
if (cd.proc_progress) {
|
||||
if ((ret = cd.proc_progress(cd.instance, x, g, fx, xnorm, gnorm, step, cd.n, k, ls))) {
|
||||
// 如果监控函数返回值不为0 则退出迭过程
|
||||
if ((ret = cd.proc_progress(cd.instance, x, g, fx, xnorm, gnorm, step, param, cd.n, k, ls))) {
|
||||
goto lbfgs_exit;
|
||||
}
|
||||
}
|
||||
@@ -499,6 +514,9 @@ int lbfgs(
|
||||
Convergence test.
|
||||
The criterion is given by the following formula:
|
||||
|g(x)| / \max(1, |x|) < \epsilon
|
||||
这里稍微解释一下:这个标准的含义是此时的模型梯度模与模型模的比值,这个值在模型变化非常平缓时会很小,一般我们认为此时也就达到了最优。
|
||||
因此如果x的模小于1的话反而会放大模型梯度的模,所以这里默认x的模长大于等于1.0。同样的,可以预见对于求0值的非线性最优化问题,这个标准
|
||||
并不适用,因为目标函数在0值的梯度很可能不是0。
|
||||
*/
|
||||
if (xnorm < 1.0) xnorm = 1.0;
|
||||
if (gnorm / xnorm <= param.epsilon) {
|
||||
@@ -510,7 +528,8 @@ int lbfgs(
|
||||
/*
|
||||
Test for stopping criterion.
|
||||
The criterion is given by the following formula:
|
||||
(f(past_x) - f(x)) / f(x) < \delta
|
||||
|(f(past_x) - f(x))| / f(x) < \delta
|
||||
利用之前的目标函数值与当前目标函数值之差的绝对值与当前函数值的比值来确定是否终止迭代。与前一种判断方式一样,不适合求0的最优化问题。
|
||||
*/
|
||||
if (pf != NULL) {
|
||||
/* We don't test the stopping criterion while k < past. */
|
||||
@@ -519,7 +538,7 @@ int lbfgs(
|
||||
rate = (pf[k % param.past] - fx) / fx;
|
||||
|
||||
/* The stopping criterion. */
|
||||
if (rate < param.delta) {
|
||||
if (fabs(rate) < param.delta) {
|
||||
ret = LBFGS_STOP;
|
||||
break;
|
||||
}
|
||||
@@ -535,13 +554,14 @@ int lbfgs(
|
||||
break;
|
||||
}
|
||||
|
||||
// 以下是L-BFGS算法的核心部分
|
||||
/*
|
||||
Update vectors s and y:
|
||||
s_{k+1} = x_{k+1} - x_{k} = \step * d_{k}.
|
||||
y_{k+1} = g_{k+1} - g_{k}.
|
||||
*/
|
||||
it = &lm[end];
|
||||
vecdiff(it->s, x, xp, n);
|
||||
vecdiff(it->s, x, xp, n); // 计算两个数组的差 it->s = x - xp
|
||||
vecdiff(it->y, g, gp, n);
|
||||
|
||||
/*
|
||||
@@ -550,7 +570,7 @@ int lbfgs(
|
||||
yy = y^t \cdot y.
|
||||
Notice that yy is used for scaling the hessian matrix H_0 (Cholesky factor).
|
||||
*/
|
||||
vecdot(&ys, it->y, it->s, n);
|
||||
vecdot(&ys, it->y, it->s, n); // 计算两个数组的点积
|
||||
vecdot(&yy, it->y, it->y, n);
|
||||
it->ys = ys;
|
||||
|
||||
@@ -569,11 +589,11 @@ int lbfgs(
|
||||
/* Compute the steepest direction. */
|
||||
if (param.orthantwise_c == 0.) {
|
||||
/* Compute the negative of gradients. */
|
||||
vecncpy(d, g, n);
|
||||
vecncpy(d, g, n); // 注意这里有符号的翻转
|
||||
} else {
|
||||
vecncpy(d, pg, n);
|
||||
}
|
||||
|
||||
// 此处开始迭代 利用双重循环计算H^-1*g得到下降方向
|
||||
j = end;
|
||||
for (i = 0;i < bound;++i) {
|
||||
j = (j + m - 1) % m; /* if (--j == -1) j = m-1; */
|
||||
@@ -585,7 +605,7 @@ int lbfgs(
|
||||
vecadd(d, it->y, -it->alpha, n);
|
||||
}
|
||||
|
||||
vecscale(d, ys / yy, n);
|
||||
vecscale(d, ys / yy, n); // 适当缩放d的大小
|
||||
|
||||
for (i = 0;i < bound;++i) {
|
||||
it = &lm[j];
|
||||
@@ -640,8 +660,128 @@ lbfgs_exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 返回一个包含错误信息的字符串
|
||||
*
|
||||
* @param[in] err lbfgs()函数的返回值
|
||||
*
|
||||
* @return 错误信息字符串
|
||||
*/
|
||||
const char* lbfgs_strerror(int err)
|
||||
{
|
||||
switch(err) {
|
||||
case LBFGS_SUCCESS:
|
||||
/* Also handles LBFGS_CONVERGENCE. */
|
||||
return "Success: reached convergence (gtol).";
|
||||
|
||||
case LBFGS_STOP:
|
||||
return "Success: met stopping criteria (ftol).";
|
||||
|
||||
case LBFGS_ALREADY_MINIMIZED:
|
||||
return "The initial variables already minimize the objective function.";
|
||||
|
||||
case LBFGSERR_UNKNOWNERROR:
|
||||
return "Unknown error.";
|
||||
|
||||
case LBFGSERR_LOGICERROR:
|
||||
return "Logic error.";
|
||||
|
||||
case LBFGSERR_OUTOFMEMORY:
|
||||
return "Insufficient memory.";
|
||||
|
||||
case LBFGSERR_CANCELED:
|
||||
return "The minimization process has been canceled.";
|
||||
|
||||
case LBFGSERR_INVALID_N:
|
||||
return "Invalid number of variables specified.";
|
||||
|
||||
case LBFGSERR_INVALID_N_SSE:
|
||||
return "Invalid number of variables (for SSE) specified.";
|
||||
|
||||
case LBFGSERR_INVALID_X_SSE:
|
||||
return "The array x must be aligned to 16 (for SSE).";
|
||||
|
||||
case LBFGSERR_INVALID_EPSILON:
|
||||
return "Invalid parameter lbfgs_parameter_t::epsilon specified.";
|
||||
|
||||
case LBFGSERR_INVALID_TESTPERIOD:
|
||||
return "Invalid parameter lbfgs_parameter_t::past specified.";
|
||||
|
||||
case LBFGSERR_INVALID_DELTA:
|
||||
return "Invalid parameter lbfgs_parameter_t::delta specified.";
|
||||
|
||||
case LBFGSERR_INVALID_LINESEARCH:
|
||||
return "Invalid parameter lbfgs_parameter_t::linesearch specified.";
|
||||
|
||||
case LBFGSERR_INVALID_MINSTEP:
|
||||
return "Invalid parameter lbfgs_parameter_t::max_step specified.";
|
||||
|
||||
case LBFGSERR_INVALID_MAXSTEP:
|
||||
return "Invalid parameter lbfgs_parameter_t::max_step specified.";
|
||||
|
||||
case LBFGSERR_INVALID_FTOL:
|
||||
return "Invalid parameter lbfgs_parameter_t::ftol specified.";
|
||||
|
||||
case LBFGSERR_INVALID_WOLFE:
|
||||
return "Invalid parameter lbfgs_parameter_t::wolfe specified.";
|
||||
|
||||
case LBFGSERR_INVALID_GTOL:
|
||||
return "Invalid parameter lbfgs_parameter_t::gtol specified.";
|
||||
|
||||
case LBFGSERR_INVALID_XTOL:
|
||||
return "Invalid parameter lbfgs_parameter_t::xtol specified.";
|
||||
|
||||
case LBFGSERR_INVALID_MAXLINESEARCH:
|
||||
return "Invalid parameter lbfgs_parameter_t::max_linesearch specified.";
|
||||
|
||||
case LBFGSERR_INVALID_ORTHANTWISE:
|
||||
return "Invalid parameter lbfgs_parameter_t::orthantwise_c specified.";
|
||||
|
||||
case LBFGSERR_INVALID_ORTHANTWISE_START:
|
||||
return "Invalid parameter lbfgs_parameter_t::orthantwise_start specified.";
|
||||
|
||||
case LBFGSERR_INVALID_ORTHANTWISE_END:
|
||||
return "Invalid parameter lbfgs_parameter_t::orthantwise_end specified.";
|
||||
|
||||
case LBFGSERR_OUTOFINTERVAL:
|
||||
return "The line-search step went out of the interval of uncertainty.";
|
||||
|
||||
case LBFGSERR_INCORRECT_TMINMAX:
|
||||
return "A logic error occurred; alternatively, the interval of uncertainty"
|
||||
" became too small.";
|
||||
|
||||
case LBFGSERR_ROUNDING_ERROR:
|
||||
return "A rounding error occurred; alternatively, no line-search step"
|
||||
" satisfies the sufficient decrease and curvature conditions.";
|
||||
|
||||
case LBFGSERR_MINIMUMSTEP:
|
||||
return "The line-search step became smaller than lbfgs_parameter_t::min_step.";
|
||||
|
||||
case LBFGSERR_MAXIMUMSTEP:
|
||||
return "The line-search step became larger than lbfgs_parameter_t::max_step.";
|
||||
|
||||
case LBFGSERR_MAXIMUMLINESEARCH:
|
||||
return "The line-search routine reaches the maximum number of evaluations.";
|
||||
|
||||
case LBFGSERR_MAXIMUMITERATION:
|
||||
return "The algorithm routine reaches the maximum number of iterations.";
|
||||
|
||||
case LBFGSERR_WIDTHTOOSMALL:
|
||||
return "Relative width of the interval of uncertainty is at most"
|
||||
" lbfgs_parameter_t::xtol.";
|
||||
|
||||
case LBFGSERR_INVALIDPARAMETERS:
|
||||
return "A logic error (negative line-search step) occurred.";
|
||||
|
||||
case LBFGSERR_INCREASEGRADIENT:
|
||||
return "The current search direction increases the objective function value.";
|
||||
|
||||
default:
|
||||
return "(unknown)";
|
||||
}
|
||||
}
|
||||
|
||||
// 反向搜索,即根据一个初值时情况增大或减小步长
|
||||
static int line_search_backtracking(
|
||||
int n,
|
||||
lbfgsfloatval_t *x,
|
||||
@@ -667,7 +807,7 @@ static int line_search_backtracking(
|
||||
}
|
||||
|
||||
/* Compute the initial gradient in the search direction. */
|
||||
vecdot(&dginit, g, s, n);
|
||||
vecdot(&dginit, g, s, n); //计算点积 g为梯度方向 s为下降方向
|
||||
|
||||
/* Make sure that s points to a descent direction. */
|
||||
if (0 < dginit) {
|
||||
@@ -676,20 +816,23 @@ static int line_search_backtracking(
|
||||
|
||||
/* The initial value of the objective function. */
|
||||
finit = *f;
|
||||
dgtest = param->ftol * dginit;
|
||||
dgtest = param->ftol * dginit; // ftol 大概为 function tolerance
|
||||
|
||||
for (;;) {
|
||||
veccpy(x, xp, n);
|
||||
vecadd(x, s, *stp, n);
|
||||
vecadd(x, s, *stp, n); // vecadd x += (*stp)*s
|
||||
|
||||
/* Evaluate the function and gradient values. */
|
||||
// 这里我们发现的cd的用法,即传递函数指针
|
||||
*f = cd->proc_evaluate(cd->instance, x, g, cd->n, *stp);
|
||||
|
||||
++count;
|
||||
|
||||
// 充分下降条件
|
||||
if (*f > finit + *stp * dgtest) {
|
||||
width = dec;
|
||||
width = dec; //如果不满充分下降条件则减小步长
|
||||
} else {
|
||||
// 充分下降条件满足并搜索方法为backtracking,搜索条件为Armijo,则可以退出了。否则更新步长,继续搜索。
|
||||
/* The sufficient decrease condition (Armijo condition). */
|
||||
if (param->linesearch == LBFGS_LINESEARCH_BACKTRACKING_ARMIJO) {
|
||||
/* Exit with the Armijo condition. */
|
||||
@@ -697,10 +840,11 @@ static int line_search_backtracking(
|
||||
}
|
||||
|
||||
/* Check the Wolfe condition. */
|
||||
vecdot(&dg, g, s, n);
|
||||
vecdot(&dg, g, s, n); // 验证标准Wolfe条件 需要计算新的梯度信息
|
||||
if (dg < param->wolfe * dginit) {
|
||||
width = inc;
|
||||
width = inc; //注意这里dginit一般是负的,所以在测试Wolfe条件时上式为下限。不满足标准Wolfe条件,增大步长。
|
||||
} else {
|
||||
// 标准Wolfe条件满足,且搜索方法为backtracking,搜索条件为Wolfe,则可以退出了。否则继续测试是否满足Strong Wolfe
|
||||
if(param->linesearch == LBFGS_LINESEARCH_BACKTRACKING_WOLFE) {
|
||||
/* Exit with the regular Wolfe condition. */
|
||||
return count;
|
||||
@@ -708,7 +852,7 @@ static int line_search_backtracking(
|
||||
|
||||
/* Check the strong Wolfe condition. */
|
||||
if(dg > -param->wolfe * dginit) {
|
||||
width = dec;
|
||||
width = dec; //不满足曲率的绝对值条件,减小步长。
|
||||
} else {
|
||||
/* Exit with the strong Wolfe condition. */
|
||||
return count;
|
||||
@@ -716,16 +860,20 @@ static int line_search_backtracking(
|
||||
}
|
||||
}
|
||||
|
||||
// 以下情况返回的步长不能保证满足搜索条件
|
||||
if (*stp < param->min_step) {
|
||||
/* The step is the minimum value. */
|
||||
// 退出 此时步长小于最小步长
|
||||
return LBFGSERR_MINIMUMSTEP;
|
||||
}
|
||||
if (*stp > param->max_step) {
|
||||
/* The step is the maximum value. */
|
||||
// 退出 此时步长大于最大步长
|
||||
return LBFGSERR_MAXIMUMSTEP;
|
||||
}
|
||||
if (param->max_linesearch <= count) {
|
||||
/* Maximum number of iteration. */
|
||||
// 退出 线性搜索次数超过了最大限制
|
||||
return LBFGSERR_MAXIMUMLINESEARCH;
|
||||
}
|
||||
|
||||
@@ -733,8 +881,7 @@ static int line_search_backtracking(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 还是反向搜索 只是添加了L1模方向
|
||||
static int line_search_backtracking_owlqn(
|
||||
int n,
|
||||
lbfgsfloatval_t *x,
|
||||
@@ -744,7 +891,7 @@ static int line_search_backtracking_owlqn(
|
||||
lbfgsfloatval_t *stp,
|
||||
const lbfgsfloatval_t* xp,
|
||||
const lbfgsfloatval_t* gp,
|
||||
lbfgsfloatval_t *wp,
|
||||
lbfgsfloatval_t *wp, // 这个数组只在这个函数内使用
|
||||
callback_data_t *cd,
|
||||
const lbfgs_parameter_t *param
|
||||
)
|
||||
@@ -1294,7 +1441,7 @@ static int update_trial_interval(
|
||||
|
||||
|
||||
|
||||
|
||||
// 计算x的L1模 计算从start到n的绝对值的和
|
||||
static lbfgsfloatval_t owlqn_x1norm(
|
||||
const lbfgsfloatval_t* x,
|
||||
const int start,
|
||||
@@ -29,10 +29,12 @@
|
||||
#ifndef __LBFGS_H__
|
||||
#define __LBFGS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus //c++编译环境中才会定义__cplusplus (plus就是"+"的意思)
|
||||
//作用是让 C++ 编译器将 extern "C" 声明的代码当作 C 语言代码处理,可以避免 C++ 因符号修饰导致代码不能和C语言库中的符号进行链接的问题。
|
||||
extern "C" {
|
||||
#endif/*__cplusplus*/
|
||||
|
||||
// 算法库使用的浮点类型定义
|
||||
/*
|
||||
* The default precision of floating point values is 64bit (double).
|
||||
*/
|
||||
@@ -58,7 +60,8 @@ typedef double lbfgsfloatval_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// 枚举类型 lbfgs()返回值 定义了各种返回值对应的别称
|
||||
// 返回值为负代表错误
|
||||
/**
|
||||
* \addtogroup liblbfgs_api libLBFGS API
|
||||
* @{
|
||||
@@ -75,16 +78,16 @@ enum {
|
||||
/** L-BFGS reaches convergence. */
|
||||
LBFGS_SUCCESS = 0,
|
||||
LBFGS_CONVERGENCE = 0,
|
||||
LBFGS_STOP,
|
||||
LBFGS_STOP, //1
|
||||
/** The initial variables already minimize the objective function. */
|
||||
LBFGS_ALREADY_MINIMIZED,
|
||||
LBFGS_ALREADY_MINIMIZED, //2
|
||||
|
||||
/** Unknown error. */
|
||||
LBFGSERR_UNKNOWNERROR = -1024,
|
||||
/** Logic error. */
|
||||
LBFGSERR_LOGICERROR,
|
||||
LBFGSERR_LOGICERROR, //-1023
|
||||
/** Insufficient memory. */
|
||||
LBFGSERR_OUTOFMEMORY,
|
||||
LBFGSERR_OUTOFMEMORY, //-1022
|
||||
/** The minimization process has been canceled. */
|
||||
LBFGSERR_CANCELED,
|
||||
/** Invalid number of variables specified. */
|
||||
@@ -146,6 +149,11 @@ enum {
|
||||
LBFGSERR_INCREASEGRADIENT,
|
||||
};
|
||||
|
||||
// 枚举类型 线性搜索方法
|
||||
// 0 MoreThuente方法
|
||||
// 1 Armijo条件方法
|
||||
// 2 标准Wolfe条件方法
|
||||
// 3 增强Wolfe条件方法
|
||||
/**
|
||||
* Line search algorithms.
|
||||
*/
|
||||
@@ -190,6 +198,24 @@ enum {
|
||||
LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE = 3,
|
||||
};
|
||||
|
||||
// L-BFGS参数类型。参数很多,简要说明如下:
|
||||
// m L-BFGS算法中储存的前序sk与yk向量个数,这个值控制了算法使用的内存多少,默认值为6(不建议小于3的值),值多大近似精度越高,计算量也越大。
|
||||
// epsilon 迭代的终止精度,默认值为1e-5
|
||||
// past 以delta(不同迭代次数的目标函数值)为基础的迭代终止条件数,past代表了以多少迭代次数之前的目标函数值作为delta计算的间隔,默认值为0,
|
||||
// 即不以delta为迭代终止条件。
|
||||
// delta (f' - f) / f 不同迭代次数时目标函数之差与当前目标函数值之比,但past不为0时会计算。
|
||||
// max_iterations 最大迭代次数
|
||||
// linesearch 线性搜索方式,由此文件上部枚举类型定义。
|
||||
// max_linesearch 每次迭代中线性搜索的最大次数,默认值为40
|
||||
// min_step 线性搜索中的最小步长,默认值为1e-20
|
||||
// max_step 线性搜索中的最大步长,默认值为1e+20
|
||||
// ftol 线性搜索的精度值,默认值为1e-4,取值范围(0-0.5)。
|
||||
// wolfe Wolfe线性搜索中的控制参数,默认值为0.9,大于ftol小于1.0
|
||||
// gtol 线性搜索中的控制参数,默认值为0.9,大于ftol小于1.0
|
||||
// xtol 浮点数精度,默认值为1e-16
|
||||
// orthantwise_c 模型参数x的L1模的乘积参数,默认值为0.0,此时算法即为L2模形式,当此参数大于0时,算法即为OWL-QN
|
||||
// orthantwise_start 开始计算模型参数x的L1模的迭代序号
|
||||
// orthantwise_end 终止计算模型参数x的L1模的迭代序号
|
||||
/**
|
||||
* L-BFGS optimization parameters.
|
||||
* Call lbfgs_parameter_init() function to initialize parameters to the
|
||||
@@ -233,7 +259,7 @@ typedef struct {
|
||||
* (f' - f) / f < \ref delta,
|
||||
* where f' is the objective value of \ref past iterations ago, and f is
|
||||
* the objective value of the current iteration.
|
||||
* The default value is \c 0.
|
||||
* The default value is \c 1e-5.
|
||||
*/
|
||||
lbfgsfloatval_t delta;
|
||||
|
||||
@@ -257,7 +283,7 @@ typedef struct {
|
||||
/**
|
||||
* The maximum number of trials for the line search.
|
||||
* This parameter controls the number of function and gradients evaluations
|
||||
* per iteration for the line search routine. The default value is \c 20.
|
||||
* per iteration for the line search routine. The default value is \c 40.
|
||||
*/
|
||||
int max_linesearch;
|
||||
|
||||
@@ -357,7 +383,13 @@ typedef struct {
|
||||
int orthantwise_end;
|
||||
} lbfgs_parameter_t;
|
||||
|
||||
|
||||
// 目标函数与其梯度值计算的回调函数模版,参数简要说明如下:
|
||||
// instance 运行实例的指针,帮助程序正确定位回调函数在内存中的位置。
|
||||
// x 当前的模型参数值的指针
|
||||
// g 当前模型参数值对应的梯度指针
|
||||
// n 模型参数的数量
|
||||
// step 当前线性搜索所使用的步长
|
||||
// retval 当前模型参数的目标函数值
|
||||
/**
|
||||
* Callback interface to provide objective function and gradient evaluations.
|
||||
*
|
||||
@@ -383,6 +415,18 @@ typedef lbfgsfloatval_t (*lbfgs_evaluate_t)(
|
||||
const lbfgsfloatval_t step
|
||||
);
|
||||
|
||||
// 进程函数的回调函数模版,参数简要说明如下:
|
||||
// instance 运行实例的指针,帮助程序正确定位回调函数在内存中的位置。
|
||||
// x 当前的模型参数值的指针
|
||||
// g 当前模型参数值对应的梯度指针
|
||||
// fx 目标函数的值
|
||||
// xnorm 模型参数数组的L2模长
|
||||
// gnorm 模型梯度数组的L2模长
|
||||
// step 当前线性搜索所使用的步长
|
||||
// n 模型参数的数量
|
||||
// k 迭代的次数
|
||||
// ls 此次迭代所使用的线性搜索次数
|
||||
// retval 返回0则lbfgs()函数继续,否则终止
|
||||
/**
|
||||
* Callback interface to receive the progress of the optimization process.
|
||||
*
|
||||
@@ -397,6 +441,7 @@ typedef lbfgsfloatval_t (*lbfgs_evaluate_t)(
|
||||
* @param xnorm The Euclidean norm of the variables.
|
||||
* @param gnorm The Euclidean norm of the gradients.
|
||||
* @param step The line-search step used for this iteration.
|
||||
* @param param 这是我们添加了一个指针以使用参数类型来监控迭代流程
|
||||
* @param n The number of variables.
|
||||
* @param k The iteration count.
|
||||
* @param ls The number of evaluations called for this iteration.
|
||||
@@ -411,6 +456,7 @@ typedef int (*lbfgs_progress_t)(
|
||||
const lbfgsfloatval_t xnorm,
|
||||
const lbfgsfloatval_t gnorm,
|
||||
const lbfgsfloatval_t step,
|
||||
const lbfgs_parameter_t param,
|
||||
int n,
|
||||
int k,
|
||||
int ls
|
||||
@@ -425,6 +471,11 @@ value, ||G||, etc) and to cancel the iteration process if necessary.
|
||||
Implementation of a progress callback is optional: a user can pass \c NULL if
|
||||
progress notification is not necessary.
|
||||
|
||||
// 这里提出了算法使用中的两个要求
|
||||
// 1. 变量的数量必须是16的倍数
|
||||
// 2. 变量的储存以16对齐
|
||||
// 还不太明白为什么要这么要求。这里需要以后再注解。
|
||||
// 注解:貌似只有使用SEE
|
||||
In addition, a user must preserve two requirements:
|
||||
- The number of variables must be multiples of 16 (this is not 4).
|
||||
- The memory block of variable array ::x must be aligned to 16.
|
||||
@@ -437,6 +488,23 @@ when:
|
||||
In this formula, ||.|| denotes the Euclidean norm.
|
||||
*/
|
||||
|
||||
// 下面是L-BFGS的主函数,各个参数的说明简要翻译如下:
|
||||
// n 数组的长度,也就是待求的模型参数的数量
|
||||
// x 模型参数数组的指针,函数通过指针直接操作模型数组,所以不需要返回计算结果。一开始赋给函数的数组即为
|
||||
// 初始模型,函数结束后即为最优化结果
|
||||
// ptr_fx 目标函数的值的指针,设计成指针可以方便在函数外部监控迭代过程的收敛情况
|
||||
// proc_evaluate 计算目标函数与目标函数相对于模型的导数的函数名称。这个函数在实际使用中需要用户按照
|
||||
// 算法库指定的参数形式自行定义。函数功能即为计算非线性最优化问题的目标函数值与相应的
|
||||
// 模型梯度。L-BFGS将利用这两个量来计算雅各比与近似海森矩阵,进而确定迭代的方向与步长。
|
||||
// proc_progress 接收迭代过程指标参数的函数名称,这个函数的作为即方便用户以自定义的形式为迭代过程进行
|
||||
// 监控或显示。
|
||||
// instance 函数执行时的实例对象,将被proc_evaluate函数与proc_progress函数接收。这个变量的存在
|
||||
// 是由于如果回调函数是类的成员函数时无法直接调用,需要通过定义一个静态的类成员函数作为新的回调函数
|
||||
// 来调用回调函数。但是类内的函数指针调用只能通过实例进行,所以必然需要一个空的指针来指向运行时的实例。
|
||||
// 而这个指针也就一路来到了这里,它的作用就是在运行时帮助程序确定回调函数在内存的位置以保证正确的调用。
|
||||
// param L-BFGS算法参数类型的指针,指向一个包含算法运行需要的参数的结构体。
|
||||
// retval 返回值。无错即为0,非0值代表此文件上部枚举类型中的对应错误。此文件下部定义的错误信息显示即利用此返回值与
|
||||
// 预定义的枚举类型输出相应的错误信息。
|
||||
/**
|
||||
* Start a L-BFGS optimization.
|
||||
*
|
||||
@@ -484,6 +552,8 @@ int lbfgs(
|
||||
lbfgs_parameter_t *param
|
||||
);
|
||||
|
||||
// 将一个参数类型内的全部变量值重置为默认值
|
||||
// 如果害怕参数被自己调乱了可以用这个函数将参数重置
|
||||
/**
|
||||
* Initialize L-BFGS parameters to the default values.
|
||||
*
|
||||
@@ -494,6 +564,7 @@ int lbfgs(
|
||||
*/
|
||||
void lbfgs_parameter_init(lbfgs_parameter_t *param);
|
||||
|
||||
// 开辟浮点类型的数组空间
|
||||
/**
|
||||
* Allocate an array for variables.
|
||||
*
|
||||
@@ -507,6 +578,7 @@ void lbfgs_parameter_init(lbfgs_parameter_t *param);
|
||||
*/
|
||||
lbfgsfloatval_t* lbfgs_malloc(int n);
|
||||
|
||||
// 释放浮点类型的数组空间
|
||||
/**
|
||||
* Free an array of variables.
|
||||
*
|
||||
@@ -515,8 +587,17 @@ lbfgsfloatval_t* lbfgs_malloc(int n);
|
||||
*/
|
||||
void lbfgs_free(lbfgsfloatval_t *x);
|
||||
|
||||
/** @} */
|
||||
// 使用lbfgs()函数的返回值被返回一个包含相应错误信息的字符串。
|
||||
// 锦上添花,不是必要的部分。
|
||||
/**
|
||||
* Get string description of an lbfgs() return code.
|
||||
*
|
||||
* @param err A value returned by lbfgs().
|
||||
*/
|
||||
const char* lbfgs_strerror(int err);
|
||||
|
||||
/** @} */
|
||||
// 这里链接头文件开始位置的声明,保证了整个头文件都会以C的形式被编译
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif/*__cplusplus*/
|
||||
@@ -587,8 +668,6 @@ This library is used by:
|
||||
- <a href="http://www.chokkan.org/software/classias/">Classias: A collection of machine-learning algorithms for classification</a>
|
||||
- <a href="http://www.public.iastate.edu/~gdancik/mlegp/">mlegp: an R package for maximum likelihood estimates for Gaussian processes</a>
|
||||
- <a href="http://infmath.uibk.ac.at/~matthiasf/imaging2/">imaging2: the imaging2 class library</a>
|
||||
- <a href="http://search.cpan.org/~laye/Algorithm-LBFGS-0.16/">Algorithm::LBFGS - Perl extension for L-BFGS</a>
|
||||
- <a href="http://www.cs.kuleuven.be/~bernd/yap-lbfgs/">YAP-LBFGS (an interface to call libLBFGS from YAP Prolog)</a>
|
||||
|
||||
@section download Download
|
||||
|
||||
@@ -598,6 +677,11 @@ This library is used by:
|
||||
libLBFGS is distributed under the term of the
|
||||
<a href="http://opensource.org/licenses/mit-license.php">MIT license</a>.
|
||||
|
||||
@section modules Third-party modules
|
||||
- <a href="http://cran.r-project.org/web/packages/lbfgs/index.html">lbfgs: Limited-memory BFGS Optimization (a wrapper for R)</a> maintained by Antonio Coppola.
|
||||
- <a href="http://search.cpan.org/~laye/Algorithm-LBFGS-0.16/">Algorithm::LBFGS - Perl extension for L-BFGS</a> maintained by Lei Sun.
|
||||
- <a href="http://www.cs.kuleuven.be/~bernd/yap-lbfgs/">YAP-LBFGS (an interface to call libLBFGS from YAP Prolog)</a> maintained by Bernd Gutmann.
|
||||
|
||||
@section changelog History
|
||||
- Version 1.10 (2010-12-22):
|
||||
- Fixed compiling errors on Mac OS X; this patch was kindly submitted by
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <lbfgs.h>
|
||||
#include "../lib/lbfgs.h"
|
||||
|
||||
static lbfgsfloatval_t evaluate(
|
||||
void *instance,
|
||||
@@ -30,6 +30,7 @@ static int progress(
|
||||
const lbfgsfloatval_t xnorm,
|
||||
const lbfgsfloatval_t gnorm,
|
||||
const lbfgsfloatval_t step,
|
||||
const lbfgs_parameter_t param,
|
||||
int n,
|
||||
int k,
|
||||
int ls
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <lbfgs.h>
|
||||
#include "../lib/lbfgs.h"
|
||||
|
||||
class objective_function
|
||||
{
|
||||
@@ -87,12 +87,13 @@ protected:
|
||||
const lbfgsfloatval_t xnorm,
|
||||
const lbfgsfloatval_t gnorm,
|
||||
const lbfgsfloatval_t step,
|
||||
const lbfgs_parameter_t param,
|
||||
int n,
|
||||
int k,
|
||||
int ls
|
||||
)
|
||||
{
|
||||
return reinterpret_cast<objective_function*>(instance)->progress(x, g, fx, xnorm, gnorm, step, n, k, ls);
|
||||
return reinterpret_cast<objective_function*>(instance)->progress(x, g, fx, xnorm, gnorm, step, param, n, k, ls);
|
||||
}
|
||||
|
||||
int progress(
|
||||
@@ -102,6 +103,7 @@ protected:
|
||||
const lbfgsfloatval_t xnorm,
|
||||
const lbfgsfloatval_t gnorm,
|
||||
const lbfgsfloatval_t step,
|
||||
const lbfgs_parameter_t param,
|
||||
int n,
|
||||
int k,
|
||||
int ls
|
||||
@@ -119,7 +121,7 @@ protected:
|
||||
|
||||
#define N 100
|
||||
|
||||
int main(int argc, char *argv)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
objective_function obj;
|
||||
return obj.run(N);
|
||||
102
src/sample/sample3.cpp
Normal file
102
src/sample/sample3.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "iostream"
|
||||
#include "cmath"
|
||||
#include "../lib/lbfgs.h"
|
||||
|
||||
using std::clog;
|
||||
using std::endl;
|
||||
|
||||
class TEST_FUNC
|
||||
{
|
||||
public:
|
||||
TEST_FUNC();
|
||||
~TEST_FUNC();
|
||||
static lbfgsfloatval_t _Func(void *instance, const lbfgsfloatval_t *x, lbfgsfloatval_t *g,
|
||||
const int n, const lbfgsfloatval_t step)
|
||||
{
|
||||
return reinterpret_cast<TEST_FUNC*>(instance)->Func(x, g, n, step);
|
||||
}
|
||||
|
||||
lbfgsfloatval_t Func(const lbfgsfloatval_t *x, lbfgsfloatval_t *g,
|
||||
const int n, const lbfgsfloatval_t step);
|
||||
|
||||
static int _Progress(void *instance, const lbfgsfloatval_t *x, const lbfgsfloatval_t *g, const lbfgsfloatval_t fx,
|
||||
const lbfgsfloatval_t xnorm, const lbfgsfloatval_t gnorm, const lbfgsfloatval_t step, const lbfgs_parameter_t param,
|
||||
int n, int k, int ls)
|
||||
{
|
||||
return reinterpret_cast<TEST_FUNC*>(instance)->Progress(x, g, fx, xnorm, gnorm, step, param, n, k, ls);
|
||||
}
|
||||
|
||||
int Progress(const lbfgsfloatval_t *x, const lbfgsfloatval_t *g, const lbfgsfloatval_t fx,
|
||||
const lbfgsfloatval_t xnorm, const lbfgsfloatval_t gnorm, const lbfgsfloatval_t step, const lbfgs_parameter_t param,
|
||||
int n, int k, int ls);
|
||||
|
||||
int Routine();
|
||||
private:
|
||||
lbfgsfloatval_t *m_x;
|
||||
};
|
||||
|
||||
TEST_FUNC::TEST_FUNC()
|
||||
{
|
||||
m_x = NULL;
|
||||
m_x = lbfgs_malloc(3);
|
||||
m_x[0] = m_x[1] = m_x[2] = 0.0;
|
||||
}
|
||||
|
||||
TEST_FUNC::~TEST_FUNC()
|
||||
{
|
||||
if (m_x != NULL) lbfgs_free(m_x);
|
||||
}
|
||||
|
||||
// test functions
|
||||
// 3 = 3*x1 + x2 + 2*x3*x3
|
||||
// 1 = -3*x1 + 5*x2*x2 + 2*x1*x3
|
||||
// -12 = 25*x1*x2 + 20*x3
|
||||
lbfgsfloatval_t TEST_FUNC::Func(const lbfgsfloatval_t *x, lbfgsfloatval_t *g,
|
||||
const int n, const lbfgsfloatval_t step)
|
||||
{
|
||||
double f0,f1,f2,temp;
|
||||
f0 = 3*x[0] + x[1] + 2*x[2]*x[2] - 3.012; //这里添加一点噪声
|
||||
f1 = -3*x[0] + 5*x[1]*x[1] + 2*x[0]*x[2] - 1.0521;
|
||||
f2 = 25*x[0]*x[1] + 20*x[2] + 12.10231;
|
||||
temp = sqrt(f0*f0+f1*f1+f2*f2);
|
||||
|
||||
g[0] = 0.5*(6*f0+2*f1*(2*x[2]-3)+50*f2*x[1])/temp;
|
||||
g[1] = 0.5*(2*f0+20*f1*x[1]+50*f2*x[0])/temp;
|
||||
g[2] = 0.5*(8*f0*x[2]+4*f1*x[0]+40*f2)/temp;
|
||||
return temp;
|
||||
}
|
||||
|
||||
int TEST_FUNC::Progress(const lbfgsfloatval_t *x, const lbfgsfloatval_t *g, const lbfgsfloatval_t fx,
|
||||
const lbfgsfloatval_t xnorm, const lbfgsfloatval_t gnorm, const lbfgsfloatval_t step, const lbfgs_parameter_t param,
|
||||
int n, int k, int ls)
|
||||
{
|
||||
clog << "iteration times: " << k << " fx = " << fx << " gnorm/xnorm = " << gnorm/xnorm << endl;
|
||||
clog << x[0] << " " << x[1] << " " << x[2] << endl;
|
||||
|
||||
if (fx < 1e-10) return 1; //这里我们设置一个方程组的整体目标函数值作为终止条件 因为此方程组在0值处梯度不为0 无法使用梯度条件
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TEST_FUNC::Routine()
|
||||
{
|
||||
lbfgsfloatval_t fx;
|
||||
|
||||
lbfgs_parameter_t self_para;
|
||||
lbfgs_parameter_init(&self_para);
|
||||
//self_para.min_step = 1e-30;
|
||||
//self_para.max_linesearch = 40;
|
||||
//self_para.linesearch = LBFGS_LINESEARCH_BACKTRACKING_WOLFE;
|
||||
|
||||
int ret = lbfgs(3, m_x, &fx, _Func, _Progress, this, &self_para);
|
||||
|
||||
clog << "L-BFGS optimization terminated with status: " << endl << lbfgs_strerror(ret) << endl;
|
||||
clog << m_x[0] << " " << m_x[1] << " " << m_x[2] << endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
TEST_FUNC test;
|
||||
test.Routine();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user