<commit_before>//===- gccld.cpp - LLVM 'ld' compatible linker ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility is intended to be compatible with GCC, and follows standard
// system 'ld' conventions.  As such, the default output file is ./a.out.
// Additionally, this program outputs a shell script that is used to invoke LLI
// to execute the program.  In this manner, the generated executable (a.out for
// example), is directly executable, whereas the bytecode file actually lives in
// the a.out.bc file generated by this program.  Also, Force is on by default.
//
// Note that if someone (or a script) deletes the executable program generated,
// the .bc file will be left around.  Considering that this is a temporary hack,
// I'm not too worried about this.
//
//===----------------------------------------------------------------------===//

#include "gccld.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Linker.h"
#include "Support/CommandLine.h"
#include "Support/FileUtilities.h"
#include "Support/Signals.h"
#include "Support/SystemUtils.h"
#include <fstream>
#include <memory>

namespace {
  cl::list<std::string>
  InputFilenames(cl::Positional, cl::desc("<input bytecode files>"),
                 cl::OneOrMore);

  cl::opt<std::string>
  OutputFilename("o", cl::desc("Override output filename"), cl::init("a.out"),
                 cl::value_desc("filename"));

  cl::opt<bool>
  Verbose("v", cl::desc("Print information about actions taken"));

  cl::list<std::string>
  LibPaths("L", cl::desc("Specify a library search path"), cl::Prefix,
           cl::value_desc("directory"));

  cl::list<std::string>
  Libraries("l", cl::desc("Specify libraries to link to"), cl::Prefix,
            cl::value_desc("library prefix"));

  cl::opt<bool>
  Strip("s", cl::desc("Strip symbol info from executable"));

  cl::opt<bool>
  NoInternalize("disable-internalize",
                cl::desc("Do not mark all symbols as internal"));
  static cl::alias
  ExportDynamic("export-dynamic", cl::desc("Alias for -disable-internalize"),
                cl::aliasopt(NoInternalize));

  cl::opt<bool>
  LinkAsLibrary("link-as-library", cl::desc("Link the .bc files together as a"
                                            " library, not an executable"));

  cl::opt<bool>
  Native("native",
         cl::desc("Generate a native binary instead of a shell script"));

  // Compatibility options that are ignored but supported by LD
  cl::opt<std::string>
  CO3("soname", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<std::string>
  CO4("version-script", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<bool>
  CO5("eh-frame-hdr", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<bool>
  CO6("r", cl::Hidden, cl::desc("Compatibility option: ignored"));
}

//
// Function: PrintAndReturn ()
//
// Description:
//  Prints a message (usually error message) to standard error (stderr) and
//  returns a value usable for an exit status.
//
// Inputs:
//  progname - The name of the program (i.e. argv[0]).
//  Message  - The message to print to standard error.
//  Extra    - Extra information to print between the program name and thei
//             message.  It is optional.
//
// Outputs:
//  None.
//
// Return value:
//  Returns a value that can be used as the exit status (i.e. for exit()).
//
int
PrintAndReturn (const char *progname,
                const std::string &Message,
                const std::string &Extra)
{
  std::cerr << progname << Extra << ": " << Message << "\n";
  return 1;
}

//
//
// Function: CopyEnv()
//
// Description:
//	This function takes an array of environment variables and makes a
//	copy of it.  This copy can then be manipulated any way the caller likes
//  without affecting the process's real environment.
//
// Inputs:
//  envp - An array of C strings containing an environment.
//
// Outputs:
//  None.
//
// Return value:
//  NULL - An error occurred.
//
//  Otherwise, a pointer to a new array of C strings is returned.  Every string
//  in the array is a duplicate of the one in the original array (i.e. we do
//  not copy the char *'s from one array to another).
//
char ** CopyEnv(char ** const envp) {
  // Count the number of entries in the old list;
  unsigned entries;   // The number of entries in the old environment list
  for (entries = 0; envp[entries] != NULL; entries++)
  {
    ;
  }

  // Add one more entry for the NULL pointer that ends the list.
  ++entries;

  // If there are no entries at all, just return NULL.
  if (entries == 0)
    return NULL;

  // Allocate a new environment list.
  char **newenv;
  if ((newenv = new (char *) [entries]) == NULL)
    return NULL;

  // Make a copy of the list.  Don't forget the NULL that ends the list.
  entries = 0;
  while (envp[entries] != NULL) {
    newenv[entries] = new char[strlen (envp[entries]) + 1];
    strcpy (newenv[entries], envp[entries]);
    ++entries;
  }
  newenv[entries] = NULL;

  return newenv;
}

//
// Function: RemoveEnv()
//
// Description:
//	Remove the specified environment variable from the environment array.
//
// Inputs:
//	name - The name of the variable to remove.  It cannot be NULL.
//	envp - The array of environment variables.  It cannot be NULL.
//
// Outputs:
//	envp - The pointer to the specified variable name is removed.
//
// Return value:
//	None.
//
// Notes:
//  This is mainly done because functions to remove items from the environment
//  are not available across all platforms.  In particular, Solaris does not
//  seem to have an unsetenv() function or a setenv() function (or they are
//  undocumented if they do exist).
//
void RemoveEnv(const char * name, char ** const envp) {
  for (unsigned index=0; envp[index] != NULL; index++) {
    // Find the first equals sign in the array and make it an EOS character.
    char *p = strchr (envp[index], '=');
    if (p == NULL)
      continue;
    else
      *p = '\0';

    // Compare the two strings.  If they are equal, zap this string.
    // Otherwise, restore it.
    if (!strcmp(name, envp[index]))
      *envp[index] = '\0';
    else
      *p = '=';
  }

  return;
}

int main(int argc, char **argv, char **envp) {
  cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n");

  std::string ErrorMessage;
  std::auto_ptr<Module> Composite(LoadObject(InputFilenames[0], ErrorMessage));
  if (Composite.get() == 0)
    return PrintAndReturn(argv[0], ErrorMessage);

  // We always look first in the current directory when searching for libraries.
  LibPaths.insert(LibPaths.begin(), ".");

  // If the user specified an extra search path in their environment, respect
  // it.
  if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
    LibPaths.push_back(SearchPath);

  // Remove any consecutive duplicates of the same library...
  Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
                  Libraries.end());

  // Link in all of the files
  if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
    return 1; // Error already printed

  if (!LinkAsLibrary)
    LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths,
                  Verbose, Native);

  // Link in all of the libraries next...

  // Create the output file.
  std::string RealBytecodeOutput = OutputFilename;
  if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
  std::ofstream Out(RealBytecodeOutput.c_str());
  if (!Out.good())
    return PrintAndReturn(argv[0], "error opening '" + RealBytecodeOutput +
                                   "' for writing!");

  // Ensure that the bytecode file gets removed from the disk if we get a
  // SIGINT signal.
  RemoveFileOnSignal(RealBytecodeOutput);

  // Generate the bytecode file.
  if (GenerateBytecode(Composite.get(), Strip, !NoInternalize, &Out)) {
    Out.close();
    return PrintAndReturn(argv[0], "error generating bytcode");
  }

  // Close the bytecode file.
  Out.close();

  // If we are not linking a library, generate either a native executable
  // or a JIT shell script, depending upon what the user wants.
  if (!LinkAsLibrary) {
    // If the user wants to generate a native executable, compile it from the
    // bytecode file.
    //
    // Otherwise, create a script that will run the bytecode through the JIT.
    if (Native) {
      // Name of the Assembly Language output file
      std::string AssemblyFile = OutputFilename + ".s";

      // Mark the output files for removal if we get an interrupt.
      RemoveFileOnSignal(AssemblyFile);
      RemoveFileOnSignal(OutputFilename);

      // Determine the locations of the llc and gcc programs.
      std::string llc = FindExecutable("llc", argv[0]);
      std::string gcc = FindExecutable("gcc", argv[0]);
      if (llc.empty())
        return PrintAndReturn(argv[0], "Failed to find llc");

      if (gcc.empty())
        return PrintAndReturn(argv[0], "Failed to find gcc");

      // Generate an assembly language file for the bytecode.
      if (Verbose) std::cout << "Generating Assembly Code\n";
      GenerateAssembly(AssemblyFile, RealBytecodeOutput, llc, envp);
      if (Verbose) std::cout << "Generating Native Code\n";
      GenerateNative(OutputFilename, AssemblyFile, Libraries, LibPaths,
                     gcc, envp);

      // Remove the assembly language file.
      removeFile (AssemblyFile);
    } else {
      // Output the script to start the program...
      std::ofstream Out2(OutputFilename.c_str());
      if (!Out2.good())
        return PrintAndReturn(argv[0], "error opening '" + OutputFilename +
                                       "' for writing!");
      Out2 << "#!/bin/sh\nlli $0.bc $*\n";
      Out2.close();
    }

    // Make the script executable...
    MakeFileExecutable(OutputFilename);

    // Make the bytecode file readable and directly executable in LLEE as well
    MakeFileExecutable(RealBytecodeOutput);
    MakeFileReadable(RealBytecodeOutput);
  }

  return 0;
}
<commit_msg>Make -r work, fixing PR 91<commit_after>//===- gccld.cpp - LLVM 'ld' compatible linker ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility is intended to be compatible with GCC, and follows standard
// system 'ld' conventions.  As such, the default output file is ./a.out.
// Additionally, this program outputs a shell script that is used to invoke LLI
// to execute the program.  In this manner, the generated executable (a.out for
// example), is directly executable, whereas the bytecode file actually lives in
// the a.out.bc file generated by this program.  Also, Force is on by default.
//
// Note that if someone (or a script) deletes the executable program generated,
// the .bc file will be left around.  Considering that this is a temporary hack,
// I'm not too worried about this.
//
//===----------------------------------------------------------------------===//

#include "gccld.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Linker.h"
#include "Support/CommandLine.h"
#include "Support/FileUtilities.h"
#include "Support/Signals.h"
#include "Support/SystemUtils.h"
#include <fstream>
#include <memory>

namespace {
  cl::list<std::string>
  InputFilenames(cl::Positional, cl::desc("<input bytecode files>"),
                 cl::OneOrMore);

