27 Commits

Author SHA1 Message Date
0084765d0b update to v1.1.0 2020-06-15 17:43:23 +08:00
91f332cac1 Update CMakeLists.txt
change version number to 1.1
2019-11-06 11:03:14 +08:00
pi
d2904f3379 更新progress回调函数
增加了lbfgs_parameter_t参数以监控反演进度
2019-11-04 12:51:37 +08:00
pi
1f5145a580 Update lbfgs.c 2019-10-22 16:13:15 +08:00
38c0f38d72 Update sample3.cpp 2019-10-22 10:52:04 +08:00
cb3d271071 add a new example 2019-10-22 10:25:55 +08:00
bcafb30f35 编译成功 2019-10-21 22:40:08 +08:00
4076f6803a Update CMakeLists.txt 2019-10-21 22:30:24 +08:00
bbc63f3e25 edit CMakeLists.txt 2019-10-21 22:29:26 +08:00
fb98a740ea 自己编译 2019-10-21 22:24:25 +08:00
462d3121ee 添加注释 2019-10-21 22:09:44 +08:00
d3ebea8582 添加中文注释 2019-10-19 23:09:30 +08:00
Jey Kottalam
7fc787678e Add lbfgs_strerror(). 2019-07-03 20:04:47 +09:00
Sangwhan Moon
3b35fa16dc Update documentation for default value of delta.
This matches the documentation to the actual code level default.
Resolves #19.
2019-06-04 22:20:36 +09:00
Giulio Paci
2cee127280 Improvements to the build system (#25)
* Renamed configure.in into configure.ac.

* Modernized configure.ac.

* Added '-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
2019-06-04 21:04:56 +09:00
Andreas Schuh
e4f94fabd2 Enable build configuration with CMake (#18)
* add: CMake configuration files

* doc: Variables affecting CMake configuration installation

* fix: Rename CMake module and project -> subproject macro

The problem is that macro/function definitions in CMake have global scope. Therefore, use a custom macro name rather than replacing the standard CMake command.

* enh: Set LibLBFGS_LIBRARIES variable in LibLBFGSConfig.cmake

For (older) libLBFGS installations that do not contain the CMake package configuration file, a FindLibLBFGS.cmake module will be needed which then sets LibLBFGS_LIBRARIES to the path of the actual library file instead of an imported CMake build target.

* doc: Update CMakeLists.txt comment

* fix: Do not inherit CMake options from parent project

The parent project must explicitly set ${PROJECT_NAME}_${varname} before including the subproject to the value of the same named parent option ${varname} if super- and sub-project should both use the same value.

* fix: Export of targets as part of parent project

* fix: Do not import targets when liblbfgs TARGET exists

* enh: Prefix Subproject module functions, use unique target names and non-imported target ALIAS

* enh: Remove check if PROJECT_NAME is defined

* fix: Update documentation of CMakeLists.txt

* enh: Document LBFGS_INSTALL_HEADERS
2019-06-04 21:04:00 +09:00
Sangwhan "fish" Moon
6aa4a77c99 Merge pull request #22 from mikhailkin/patch-1
Bug was fixed in delta criterion
2019-06-04 20:53:00 +09:00
Sangwhan "fish" Moon
2fc13c1ac5 Merge pull request #9 from dkogan/upstream
The comment describing the default max_linesearch value now matches the ...
2019-06-04 20:37:56 +09:00
Sangwhan Moon
7777580e1e Add missing details in build instructions.
Resolves #3 and #8.
2019-06-04 20:32:03 +09:00
Sangwhan "fish" Moon
23b8bddc92 Merge pull request #2 from sseemayer/master
Add .gitignore
2019-06-04 20:27:57 +09:00
Kostyukov
c16297a59e Bug was fixed in delta criterion
Delta criterion didn't work properly. Please, consider fix to add
2017-06-02 14:59:56 +03:00
Naoaki Okazaki
57678b188a Upgraded to MSVC 2015. 2016-01-25 17:41:23 +09:00
Naoaki Okazaki
b2a54a9812 - Added a link to a R wrapper (contributed by Antonio Coppola)
- Updated the web site.
2014-09-02 11:39:32 +09:00
Dima Kogan
31ef1e8ea0 The comment describing the default max_linesearch value now matches the code
The code set it to 40, but the comment said 20. The comment now matches the code
2014-01-18 12:36:07 -08:00
Stefan Seemayer
2e414afe81 Add gitignore 2013-02-26 18:15:09 +01:00
Naoaki Okazaki
fb51be30d4 Merge pull request #1 from lucastheis/master
Merged the pull request from lucastheis to fix compiling problem with single precision (float) and SSE.
2013-02-14 23:22:07 -08:00
Lucas Theis
d83800b05c Minor fix. 2012-12-22 16:26:45 +01:00
29 changed files with 511 additions and 2160 deletions

25
.gitignore vendored Normal file
View 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

View File

@@ -1 +0,0 @@
Naoaki Okazaki <okazaki at chokkan org>

20
CMakeLists.txt Normal file
View 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
View File

@@ -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
View File

@@ -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.

View File

@@ -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

0
NEWS
View File

8
README
View File

@@ -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.

View File

@@ -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
View File

@@ -0,0 +1,3 @@
#cmakedefine HAVE_CONFIG_H
#cmakedefine _MSC_VER
#cmakedefine USE_SSE

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
<hr/>
<div>
Copyright (c) 2002-2010 by Naoaki Okazaki
<br /><i>$datetime</i>
</div>
</body>
</html>

View File

@@ -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>

View File

@@ -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

View File

@@ -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@

View File

@@ -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>

View File

@@ -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@

View File

@@ -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
View 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)

View File

@@ -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
View File

@@ -0,0 +1,3 @@
#define HAVE_CONFIG_H
/* #undef _MSC_VER */
/* #undef USE_SSE */

View File

@@ -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.00线
00
*/
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,

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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;
}