  cl::opt<std::string>
  OutputFilename("o", cl::desc("Override output filename"), cl::init("a.out"),
                 cl::value_desc("filename"));

  cl::opt<bool>
  Verbose("v", cl::desc("Print information about actions taken"));

  cl::list<std::string>
  LibPaths("L", cl::desc("Specify a library search path"), cl::Prefix,
           cl::value_desc("directory"));

  cl::list<std::string>
  Libraries("l", cl::desc("Specify libraries to link to"), cl::Prefix,
            cl::value_desc("library prefix"));

  cl::opt<bool>
  Strip("s", cl::desc("Strip symbol info from executable"));

  cl::opt<bool>
  NoInternalize("disable-internalize",
                cl::desc("Do not mark all symbols as internal"));
  cl::alias
  ExportDynamic("export-dynamic", cl::desc("Alias for -disable-internalize"),
                cl::aliasopt(NoInternalize));

  cl::opt<bool>
  LinkAsLibrary("link-as-library", cl::desc("Link the .bc files together as a"
                                            " library, not an executable"));
  cl::alias
  Relink("r", cl::desc("Alias for -link-as-library"),
         cl::aliasopt(LinkAsLibrary));

  cl::opt<bool>
  Native("native",
         cl::desc("Generate a native binary instead of a shell script"));

  // Compatibility options that are ignored but supported by LD
  cl::opt<std::string>
  CO3("soname", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<std::string>
  CO4("version-script", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<bool>
  CO5("eh-frame-hdr", cl::Hidden, cl::desc("Compatibility option: ignored"));
}

//
// Function: PrintAndReturn ()
//
// Description:
//  Prints a message (usually error message) to standard error (stderr) and
//  returns a value usable for an exit status.
//
// Inputs:
//  progname - The name of the program (i.e. argv[0]).
//  Message  - The message to print to standard error.
//  Extra    - Extra information to print between the program name and thei
//             message.  It is optional.
//
// Outputs:
//  None.
//
// Return value:
//  Returns a value that can be used as the exit status (i.e. for exit()).
//
int
PrintAndReturn (const char *progname,
                const std::string &Message,
                const std::string &Extra)
{
  std::cerr << progname << Extra << ": " << Message << "\n";
  return 1;
}

//
//
// Function: CopyEnv()
//
// Description:
//	This function takes an array of environment variables and makes a
//	copy of it.  This copy can then be manipulated any way the caller likes
//  without affecting the process's real environment.
//
// Inputs:
//  envp - An array of C strings containing an environment.
//
// Outputs:
//  None.
//
// Return value:
//  NULL - An error occurred.
//
//  Otherwise, a pointer to a new array of C strings is returned.  Every string
//  in the array is a duplicate of the one in the original array (i.e. we do
//  not copy the char *'s from one array to another).
//
char ** CopyEnv(char ** const envp) {
  // Count the number of entries in the old list;
  unsigned entries;   // The number of entries in the old environment list
  for (entries = 0; envp[entries] != NULL; entries++)
  {
    ;
  }

  // Add one more entry for the NULL pointer that ends the list.
  ++entries;

  // If there are no entries at all, just return NULL.
  if (entries == 0)
    return NULL;

  // Allocate a new environment list.
  char **newenv;
  if ((newenv = new (char *) [entries]) == NULL)
    return NULL;

  // Make a copy of the list.  Don't forget the NULL that ends the list.
  entries = 0;
  while (envp[entries] != NULL) {
    newenv[entries] = new char[strlen (envp[entries]) + 1];
    strcpy (newenv[entries], envp[entries]);
    ++entries;
  }
  newenv[entries] = NULL;

  return newenv;
}

//
// Function: RemoveEnv()
//
// Description:
//	Remove the specified environment variable from the environment array.
//
// Inputs:
//	name - The name of the variable to remove.  It cannot be NULL.
//	envp - The array of environment variables.  It cannot be NULL.
//
// Outputs:
//	envp - The pointer to the specified variable name is removed.
//
// Return value:
//	None.
//
// Notes:
//  This is mainly done because functions to remove items from the environment
//  are not available across all platforms.  In particular, Solaris does not
//  seem to have an unsetenv() function or a setenv() function (or they are
//  undocumented if they do exist).
//
void RemoveEnv(const char * name, char ** const envp) {
  for (unsigned index=0; envp[index] != NULL; index++) {
    // Find the first equals sign in the array and make it an EOS character.
    char *p = strchr (envp[index], '=');
    if (p == NULL)
      continue;
    else
      *p = '\0';

    // Compare the two strings.  If they are equal, zap this string.
    // Otherwise, restore it.
    if (!strcmp(name, envp[index]))
      *envp[index] = '\0';
    else
      *p = '=';
  }

  return;
}

int main(int argc, char **argv, char **envp) {
  cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n");

  std::string ErrorMessage;
  std::auto_ptr<Module> Composite(LoadObject(InputFilenames[0], ErrorMessage));
  if (Composite.get() == 0)
    return PrintAndReturn(argv[0], ErrorMessage);

  // We always look first in the current directory when searching for libraries.
  LibPaths.insert(LibPaths.begin(), ".");

  // If the user specified an extra search path in their environment, respect
  // it.
  if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
    LibPaths.push_back(SearchPath);

  // Remove any consecutive duplicates of the same library...
  Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
                  Libraries.end());

  // Link in all of the files
  if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
    return 1; // Error already printed

  if (!LinkAsLibrary)
    LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths,
                  Verbose, Native);

  // Link in all of the libraries next...

  // Create the output file.
  std::string RealBytecodeOutput = OutputFilename;
  if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
  std::ofstream Out(RealBytecodeOutput.c_str());
  if (!Out.good())
    return PrintAndReturn(argv[0], "error opening '" + RealBytecodeOutput +
                                   "' for writing!");

  // Ensure that the bytecode file gets removed from the disk if we get a
  // SIGINT signal.
  RemoveFileOnSignal(RealBytecodeOutput);

  // Generate the bytecode file.
  if (GenerateBytecode(Composite.get(), Strip, !NoInternalize, &Out)) {
    Out.close();
    return PrintAndReturn(argv[0], "error generating bytcode");
  }

  // Close the bytecode file.
  Out.close();

  // If we are not linking a library, generate either a native executable
  // or a JIT shell script, depending upon what the user wants.
  if (!LinkAsLibrary) {
    // If the user wants to generate a native executable, compile it from the
    // bytecode file.
    //
    // Otherwise, create a script that will run the bytecode through the JIT.
    if (Native) {
      // Name of the Assembly Language output file
      std::string AssemblyFile = OutputFilename + ".s";

      // Mark the output files for removal if we get an interrupt.
      RemoveFileOnSignal(AssemblyFile);
      RemoveFileOnSignal(OutputFilename);

      // Determine the locations of the llc and gcc programs.
      std::string llc = FindExecutable("llc", argv[0]);
      std::string gcc = FindExecutable("gcc", argv[0]);
      if (llc.empty())
        return PrintAndReturn(argv[0], "Failed to find llc");

      if (gcc.empty())
        return PrintAndReturn(argv[0], "Failed to find gcc");

      // Generate an assembly language file for the bytecode.
      if (Verbose) std::cout << "Generating Assembly Code\n";
      GenerateAssembly(AssemblyFile, RealBytecodeOutput, llc, envp);
      if (Verbose) std::cout << "Generating Native Code\n";
      GenerateNative(OutputFilename, AssemblyFile, Libraries, LibPaths,
                     gcc, envp);

      // Remove the assembly language file.
      removeFile (AssemblyFile);
    } else {
      // Output the script to start the program...
      std::ofstream Out2(OutputFilename.c_str());
      if (!Out2.good())
        return PrintAndReturn(argv[0], "error opening '" + OutputFilename +
                                       "' for writing!");
      Out2 << "#!/bin/sh\nlli $0.bc $*\n";
      Out2.close();
    }

    // Make the script executable...
    MakeFileExecutable(OutputFilename);

    // Make the bytecode file readable and directly executable in LLEE as well
    MakeFileExecutable(RealBytecodeOutput);
    MakeFileReadable(RealBytecodeOutput);
  }

  return 0;
}
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#include "condor_common.h"
#include "matchmaker.h"

// for daemon core
char *mySubSystem = "NEGOTIATOR";

// the matchmaker object
Matchmaker matchMaker;

int main_init (int, char *[])
{
	// read in params
	matchMaker.initialize ();
	return TRUE;
}

int main_shutdown_graceful()
{
	matchMaker.invalidateNegotiatorAd();
	DC_Exit(0);
	return 0;
}

int main_shutdown_fast()
{
	DC_Exit(0);
	return 0;
}

int
main_config( bool /* is_full */ )
{
	return (matchMaker.reinitialize ());
}

void
main_pre_dc_init( int /* argc */, char** /* argv */ )
{
}

void
main_pre_command_sock_init( )
{
}

<commit_msg>Windows doesn't think char** and char*[] are equivalent when declaring the type of the function's arguments.<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#include "condor_common.h"
#include "matchmaker.h"

// for daemon core
char *mySubSystem = "NEGOTIATOR";

// the matchmaker object
Matchmaker matchMaker;

int main_init (int, char *[])
{
	// read in params
	matchMaker.initialize ();
	return TRUE;
}

int main_shutdown_graceful()
{
	matchMaker.invalidateNegotiatorAd();
	DC_Exit(0);
	return 0;
}

int main_shutdown_fast()
{
	DC_Exit(0);
	return 0;
}

int
main_config( bool /* is_full */ )
{
	return (matchMaker.reinitialize ());
}

void
main_pre_dc_init( int /* argc */, char*[] /* argv */ )
{
}

void
main_pre_command_sock_init( )
{
}

<|endoftext|>


<commit_before>#ifndef NANOCV_OPTIMIZE_OPTIMIZER_HPP
#define NANOCV_OPTIMIZE_OPTIMIZER_HPP

#include "core/optimize/result.hpp"
#include "core/optimize/problem.hpp"
#include <type_traits>
#include <deque>

namespace ncv
{
        namespace optimize
        {
                /////////////////////////////////////////////////////////////////////////////////////////
                // optimization methods (GD, CGD, LBFGS) starting from the initial value (guess) x0.
                /////////////////////////////////////////////////////////////////////////////////////////

                template
                <
                        typename tscalar,
                        typename tsize,
                        typename top_size,              // dimensionality operator: size = op()
                        typename top_fval,              // function value operator: f = op(x)
                        typename top_grad,              // function value and gradient operator: f = op(x, g)
                        typename top_wlog,              // warning logging operator: op("message")
                        typename top_elog,              // error logging operator: op("message")
                        typename top_ulog,              // update (with current result/solution) logging operator: op(result)

                        // disable for not valid types!
                        typename tvalid_tscalar = typename std::enable_if<std::is_floating_point<tscalar>::value>::type,
                        typename tvalid_tsize = typename std::enable_if<std::is_integral<tsize>::value>::type
                >
                class optimizer_t
                {
                public:

                        typedef problem_t<tscalar, tsize, top_size, top_fval, top_grad>         tproblem;
                        typedef result_t<tscalar, tsize>                                        tresult;
                        typedef typename tresult::tstate                                        tstate;
                        typedef typename tresult::tvector                                       tvector;

                        // gradient descent starting from the initial value (guess) x0
                        static tresult gd(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,           // maximum number of iterations
                                tscalar epsilon,                // convergence precision
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                return _gd(problem, x0, max_iterations, epsilon, op_wlog, op_elog, op_ulog);
                        }

                        // conjugate gradient descent starting from the initial value (guess) x0
                        static tresult cgd(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,           // maximum number of iterations
                                tscalar epsilon,                // convergence precision
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                return _cgd(problem, x0, max_iterations, epsilon, op_wlog, op_elog, op_ulog);
                        }

                        // limited memory bfgs (l-bfgs) starting from the initial value (guess) x0
                        static tresult lbfgs(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,           // maximum number of iterations
                                tscalar epsilon,                // convergence precision
                                tsize hist_size = 8,            // hessian approximation history size
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                return _lbfgs(problem, x0, max_iterations, epsilon, hist_size, op_wlog, op_elog, op_ulog);
                        }

                private:

                        /////////////////////////////////////////////////////////////////////////////////////////

                        // check and force a descent direction
                        static tscalar descent(tstate& st, const top_wlog& wlog)
                        {
                                tscalar dg = st.d.dot(st.g);
                                if (dg > std::numeric_limits<tscalar>::min())
                                {
                                        if (wlog)
                                        {
                                                wlog("not a descent direction!");
                                        }
                                        st.d = -st.g;
                                        dg = st.d.dot(st.g);
                                }

                                return dg;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                private:

                        /////////////////////////////////////////////////////////////////////////////////////////
                        // line-search methods to find the scalar that reduces
                        //      the function value (the most) along the direction d: argmin(t) f(x + t * d).
                        /////////////////////////////////////////////////////////////////////////////////////////

                        // Armijo (sufficient decrease) condition
                        static tscalar ls_armijo(const tproblem& problem, tstate& st, const top_wlog& wlog,
                                tscalar alpha = 0.2, tscalar beta = 0.7, tsize max_iters = 64)
                        {
                                const tscalar dg = descent(st, wlog);

                                tscalar t = 1;
                                for (tsize i = 0; i < max_iters; i ++, t = beta * t)
                                {
                                        if (problem.f(st.x + t * st.d) < st.f + t * alpha * dg)
                                        {
                                                return t;
                                        }
                                }

                                return 0;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        // helper function: strong Wolfe (sufficient decrease and curvature) conditions
                        static tscalar ls_zoom(const tproblem& problem, const tstate& st,
                                tscalar& ft, tvector& gt,
                                tscalar tlo, tscalar thi, tscalar ftlo, tscalar fthi,
                                tscalar c1, tscalar c2, tsize max_iters = 64)
                        {
                                const tscalar dg = st.d.dot(st.g);

                                // (Nocedal & Wright (numerical optimization 2nd) @ p.60)
                                for (tsize i = 0; i < max_iters; i ++)
                                {
                                        const tscalar t = (tlo + thi) / 2;

                                        // check sufficient decrease
                                        ft = problem.f(st.x + t * st.d, gt);
                                        if (ft > st.f + c1 * t * dg || ft >= ftlo)
                                        {
                                                thi = t;
                                                fthi = ft;
                                        }

                                        // check curvature
                                        else
                                        {
                                                const tscalar dg1 = gt.dot(st.d);
                                                if (std::fabs(dg1) <= -c2 * dg)
                                                {
                                                        return t;
                                                }

                                                if (dg1 * (thi - tlo) >= 0)
                                                {
                                                        thi = tlo;
                                                        fthi = ftlo;
                                                }

                                                tlo = t;
                                                ftlo = ft;
                                        }
                                }

                                return 0;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        // strong Wolfe (sufficient decrease and curvature) conditions
                        static tscalar ls_strong_wolfe(const tproblem& problem, tstate& st, const top_wlog& wlog,
                                tscalar& ft, tvector& gt,
                                tscalar c1 = 1e-4, tscalar c2 = 0.1, tsize max_iters = 64)
                        {
                                const tscalar dg = descent(st, wlog);

                                const tscalar tmax = 1000;

                                tscalar t0 = 0, ft0 = std::numeric_limits<tscalar>::max();
                                tscalar t = 1;

                                // (Nocedal & Wright (numerical optimization 2nd) @ p.60)
                                for (tsize i = 0; i < max_iters; i ++)
                                {
                                        // check sufficient decrease
                                        ft = problem.f(st.x + t * st.d, gt);
                                        if (ft > st.f + c1 * t * dg || ft >= ft0)
                                        {
                                                return ls_zoom(problem, st, ft, gt, t0, t, ft0, ft, c1, c2, max_iters);
                                        }

                                        // check curvature
                                        const tscalar dg1 = gt.dot(st.d);
                                        if (std::fabs(dg1) <= -c2 * dg)
                                        {
                                                return t;
                                        }

                                        if (dg1 >= 0)
                                        {
                                                return ls_zoom(problem, st, ft, gt, t, t0, ft, ft0, c1, c2, max_iters);
                                        }

                                        t0 = t;
                                        t = std::min(tmax, t * 3);
                                        ft0 = ft;
                                }

                                return 0;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        static tresult _gd(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,
                                tscalar epsilon,
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                assert(problem.size() == static_cast<tsize>(x0.size()));

                                tresult result(problem.size());
                                tstate cstate(problem, x0);

                                // iterate until convergence
                                for (tsize i = 0; i < max_iterations; i ++)
                                {
                                        result.update(problem, cstate);
                                        if (op_ulog)
                                        {
                                                op_ulog(result);
                                        }

                                        // check convergence
                                        if (cstate.converged(epsilon))
                                        {
                                                break;
                                        }

                                        // descent direction
                                        cstate.d = -cstate.g;

                                        // update solution
                                        const tscalar t = ls_armijo(problem, cstate, op_wlog);
                                        if (t < std::numeric_limits<tscalar>::epsilon())
                                        {
                                                if (op_elog)
                                                {
                                                        op_elog("line-search failed for GD!");
                                                }
                                                break;
                                        }
                                        cstate.update(problem, t);
                                }

                                return result;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        static tresult _cgd(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,
                                tscalar epsilon,
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                assert(problem.size() == static_cast<tsize>(x0.size()));

                                tresult result(problem.size());
                                tstate cstate(problem, x0), pstate = cstate;

                                tscalar ft;
                                tvector gt;

                                // iterate until convergence
                                for (tsize i = 0; i < max_iterations; i ++)
                                {
                                        result.update(problem, cstate);
                                        if (op_ulog)
                                        {
                                                op_ulog(result);
                                        }

                                        // check convergence
                                        if (cstate.converged(epsilon))
                                        {
                                                break;
                                        }

                                        // descent direction (Polak–Ribière updates)
                                        if (i == 0)
                                        {
                                                cstate.d = -cstate.g;
                                        }
                                        else
                                        {
                                                const tscalar beta = cstate.g.dot(cstate.g - pstate.g) /
                                                                      pstate.g.dot(pstate.g);
                                                cstate.d = -cstate.g + std::max(static_cast<tscalar>(0), beta) * pstate.d;
                                        }

                                        // update solution
                                        const tscalar t = ls_strong_wolfe(problem, cstate, op_wlog, ft, gt, 1e-4, 0.1);
                                        if (t < std::numeric_limits<tscalar>::epsilon())
                                        {
                                                if (op_elog)
                                                {
                                                        op_elog("line-search failed for CGD!");
                                                }
                                                break;
                                        }
                                        pstate = cstate;
                                        cstate.update(t, ft, gt);
                                }

                                return result;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        static tresult _lbfgs(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,
                                tscalar epsilon,
                                tsize hist_size = 8,
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                assert(problem.size() == static_cast<tsize>(x0.size()));

                                tresult result(problem.size());
                                std::deque<tvector> ss, ys;
                                tstate cstate(problem, x0), pstate = cstate;

                                tvector q, r;
                                tscalar ft;
                                tvector gt;

                                // iterate until convergence
                                for (tsize i = 0; i < max_iterations; i ++)
                                {
                                        result.update(problem, cstate);
                                        if (op_ulog)
                                        {
                                                op_ulog(result);
                                        }

                                        // check convergence
                                        if (cstate.converged(epsilon))
                                        {
                                                break;
                                        }

                                        // descent direction
                                        //      (LBFGS - Nocedal & Wright (numerical optimization 2nd) notations @ p.178)
                                        q = cstate.g;

                                        typename std::deque<tvector>::const_reverse_iterator itr_s = ss.rbegin();
                                        typename std::deque<tvector>::const_reverse_iterator itr_y = ys.rbegin();
                                        std::vector<tscalar> alphas;
                                        for (tsize j = 1; j <= hist_size && i >= j; j ++)
                                        {
                                                const tvector& s = (*itr_s ++);
                                                const tvector& y = (*itr_y ++);

                                                const tscalar alpha = s.dot(q) / s.dot(y);
                                                q.noalias() -= alpha * y;
                                                alphas.push_back(alpha);
                                        }

                                        if (i == 0)
                                        {
                                                r = q;
                                        }
                                        else
                                        {
                                                const tvector& s = *ss.rbegin();
                                                const tvector& y = *ys.rbegin();
                                                r = s.dot(y) / y.dot(y) * q;
                                        }

                                        typename std::deque<tvector>::const_iterator it_s = ss.begin();
                                        typename std::deque<tvector>::const_iterator it_y = ys.begin();
                                        typename std::vector<tscalar>::const_reverse_iterator itr_alpha = alphas.rbegin();
                                        for (tsize j = 1; j <= hist_size && i >= j; j ++)
                                        {
                                                const tvector& s = (*it_s ++);
                                                const tvector& y = (*it_y ++);

                                                const tscalar alpha = *(itr_alpha ++);
                                                const tscalar beta = y.dot(r) / s.dot(y);
                                                r.noalias() += s * (alpha - beta);
                                        }

                                        cstate.d = -r;

                                        // update solution
                                        const tscalar t = ls_strong_wolfe(problem, cstate, op_wlog, ft, gt, 0.1, 0.9);
                                        if (t < std::numeric_limits<tscalar>::epsilon())
                                        {
                                                if (op_elog)
                                                {
                                                        op_elog("line-search failed for LBFGS!");
                                                }
                                                break;
                                        }
                                        pstate = cstate;
                                        cstate.update(t, ft, gt);

                                        ss.push_back(cstate.x - pstate.x);
                                        ys.push_back(cstate.g - pstate.g);
                                        if (ss.size() > hist_size)
                                        {
                                                ss.pop_front();
                                                ys.pop_front();
                                        }
                                }

                                return result;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////
                };
        }
}

#endif // NANOCV_OPTIMIZE_OPTIMIZER_HPP
<commit_msg>fix LBFGS convergence test<commit_after>#ifndef NANOCV_OPTIMIZE_OPTIMIZER_HPP
#define NANOCV_OPTIMIZE_OPTIMIZER_HPP

#include "core/optimize/result.hpp"
#include "core/optimize/problem.hpp"
#include <type_traits>
#include <deque>

namespace ncv
{
        namespace optimize
        {
                /////////////////////////////////////////////////////////////////////////////////////////
                // optimization methods (GD, CGD, LBFGS) starting from the initial value (guess) x0.
                /////////////////////////////////////////////////////////////////////////////////////////

                template
                <
                        typename tscalar,
                        typename tsize,
                        typename top_size,              // dimensionality operator: size = op()
                        typename top_fval,              // function value operator: f = op(x)
                        typename top_grad,              // function value and gradient operator: f = op(x, g)
                        typename top_wlog,              // warning logging operator: op("message")
                        typename top_elog,              // error logging operator: op("message")
                        typename top_ulog,              // update (with current result/solution) logging operator: op(result)

                        // disable for not valid types!
                        typename tvalid_tscalar = typename std::enable_if<std::is_floating_point<tscalar>::value>::type,
                        typename tvalid_tsize = typename std::enable_if<std::is_integral<tsize>::value>::type
                >
                class optimizer_t
                {
                public:

                        typedef problem_t<tscalar, tsize, top_size, top_fval, top_grad>         tproblem;
                        typedef result_t<tscalar, tsize>                                        tresult;
                        typedef typename tresult::tstate                                        tstate;
                        typedef typename tresult::tvector                                       tvector;

                        // gradient descent starting from the initial value (guess) x0
                        static tresult gd(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,           // maximum number of iterations
                                tscalar epsilon,                // convergence precision
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                return _gd(problem, x0, max_iterations, epsilon, op_wlog, op_elog, op_ulog);
                        }

                        // conjugate gradient descent starting from the initial value (guess) x0
                        static tresult cgd(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,           // maximum number of iterations
                                tscalar epsilon,                // convergence precision
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                return _cgd(problem, x0, max_iterations, epsilon, op_wlog, op_elog, op_ulog);
                        }

                        // limited memory bfgs (l-bfgs) starting from the initial value (guess) x0
                        static tresult lbfgs(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,           // maximum number of iterations
                                tscalar epsilon,                // convergence precision
                                tsize hist_size = 8,            // hessian approximation history size
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                return _lbfgs(problem, x0, max_iterations, epsilon, hist_size, op_wlog, op_elog, op_ulog);
                        }

                private:

                        /////////////////////////////////////////////////////////////////////////////////////////

                        // check and force a descent direction
                        static tscalar descent(tstate& st, const top_wlog& wlog)
                        {
                                tscalar dg = st.d.dot(st.g);
                                if (dg > std::numeric_limits<tscalar>::min())
                                {
                                        if (wlog)
                                        {
                                                wlog("not a descent direction!");
                                        }
                                        st.d = -st.g;
                                        dg = st.d.dot(st.g);
                                }

                                return dg;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                private:

                        /////////////////////////////////////////////////////////////////////////////////////////
                        // line-search methods to find the scalar that reduces
                        //      the function value (the most) along the direction d: argmin(t) f(x + t * d).
                        /////////////////////////////////////////////////////////////////////////////////////////

                        // Armijo (sufficient decrease) condition
                        static tscalar ls_armijo(const tproblem& problem, tstate& st, const top_wlog& wlog,
                                tscalar alpha = 0.2, tscalar beta = 0.7, tsize max_iters = 64)
                        {
                                const tscalar dg = descent(st, wlog);

                                tscalar t = 1;
                                for (tsize i = 0; i < max_iters; i ++, t = beta * t)
                                {
                                        if (problem.f(st.x + t * st.d) < st.f + t * alpha * dg)
                                        {
                                                return t;
                                        }
                                }

                                return 0;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        // helper function: strong Wolfe (sufficient decrease and curvature) conditions
                        static tscalar ls_zoom(const tproblem& problem, const tstate& st,
                                tscalar& ft, tvector& gt,
                                tscalar tlo, tscalar thi, tscalar ftlo, tscalar fthi,
                                tscalar c1, tscalar c2, tsize max_iters = 64)
                        {
                                const tscalar dg = st.d.dot(st.g);

                                // (Nocedal & Wright (numerical optimization 2nd) @ p.60)
                                for (tsize i = 0; i < max_iters; i ++)
                                {
                                        const tscalar t = (tlo + thi) / 2;

                                        // check sufficient decrease
                                        ft = problem.f(st.x + t * st.d, gt);
                                        if (ft > st.f + c1 * t * dg || ft >= ftlo)
                                        {
                                                thi = t;
                                                fthi = ft;
                                        }

                                        // check curvature
                                        else
                                        {
                                                const tscalar dg1 = gt.dot(st.d);
                                                if (std::fabs(dg1) <= -c2 * dg)
                                                {
                                                        return t;
                                                }

                                                if (dg1 * (thi - tlo) >= 0)
                                                {
                                                        thi = tlo;
                                                        fthi = ftlo;
                                                }

                                                tlo = t;
                                                ftlo = ft;
                                        }
                                }

                                return 0;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        // strong Wolfe (sufficient decrease and curvature) conditions
                        static tscalar ls_strong_wolfe(const tproblem& problem, tstate& st, const top_wlog& wlog,
                                tscalar& ft, tvector& gt,
                                tscalar c1 = 1e-4, tscalar c2 = 0.1, tsize max_iters = 64)
                        {
                                const tscalar dg = descent(st, wlog);

                                const tscalar tmax = 1000;

                                tscalar t0 = 0, ft0 = std::numeric_limits<tscalar>::max();
                                tscalar t = 1;

                                // (Nocedal & Wright (numerical optimization 2nd) @ p.60)
                                for (tsize i = 0; i < max_iters; i ++)
                                {
                                        // check sufficient decrease
                                        ft = problem.f(st.x + t * st.d, gt);
                                        if (ft > st.f + c1 * t * dg || ft >= ft0)
                                        {
                                                return ls_zoom(problem, st, ft, gt, t0, t, ft0, ft, c1, c2, max_iters);
                                        }

                                        // check curvature
                                        const tscalar dg1 = gt.dot(st.d);
                                        if (std::fabs(dg1) <= -c2 * dg)
                                        {
                                                return t;
                                        }

                                        if (dg1 >= 0)
                                        {
                                                return ls_zoom(problem, st, ft, gt, t, t0, ft, ft0, c1, c2, max_iters);
                                        }

                                        t0 = t;
                                        t = std::min(tmax, t * 3);
                                        ft0 = ft;
                                }

                                return 0;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        static tresult _gd(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,
                                tscalar epsilon,
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                assert(problem.size() == static_cast<tsize>(x0.size()));

                                tresult result(problem.size());
                                tstate cstate(problem, x0);

                                // iterate until convergence
                                for (tsize i = 0; i < max_iterations; i ++)
                                {
                                        result.update(problem, cstate);
                                        if (op_ulog)
                                        {
                                                op_ulog(result);
                                        }

                                        // check convergence
                                        if (cstate.converged(epsilon))
                                        {
                                                break;
                                        }

                                        // descent direction
                                        cstate.d = -cstate.g;

                                        // update solution
                                        const tscalar t = ls_armijo(problem, cstate, op_wlog);
                                        if (t < std::numeric_limits<tscalar>::epsilon())
                                        {
                                                if (op_elog)
                                                {
                                                        op_elog("line-search failed for GD!");
                                                }
                                                break;
                                        }
                                        cstate.update(problem, t);
                                }

                                return result;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        static tresult _cgd(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,
                                tscalar epsilon,
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                assert(problem.size() == static_cast<tsize>(x0.size()));

                                tresult result(problem.size());
                                tstate cstate(problem, x0), pstate = cstate;

                                tscalar ft;
                                tvector gt;

                                // iterate until convergence
                                for (tsize i = 0; i < max_iterations; i ++)
                                {
                                        result.update(problem, cstate);
                                        if (op_ulog)
                                        {
                                                op_ulog(result);
                                        }

                                        // check convergence
                                        if (cstate.converged(epsilon))
                                        {
                                                break;
                                        }

                                        // descent direction (Polak–Ribière updates)
                                        if (i == 0)
                                        {
                                                cstate.d = -cstate.g;
                                        }
                                        else
                                        {
                                                const tscalar beta = cstate.g.dot(cstate.g - pstate.g) /
                                                                      pstate.g.dot(pstate.g);
                                                cstate.d = -cstate.g + std::max(static_cast<tscalar>(0), beta) * pstate.d;
                                        }

                                        // update solution
                                        const tscalar t = ls_strong_wolfe(problem, cstate, op_wlog, ft, gt, 1e-4, 0.1);
                                        if (t < std::numeric_limits<tscalar>::epsilon())
                                        {
                                                if (op_elog)
                                                {
                                                        op_elog("line-search failed for CGD!");
                                                }
                                                break;
                                        }
                                        pstate = cstate;
                                        cstate.update(t, ft, gt);
                                }

                                return result;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////

                        static tresult _lbfgs(
                                const tproblem& problem,
                                const tvector& x0,
                                tsize max_iterations,
                                tscalar epsilon,
                                tsize hist_size = 8,
                                const top_wlog& op_wlog = top_wlog(),
                                const top_elog& op_elog = top_elog(),
                                const top_ulog& op_ulog = top_ulog())
                        {
                                assert(problem.size() == static_cast<tsize>(x0.size()));

                                tresult result(problem.size());
                                std::deque<tvector> ss, ys;
                                tstate cstate(problem, x0), pstate = cstate;

                                tvector q, r;
                                tscalar ft;
                                tvector gt;

                                // iterate until convergence
                                for (tsize i = 0; i < max_iterations; i ++)
                                {
                                        result.update(problem, cstate);
                                        if (op_ulog)
                                        {
                                                op_ulog(result);
                                        }

                                        // check convergence
                                        if (i > hist_size && cstate.converged(epsilon))
                                        {
                                                break;
                                        }

                                        // descent direction
                                        //      (LBFGS - Nocedal & Wright (numerical optimization 2nd) notations @ p.178)
                                        q = cstate.g;

                                        typename std::deque<tvector>::const_reverse_iterator itr_s = ss.rbegin();
                                        typename std::deque<tvector>::const_reverse_iterator itr_y = ys.rbegin();
                                        std::vector<tscalar> alphas;
                                        for (tsize j = 1; j <= hist_size && i >= j; j ++)
                                        {
                                                const tvector& s = (*itr_s ++);
                                                const tvector& y = (*itr_y ++);

                                                const tscalar alpha = s.dot(q) / s.dot(y);
                                                q.noalias() -= alpha * y;
                                                alphas.push_back(alpha);
                                        }

                                        if (i == 0)
                                        {
                                                r = q;
                                        }
                                        else
                                        {
                                                const tvector& s = *ss.rbegin();
                                                const tvector& y = *ys.rbegin();
                                                r = s.dot(y) / y.dot(y) * q;
                                        }

                                        typename std::deque<tvector>::const_iterator it_s = ss.begin();
                                        typename std::deque<tvector>::const_iterator it_y = ys.begin();
                                        typename std::vector<tscalar>::const_reverse_iterator itr_alpha = alphas.rbegin();
                                        for (tsize j = 1; j <= hist_size && i >= j; j ++)
                                        {
                                                const tvector& s = (*it_s ++);
                                                const tvector& y = (*it_y ++);

                                                const tscalar alpha = *(itr_alpha ++);
                                                const tscalar beta = y.dot(r) / s.dot(y);
                                                r.noalias() += s * (alpha - beta);
                                        }

                                        cstate.d = -r;

                                        // update solution
                                        const tscalar t = ls_strong_wolfe(problem, cstate, op_wlog, ft, gt, 0.1, 0.9);
                                        if (t < std::numeric_limits<tscalar>::epsilon())
                                        {
                                                if (op_elog)
                                                {
                                                        op_elog("line-search failed for LBFGS!");
                                                }
                                                break;
                                        }
                                        pstate = cstate;
                                        cstate.update(t, ft, gt);

                                        ss.push_back(cstate.x - pstate.x);
                                        ys.push_back(cstate.g - pstate.g);
                                        if (ss.size() > hist_size)
                                        {
                                                ss.pop_front();
                                                ys.pop_front();
                                        }
                                }

                                return result;
                        }

                        /////////////////////////////////////////////////////////////////////////////////////////
                };
        }
}

#endif // NANOCV_OPTIMIZE_OPTIMIZER_HPP
<|endoftext|>


<commit_before>// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "pal.h"
#include "args.h"
#include "trace.h"
#include "deps_resolver.h"
#include "utils.h"
#include "coreclr.h"

enum StatusCode
{
    // 0x80 prefix to distinguish from corehost main's error codes.
    InvalidArgFailure      = 0x81,
    CoreClrResolveFailure  = 0x82,
    CoreClrBindFailure     = 0x83,
    CoreClrInitFailure     = 0x84,
    CoreClrExeFailure      = 0x85,
    ResolverInitFailure    = 0x86,
    ResolverResolveFailure = 0x87,
};

// ----------------------------------------------------------------------
// resolve_clr_path: Resolve CLR Path in priority order
//
// Description:
//   Check if CoreCLR library exists in runtime servicing dir or app
//   local or DOTNET_HOME directory in that order of priority. If these
//   fail to locate CoreCLR, then check platform-specific search.
//
// Returns:
//   "true" if path to the CoreCLR dir can be resolved in "clr_path"
//    parameter. Else, returns "false" with "clr_path" unmodified.
//
bool resolve_clr_path(const arguments_t& args, pal::string_t* clr_path)
{
    const pal::string_t* dirs[] = {
        &args.dotnet_runtime_servicing, // DOTNET_RUNTIME_SERVICING
        &args.app_dir,                  // APP LOCAL
        &args.dotnet_home               // DOTNET_HOME
    };
    for (int i = 0; i < sizeof(dirs) / sizeof(dirs[0]); ++i)
    {
        if (dirs[i]->empty())
        {
            continue;
        }

        // App dir should contain coreclr, so skip appending path.
        pal::string_t cur_dir = *dirs[i];
        if (dirs[i] != &args.app_dir)
        {
            append_path(&cur_dir, _X("runtime"));
            append_path(&cur_dir, _X("coreclr"));
        }

        // Found coreclr in priority order.
        if (coreclr_exists_in_dir(cur_dir))
        {
            clr_path->assign(cur_dir);
            return true;
        }
    }

    // Use platform-specific search algorithm
    pal::string_t home_dir = args.dotnet_home;
    if (pal::find_coreclr(&home_dir))
    {
        clr_path->assign(home_dir);
        return true;
    }
    return false;
}

int run(const arguments_t& args, const pal::string_t& clr_path)
{
    // Load the deps resolver
    deps_resolver_t resolver(args);
    if (!resolver.valid())
    {
        trace::error(_X("Invalid .deps file"));
        return StatusCode::ResolverInitFailure;
    }

    // Add packages directory
    pal::string_t packages_dir = args.nuget_packages;
    if (!pal::directory_exists(packages_dir))
    {
        (void)pal::get_default_packages_directory(&packages_dir);
    }
    trace::info(_X("Package directory: %s"), packages_dir.empty() ? _X("not specified") : packages_dir.c_str());

    probe_paths_t probe_paths;
    if (!resolver.resolve_probe_paths(args.app_dir, packages_dir, args.dotnet_packages_cache, clr_path, &probe_paths))
    {
        return StatusCode::ResolverResolveFailure;
    }

    // Build CoreCLR properties
    const char* property_keys[] = {
        "TRUSTED_PLATFORM_ASSEMBLIES",
        "APP_PATHS",
        "APP_NI_PATHS",
        "NATIVE_DLL_SEARCH_DIRECTORIES",
        "PLATFORM_RESOURCE_ROOTS",
        "AppDomainCompatSwitch",
        // TODO: pipe this from corehost.json
        "SERVER_GC",
    };

    auto tpa_paths_cstr = pal::to_stdstring(probe_paths.tpa);
    auto app_base_cstr = pal::to_stdstring(args.app_dir);
    auto native_dirs_cstr = pal::to_stdstring(probe_paths.native);
    auto culture_dirs_cstr = pal::to_stdstring(probe_paths.culture);

    // Workaround for dotnet/cli Issue #488 and #652
    pal::string_t server_gc;
    std::string server_gc_cstr = (pal::getenv(_X("COREHOST_SERVER_GC"), &server_gc) && !server_gc.empty()) ? pal::to_stdstring(server_gc) : "1";

    const char* property_values[] = {
        // TRUSTED_PLATFORM_ASSEMBLIES
        tpa_paths_cstr.c_str(),
        // APP_PATHS
        app_base_cstr.c_str(),
        // APP_NI_PATHS
        app_base_cstr.c_str(),
        // NATIVE_DLL_SEARCH_DIRECTORIES
        native_dirs_cstr.c_str(),
        // PLATFORM_RESOURCE_ROOTS
        culture_dirs_cstr.c_str(),
        // AppDomainCompatSwitch
        "UseLatestBehaviorWhenTFMNotSpecified",
        // SERVER_GC
        server_gc_cstr.c_str(),
    };

    size_t property_size = sizeof(property_keys) / sizeof(property_keys[0]);

    // Bind CoreCLR
    if (!coreclr::bind(clr_path))
    {
        trace::error(_X("Failed to bind to coreclr"));
        return StatusCode::CoreClrBindFailure;
    }

    // Verbose logging
    if (trace::is_enabled())
    {
        for (size_t i = 0; i < property_size; ++i)
        {
            pal::string_t key, val;
            pal::to_palstring(property_keys[i], &key);
            pal::to_palstring(property_values[i], &val);
            trace::verbose(_X("Property %s = %s"), key.c_str(), val.c_str());
        }
    }

    std::string own_path;
    pal::to_stdstring(args.own_path.c_str(), &own_path);

    // Initialize CoreCLR
    coreclr::host_handle_t host_handle;
    coreclr::domain_id_t domain_id;
    auto hr = coreclr::initialize(
        own_path.c_str(),
        "clrhost",
        property_keys,
        property_values,
        property_size,
        &host_handle,
        &domain_id);
    if (!SUCCEEDED(hr))
    {
        trace::error(_X("Failed to initialize CoreCLR, HRESULT: 0x%X"), hr);
        return StatusCode::CoreClrInitFailure;
    }

    if (trace::is_enabled())
    {
        pal::string_t arg_str;
        for (int i = 0; i < args.app_argc; i++)
        {
            arg_str.append(args.app_argv[i]);
            arg_str.append(_X(","));
        }
        trace::info(_X("Launch host: %s app: %s, argc: %d args: %s"), args.own_path.c_str(),
            args.managed_application.c_str(), args.app_argc, arg_str.c_str());
    }

    // Initialize with empty strings
    std::vector<std::string> argv_strs(args.app_argc);
    std::vector<const char*> argv(args.app_argc);
    for (int i = 0; i < args.app_argc; i++)
    {
        pal::to_stdstring(args.app_argv[i], &argv_strs[i]);
        argv[i] = argv_strs[i].c_str();
    }

    std::string managed_app = pal::to_stdstring(args.managed_application);

    // Execute the application
    unsigned int exit_code = 1;
    hr = coreclr::execute_assembly(
        host_handle,
        domain_id,
        argv.size(),
        argv.data(),
        managed_app.c_str(),
        &exit_code);
    if (!SUCCEEDED(hr))
    {
        trace::error(_X("Failed to execute managed app, HRESULT: 0x%X"), hr);
        return StatusCode::CoreClrExeFailure;
    }

    // Shut down the CoreCLR
    hr = coreclr::shutdown(host_handle, domain_id);
    if (!SUCCEEDED(hr))
    {
        trace::warning(_X("Failed to shut down CoreCLR, HRESULT: 0x%X"), hr);
    }

    coreclr::unload();

    return exit_code;
}

SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
{
    trace::setup();

    // Take care of arguments
    arguments_t args;
    if (!parse_arguments(argc, argv, args))
    {
        return StatusCode::InvalidArgFailure;
    }

    // Resolve CLR path
    pal::string_t clr_path;
    if (!resolve_clr_path(args, &clr_path))
    {
        trace::error(_X("Could not resolve coreclr path"));
        return StatusCode::CoreClrResolveFailure;
    }
    pal::realpath(&clr_path);
    return run(args, clr_path);
}
<commit_msg>Set AppContext BaseDirectory<commit_after>// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "pal.h"
#include "args.h"
#include "trace.h"
#include "deps_resolver.h"
#include "utils.h"
#include "coreclr.h"

enum StatusCode
{
    // 0x80 prefix to distinguish from corehost main's error codes.
    InvalidArgFailure      = 0x81,
    CoreClrResolveFailure  = 0x82,
    CoreClrBindFailure     = 0x83,
    CoreClrInitFailure     = 0x84,
    CoreClrExeFailure      = 0x85,
    ResolverInitFailure    = 0x86,
    ResolverResolveFailure = 0x87,
};

// ----------------------------------------------------------------------
// resolve_clr_path: Resolve CLR Path in priority order
//
// Description:
//   Check if CoreCLR library exists in runtime servicing dir or app
//   local or DOTNET_HOME directory in that order of priority. If these
//   fail to locate CoreCLR, then check platform-specific search.
//
// Returns:
//   "true" if path to the CoreCLR dir can be resolved in "clr_path"
//    parameter. Else, returns "false" with "clr_path" unmodified.
//
bool resolve_clr_path(const arguments_t& args, pal::string_t* clr_path)
{
    const pal::string_t* dirs[] = {
        &args.dotnet_runtime_servicing, // DOTNET_RUNTIME_SERVICING
        &args.app_dir,                  // APP LOCAL
        &args.dotnet_home               // DOTNET_HOME
    };
    for (int i = 0; i < sizeof(dirs) / sizeof(dirs[0]); ++i)
    {
        if (dirs[i]->empty())
        {
            continue;
        }

        // App dir should contain coreclr, so skip appending path.
        pal::string_t cur_dir = *dirs[i];
        if (dirs[i] != &args.app_dir)
        {
            append_path(&cur_dir, _X("runtime"));
            append_path(&cur_dir, _X("coreclr"));
        }

        // Found coreclr in priority order.
        if (coreclr_exists_in_dir(cur_dir))
        {
            clr_path->assign(cur_dir);
            return true;
        }
    }

    // Use platform-specific search algorithm
    pal::string_t home_dir = args.dotnet_home;
    if (pal::find_coreclr(&home_dir))
    {
        clr_path->assign(home_dir);
        return true;
    }
    return false;
}

int run(const arguments_t& args, const pal::string_t& clr_path)
{
    // Load the deps resolver
    deps_resolver_t resolver(args);
    if (!resolver.valid())
    {
        trace::error(_X("Invalid .deps file"));
        return StatusCode::ResolverInitFailure;
    }

    // Add packages directory
    pal::string_t packages_dir = args.nuget_packages;
    if (!pal::directory_exists(packages_dir))
    {
        (void)pal::get_default_packages_directory(&packages_dir);
    }
    trace::info(_X("Package directory: %s"), packages_dir.empty() ? _X("not specified") : packages_dir.c_str());

    probe_paths_t probe_paths;
    if (!resolver.resolve_probe_paths(args.app_dir, packages_dir, args.dotnet_packages_cache, clr_path, &probe_paths))
    {
        return StatusCode::ResolverResolveFailure;
    }

    // Build CoreCLR properties
    const char* property_keys[] = {
        "TRUSTED_PLATFORM_ASSEMBLIES",
        "APP_PATHS",
        "APP_NI_PATHS",
        "NATIVE_DLL_SEARCH_DIRECTORIES",
        "PLATFORM_RESOURCE_ROOTS",
        "AppDomainCompatSwitch",
        // TODO: pipe this from corehost.json
        "SERVER_GC",
        // Workaround: mscorlib does not resolve symlinks for AppContext.BaseDirectory dotnet/coreclr/issues/2128
        "APP_CONTEXT_BASE_DIRECTORY",
    };

    auto tpa_paths_cstr = pal::to_stdstring(probe_paths.tpa);
    auto app_base_cstr = pal::to_stdstring(args.app_dir);
    auto native_dirs_cstr = pal::to_stdstring(probe_paths.native);
    auto culture_dirs_cstr = pal::to_stdstring(probe_paths.culture);

    // Workaround for dotnet/cli Issue #488 and #652
    pal::string_t server_gc;
    std::string server_gc_cstr = (pal::getenv(_X("COREHOST_SERVER_GC"), &server_gc) && !server_gc.empty()) ? pal::to_stdstring(server_gc) : "1";

    const char* property_values[] = {
        // TRUSTED_PLATFORM_ASSEMBLIES
        tpa_paths_cstr.c_str(),
        // APP_PATHS
        app_base_cstr.c_str(),
        // APP_NI_PATHS
        app_base_cstr.c_str(),
        // NATIVE_DLL_SEARCH_DIRECTORIES
        native_dirs_cstr.c_str(),
        // PLATFORM_RESOURCE_ROOTS
        culture_dirs_cstr.c_str(),
        // AppDomainCompatSwitch
        "UseLatestBehaviorWhenTFMNotSpecified",
        // SERVER_GC
        server_gc_cstr.c_str(),
        // APP_CONTEXT_BASE_DIRECTORY
        app_base_cstr.c_str()
    };

    size_t property_size = sizeof(property_keys) / sizeof(property_keys[0]);

    // Bind CoreCLR
    if (!coreclr::bind(clr_path))
    {
        trace::error(_X("Failed to bind to coreclr"));
        return StatusCode::CoreClrBindFailure;
    }

    // Verbose logging
    if (trace::is_enabled())
    {
        for (size_t i = 0; i < property_size; ++i)
        {
            pal::string_t key, val;
            pal::to_palstring(property_keys[i], &key);
            pal::to_palstring(property_values[i], &val);
            trace::verbose(_X("Property %s = %s"), key.c_str(), val.c_str());
        }
    }

    std::string own_path;
    pal::to_stdstring(args.own_path.c_str(), &own_path);

    // Initialize CoreCLR
    coreclr::host_handle_t host_handle;
    coreclr::domain_id_t domain_id;
    auto hr = coreclr::initialize(
        own_path.c_str(),
        "clrhost",
        property_keys,
        property_values,
        property_size,
        &host_handle,
        &domain_id);
    if (!SUCCEEDED(hr))
    {
        trace::error(_X("Failed to initialize CoreCLR, HRESULT: 0x%X"), hr);
        return StatusCode::CoreClrInitFailure;
    }

    if (trace::is_enabled())
    {
        pal::string_t arg_str;
        for (int i = 0; i < args.app_argc; i++)
        {
            arg_str.append(args.app_argv[i]);
            arg_str.append(_X(","));
        }
        trace::info(_X("Launch host: %s app: %s, argc: %d args: %s"), args.own_path.c_str(),
            args.managed_application.c_str(), args.app_argc, arg_str.c_str());
    }

    // Initialize with empty strings
    std::vector<std::string> argv_strs(args.app_argc);
    std::vector<const char*> argv(args.app_argc);
    for (int i = 0; i < args.app_argc; i++)
    {
        pal::to_stdstring(args.app_argv[i], &argv_strs[i]);
        argv[i] = argv_strs[i].c_str();
    }

    std::string managed_app = pal::to_stdstring(args.managed_application);

    // Execute the application
    unsigned int exit_code = 1;
    hr = coreclr::execute_assembly(
        host_handle,
        domain_id,
        argv.size(),
        argv.data(),
        managed_app.c_str(),
        &exit_code);
    if (!SUCCEEDED(hr))
    {
        trace::error(_X("Failed to execute managed app, HRESULT: 0x%X"), hr);
        return StatusCode::CoreClrExeFailure;
    }

    // Shut down the CoreCLR
    hr = coreclr::shutdown(host_handle, domain_id);
    if (!SUCCEEDED(hr))
    {
        trace::warning(_X("Failed to shut down CoreCLR, HRESULT: 0x%X"), hr);
    }

    coreclr::unload();

    return exit_code;
}

SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
{
    trace::setup();

    // Take care of arguments
    arguments_t args;
    if (!parse_arguments(argc, argv, args))
    {
        return StatusCode::InvalidArgFailure;
    }

    // Resolve CLR path
    pal::string_t clr_path;
    if (!resolve_clr_path(args, &clr_path))
    {
        trace::error(_X("Could not resolve coreclr path"));
        return StatusCode::CoreClrResolveFailure;
    }
    pal::realpath(&clr_path);
    return run(args, clr_path);
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mtimestamp.h"

#include "mdebug.h"
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

void M_CORE_EXPORT mTimestampStream(const QString &module, const QString &file, const QString &scope, const QString &msg)
{
    static const QString format("%1.%2 MARK|%3|%4|%5");
    static const QChar fill('0');
    QString output;
    struct timeval tv;

    gettimeofday(&tv, 0);

    output = format.arg(tv.tv_sec).arg(tv.tv_usec, 6, 10, fill).arg(file).arg(scope).arg(msg);
    mWarning(module) << output;
}
<commit_msg>Changes: use QTime instead of gettimeofday<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mtimestamp.h"

#include "mdebug.h"
#include <QtCore/QTime>

void M_CORE_EXPORT mTimestampStream(const QString &module, const QString &file, const QString &scope, const QString &msg)
{
    static const QString format("MARK|%3|%4|%5");
    QString output = format.arg(file).arg(scope).arg(msg);
    mWarning(module) << QTime::currentTime() << output;
}
<|endoftext|>