<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 <cassert>
#include "trace.h"
#include "pal.h"
#include "utils.h"
#include "fx_ver.h"
#include "fx_muxer.h"
#include "error_codes.h"
#include "libhost.h"
#include "runtime_config.h"

typedef int(*corehost_load_fn) (const host_interface_t* init);
typedef int(*corehost_main_fn) (const int argc, const pal::char_t* argv[]);
typedef int(*corehost_main_with_output_buffer_fn) (const int argc, const pal::char_t* argv[], pal::char_t buffer[], int32_t buffer_size, int32_t* required_buffer_size);
typedef int(*corehost_unload_fn) ();

int load_host_library_common(
    const pal::string_t& lib_dir,
    pal::string_t& host_path,
    pal::dll_t* h_host,
    corehost_load_fn* load_fn,
    corehost_unload_fn* unload_fn)
{
    if (!library_exists_in_dir(lib_dir, LIBHOSTPOLICY_NAME, &host_path))
    {
        return StatusCode::CoreHostLibMissingFailure;
    }

    // Load library
    if (!pal::load_library(&host_path, h_host))
    {
        trace::info(_X("Load library of %s failed"), host_path.c_str());
        return StatusCode::CoreHostLibLoadFailure;
    }

    // Obtain entrypoint symbols
    *load_fn = (corehost_load_fn)pal::get_symbol(*h_host, "corehost_load");
    *unload_fn = (corehost_unload_fn)pal::get_symbol(*h_host, "corehost_unload");

    return (*load_fn) && (*unload_fn)
        ? StatusCode::Success
        : StatusCode::CoreHostEntryPointFailure;
}

int load_host_library(
    const pal::string_t& lib_dir,
    pal::dll_t* h_host,
    corehost_load_fn* load_fn,
    corehost_main_fn* main_fn,
    corehost_unload_fn* unload_fn)
{
    pal::string_t host_path;
    int rc = load_host_library_common(lib_dir, host_path, h_host, load_fn, unload_fn);
    if (rc != StatusCode::Success)
    {
        return rc;
    }

    // Obtain entrypoint symbol
    *main_fn = (corehost_main_fn)pal::get_symbol(*h_host, "corehost_main");

    return (*main_fn)
        ? StatusCode::Success
        : StatusCode::CoreHostEntryPointFailure;
}

int load_host_library_with_return(
    const pal::string_t& lib_dir,
    pal::dll_t* h_host,
    corehost_load_fn* load_fn,
    corehost_main_with_output_buffer_fn* main_fn,
    corehost_unload_fn* unload_fn)
{
    pal::string_t host_path;
    int rc = load_host_library_common(lib_dir, host_path, h_host, load_fn, unload_fn);
    if (rc != StatusCode::Success)
    {
        return rc;
    }

    // Obtain entrypoint symbol
    *main_fn = (corehost_main_with_output_buffer_fn)pal::get_symbol(*h_host, "corehost_main_with_output_buffer");

    return (*main_fn)
        ? StatusCode::Success
        : StatusCode::CoreHostEntryPointFailure;
}

int execute_app(
    const pal::string_t& impl_dll_dir,
    corehost_init_t* init,
    const int argc,
    const pal::char_t* argv[])
{
    pal::dll_t corehost;
    corehost_main_fn host_main = nullptr;
    corehost_load_fn host_load = nullptr;
    corehost_unload_fn host_unload = nullptr;

    int code = load_host_library(impl_dll_dir, &corehost, &host_load, &host_main, &host_unload);
    if (code != StatusCode::Success)
    {
        trace::error(_X("An error occurred while loading required library %s from [%s]"), LIBHOSTPOLICY_NAME, impl_dll_dir.c_str());
        return code;
    }

    // Previous hostfxr trace messages must be printed before calling trace::setup in hostpolicy
    trace::flush();

    const host_interface_t& intf = init->get_host_init_data();
    if ((code = host_load(&intf)) == 0)
    {
        code = host_main(argc, argv);
        (void)host_unload();
    }

    pal::unload_library(corehost);

    return code;
}

int execute_host_command(
    const pal::string_t& impl_dll_dir,
    corehost_init_t* init,
    const int argc,
    const pal::char_t* argv[],
    pal::char_t result_buffer[],
    int32_t buffer_size,
    int32_t* required_buffer_size)
{
    pal::dll_t corehost;
    corehost_main_with_output_buffer_fn host_main = nullptr;
    corehost_load_fn host_load = nullptr;
    corehost_unload_fn host_unload = nullptr;

    int code = load_host_library_with_return(impl_dll_dir, &corehost, &host_load, &host_main, &host_unload);

    if (code != StatusCode::Success)
    {
        trace::error(_X("An error occurred while loading required library %s from [%s] for a host command"), LIBHOSTPOLICY_NAME, impl_dll_dir.c_str());
        return code;
    }

    // Previous hostfxr trace messages must be printed before calling trace::setup in hostpolicy
    trace::flush();

    const host_interface_t& intf = init->get_host_init_data();
    if ((code = host_load(&intf)) == 0)
    {
        code = host_main(argc, argv, result_buffer, buffer_size, required_buffer_size);
        (void)host_unload();
    }

    pal::unload_library(corehost);

    return code;
}

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

    trace::info(_X("--- Invoked hostfxr [commit hash: %s] main"), _STRINGIFY(REPO_COMMIT_HASH));

    fx_muxer_t muxer;
    return muxer.execute(pal::string_t(), argc, argv, nullptr, 0, nullptr);
}

//
// Determines the directory location of the SDK accounting for
// global.json and multi-level lookup policy.
//
// Invoked via MSBuild SDK resolver to locate SDK props and targets
// from an msbuild other than the one bundled by the CLI.
//
// Parameters:
//    exe_dir
//      The main directory where SDKs are located in sdk\[version]
//      sub-folders. Pass the directory of a dotnet executable to
//      mimic how that executable would search in its own directory.
//      It is also valid to pass nullptr or empty, in which case
//      multi-level lookup can still search other locations if
//      it has not been disabled by the user's environment.
//
//    working_dir
//      The directory where the search for global.json (which can
//      control the resolved SDK version) starts and proceeds
//      upwards.
//
//    buffer
//      The buffer where the resolved SDK path will be written.
//
//    buffer_size
//      The size of the buffer argument in pal::char_t units.
//
// Return value:
//   <0 - Invalid argument
//   0  - SDK could not be found.
//   >0 - The number of characters (including null terminator)
//        required to store the located SDK.
//
//   If resolution succeeds and the positive return value is less than
//   or equal to buffer_size (i.e. the the buffer is large enough),
//   then the resolved SDK path is copied to the buffer and null
//   terminated. Otherwise, no data is written to the buffer.
//
// String encoding:
//   Windows     - UTF-16 (pal::char_t is 2 byte wchar_t)
//   Unix        - UTF-8  (pal::char_t is 1 byte char)
//
SHARED_API int32_t hostfxr_resolve_sdk(
    const pal::char_t* exe_dir,
    const pal::char_t* working_dir,
    pal::char_t buffer[],
    int32_t buffer_size)
{
    trace::setup();

    trace::info(_X("--- Invoked hostfxr [commit hash: %s] hostfxr_resolve_sdk"), _STRINGIFY(REPO_COMMIT_HASH));

    if (buffer_size < 0 || (buffer_size > 0 && buffer == nullptr))
    {
        trace::error(_X("hostfxr_resolve_sdk received an invalid argument."));
        return -1;
    }

    if (exe_dir == nullptr)
    {
        exe_dir = _X("");
    }

    if (working_dir == nullptr)
    {
        working_dir = _X("");
    }

    pal::string_t cli_sdk;
    if (!fx_muxer_t::resolve_sdk_dotnet_path(exe_dir, working_dir, &cli_sdk))
    {
        // fx_muxer_t::resolve_sdk_dotnet_path handles tracing for this error case.
        return 0;
    }

    if (cli_sdk.size() < buffer_size)
    {
        size_t length = cli_sdk.copy(buffer, buffer_size - 1);
        assert(length == cli_sdk.size());
        assert(length < buffer_size);
        buffer[length] = 0;
    }
    else
    {
        trace::info(_X("hostfxr_resolve_sdk received a buffer that is too small to hold the located SDK path."));
    }

    return cli_sdk.size() + 1;
}

//
// Returns the native directories of the runtime based upon
// the specified app.
//
// Returned format is a list of paths separated by PATH_SEPARATOR
// which is a semicolon (;) on Windows and a colon (:) otherwise,
//
// Invoked from ASP.NET in order to help load a native assembly
// before the clr is initialized (through a custom host).
//
// Parameters:
//    argc
//      The number of argv arguments
//
//    argv
//      The standard arguments normally passed to dotnet.exe
//      for launching the application.
//
//    buffer
//      The buffer where the native paths will be written.
//
//    buffer_size
//      The size of the buffer argument in pal::char_t units.
//
//    required_buffer_size
//      If the return value is HostApiBufferTooSmall, then
//      required_buffer_size is set to the minimium buffer
//      size necessary to contain the result.
//
// Return value:
//   0 on success, otherwise failure
//   0x800080980 - Buffer is too small (HostApiBufferTooSmall)
//
// String encoding:
//   Windows     - UTF-16 (pal::char_t is 2 byte wchar_t)
//   Unix        - UTF-8  (pal::char_t is 1 byte char)
//
SHARED_API int32_t hostfxr_get_native_search_directories(const int argc, const pal::char_t* argv[], pal::char_t buffer[], int32_t buffer_size, int32_t* required_buffer_size)
{
    trace::setup();

    trace::info(_X("--- Invoked hostfxr_get_native_search_directories [commit hash: %s] main"), _STRINGIFY(REPO_COMMIT_HASH));

    if (buffer_size < 0 || (buffer_size > 0 && buffer == nullptr) || required_buffer_size == nullptr)
    {
        trace::error(_X("hostfxr_get_native_search_directories received an invalid argument."));
        return InvalidArgFailure;
    }

    fx_muxer_t muxer;
    int rc = muxer.execute(_X("get-native-search-directories"), argc, argv, buffer, buffer_size, required_buffer_size);
    return rc;
}
<commit_msg>Update doc for hostfxr_get_native_search_directories (#3666)<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 <cassert>
#include "trace.h"
#include "pal.h"
#include "utils.h"
#include "fx_ver.h"
#include "fx_muxer.h"
#include "error_codes.h"
#include "libhost.h"
#include "runtime_config.h"

typedef int(*corehost_load_fn) (const host_interface_t* init);
typedef int(*corehost_main_fn) (const int argc, const pal::char_t* argv[]);
typedef int(*corehost_main_with_output_buffer_fn) (const int argc, const pal::char_t* argv[], pal::char_t buffer[], int32_t buffer_size, int32_t* required_buffer_size);
typedef int(*corehost_unload_fn) ();

int load_host_library_common(
    const pal::string_t& lib_dir,
    pal::string_t& host_path,
    pal::dll_t* h_host,
    corehost_load_fn* load_fn,
    corehost_unload_fn* unload_fn)
{
    if (!library_exists_in_dir(lib_dir, LIBHOSTPOLICY_NAME, &host_path))
    {
        return StatusCode::CoreHostLibMissingFailure;
    }

    // Load library
    if (!pal::load_library(&host_path, h_host))
    {
        trace::info(_X("Load library of %s failed"), host_path.c_str());
        return StatusCode::CoreHostLibLoadFailure;
    }

    // Obtain entrypoint symbols
    *load_fn = (corehost_load_fn)pal::get_symbol(*h_host, "corehost_load");
    *unload_fn = (corehost_unload_fn)pal::get_symbol(*h_host, "corehost_unload");

    return (*load_fn) && (*unload_fn)
        ? StatusCode::Success
        : StatusCode::CoreHostEntryPointFailure;
}

int load_host_library(
    const pal::string_t& lib_dir,
    pal::dll_t* h_host,
    corehost_load_fn* load_fn,
    corehost_main_fn* main_fn,
    corehost_unload_fn* unload_fn)
{
    pal::string_t host_path;
    int rc = load_host_library_common(lib_dir, host_path, h_host, load_fn, unload_fn);
    if (rc != StatusCode::Success)
    {
        return rc;
    }

    // Obtain entrypoint symbol
    *main_fn = (corehost_main_fn)pal::get_symbol(*h_host, "corehost_main");

    return (*main_fn)
        ? StatusCode::Success
        : StatusCode::CoreHostEntryPointFailure;
}

int load_host_library_with_return(
    const pal::string_t& lib_dir,
    pal::dll_t* h_host,
    corehost_load_fn* load_fn,
    corehost_main_with_output_buffer_fn* main_fn,
    corehost_unload_fn* unload_fn)
{
    pal::string_t host_path;
    int rc = load_host_library_common(lib_dir, host_path, h_host, load_fn, unload_fn);
    if (rc != StatusCode::Success)
    {
        return rc;
    }

    // Obtain entrypoint symbol
    *main_fn = (corehost_main_with_output_buffer_fn)pal::get_symbol(*h_host, "corehost_main_with_output_buffer");

    return (*main_fn)
        ? StatusCode::Success
        : StatusCode::CoreHostEntryPointFailure;
}

int execute_app(
    const pal::string_t& impl_dll_dir,
    corehost_init_t* init,
    const int argc,
    const pal::char_t* argv[])
{
    pal::dll_t corehost;
    corehost_main_fn host_main = nullptr;
    corehost_load_fn host_load = nullptr;
    corehost_unload_fn host_unload = nullptr;

    int code = load_host_library(impl_dll_dir, &corehost, &host_load, &host_main, &host_unload);
    if (code != StatusCode::Success)
    {
        trace::error(_X("An error occurred while loading required library %s from [%s]"), LIBHOSTPOLICY_NAME, impl_dll_dir.c_str());
        return code;
    }

    // Previous hostfxr trace messages must be printed before calling trace::setup in hostpolicy
    trace::flush();

    const host_interface_t& intf = init->get_host_init_data();
    if ((code = host_load(&intf)) == 0)
    {
        code = host_main(argc, argv);
        (void)host_unload();
    }

    pal::unload_library(corehost);

    return code;
}

int execute_host_command(
    const pal::string_t& impl_dll_dir,
    corehost_init_t* init,
    const int argc,
    const pal::char_t* argv[],
    pal::char_t result_buffer[],
    int32_t buffer_size,
    int32_t* required_buffer_size)
{
    pal::dll_t corehost;
    corehost_main_with_output_buffer_fn host_main = nullptr;
    corehost_load_fn host_load = nullptr;
    corehost_unload_fn host_unload = nullptr;

    int code = load_host_library_with_return(impl_dll_dir, &corehost, &host_load, &host_main, &host_unload);

    if (code != StatusCode::Success)
    {
        trace::error(_X("An error occurred while loading required library %s from [%s] for a host command"), LIBHOSTPOLICY_NAME, impl_dll_dir.c_str());
        return code;
    }

    // Previous hostfxr trace messages must be printed before calling trace::setup in hostpolicy
    trace::flush();

    const host_interface_t& intf = init->get_host_init_data();
    if ((code = host_load(&intf)) == 0)
    {
        code = host_main(argc, argv, result_buffer, buffer_size, required_buffer_size);
        (void)host_unload();
    }

    pal::unload_library(corehost);

    return code;
}

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

    trace::info(_X("--- Invoked hostfxr [commit hash: %s] main"), _STRINGIFY(REPO_COMMIT_HASH));

    fx_muxer_t muxer;
    return muxer.execute(pal::string_t(), argc, argv, nullptr, 0, nullptr);
}

//
// Determines the directory location of the SDK accounting for
// global.json and multi-level lookup policy.
//
// Invoked via MSBuild SDK resolver to locate SDK props and targets
// from an msbuild other than the one bundled by the CLI.
//
// Parameters:
//    exe_dir
//      The main directory where SDKs are located in sdk\[version]
//      sub-folders. Pass the directory of a dotnet executable to
//      mimic how that executable would search in its own directory.
//      It is also valid to pass nullptr or empty, in which case
//      multi-level lookup can still search other locations if
//      it has not been disabled by the user's environment.
//
//    working_dir
//      The directory where the search for global.json (which can
//      control the resolved SDK version) starts and proceeds
//      upwards.
//
//    buffer
//      The buffer where the resolved SDK path will be written.
//
//    buffer_size
//      The size of the buffer argument in pal::char_t units.
//
// Return value:
//   <0 - Invalid argument
//   0  - SDK could not be found.
//   >0 - The number of characters (including null terminator)
//        required to store the located SDK.
//
//   If resolution succeeds and the positive return value is less than
//   or equal to buffer_size (i.e. the the buffer is large enough),
//   then the resolved SDK path is copied to the buffer and null
//   terminated. Otherwise, no data is written to the buffer.
//
// String encoding:
//   Windows     - UTF-16 (pal::char_t is 2 byte wchar_t)
//   Unix        - UTF-8  (pal::char_t is 1 byte char)
//
SHARED_API int32_t hostfxr_resolve_sdk(
    const pal::char_t* exe_dir,
    const pal::char_t* working_dir,
    pal::char_t buffer[],
    int32_t buffer_size)
{
    trace::setup();

    trace::info(_X("--- Invoked hostfxr [commit hash: %s] hostfxr_resolve_sdk"), _STRINGIFY(REPO_COMMIT_HASH));

    if (buffer_size < 0 || (buffer_size > 0 && buffer == nullptr))
    {
        trace::error(_X("hostfxr_resolve_sdk received an invalid argument."));
        return -1;
    }

    if (exe_dir == nullptr)
    {
        exe_dir = _X("");
    }

    if (working_dir == nullptr)
    {
        working_dir = _X("");
    }

    pal::string_t cli_sdk;
    if (!fx_muxer_t::resolve_sdk_dotnet_path(exe_dir, working_dir, &cli_sdk))
    {
        // fx_muxer_t::resolve_sdk_dotnet_path handles tracing for this error case.
        return 0;
    }

    if (cli_sdk.size() < buffer_size)
    {
        size_t length = cli_sdk.copy(buffer, buffer_size - 1);
        assert(length == cli_sdk.size());
        assert(length < buffer_size);
        buffer[length] = 0;
    }
    else
    {
        trace::info(_X("hostfxr_resolve_sdk received a buffer that is too small to hold the located SDK path."));
    }

    return cli_sdk.size() + 1;
}

//
// Returns the native directories of the runtime based upon
// the specified app.
//
// Returned format is a list of paths separated by PATH_SEPARATOR
// which is a semicolon (;) on Windows and a colon (:) otherwise.
// The returned string is null-terminated.
//
// Invoked from ASP.NET in order to help load a native assembly
// before the clr is initialized (through a custom host).
//
// Parameters:
//    argc
//      The number of argv arguments
//
//    argv
//      The standard arguments normally passed to dotnet.exe
//      for launching the application.
//
//    buffer
//      The buffer where the native paths and null terminator
//      will be written.
//
//    buffer_size
//      The size of the buffer argument in pal::char_t units.
//
//    required_buffer_size
//      If the return value is HostApiBufferTooSmall, then
//      required_buffer_size is set to the minimium buffer
//      size necessary to contain the result including the
//      null terminator.
//
// Return value:
//   0 on success, otherwise failure
//   0x800080980 - Buffer is too small (HostApiBufferTooSmall)
//
// String encoding:
//   Windows     - UTF-16 (pal::char_t is 2 byte wchar_t)
//   Unix        - UTF-8  (pal::char_t is 1 byte char)
//
SHARED_API int32_t hostfxr_get_native_search_directories(const int argc, const pal::char_t* argv[], pal::char_t buffer[], int32_t buffer_size, int32_t* required_buffer_size)
{
    trace::setup();

    trace::info(_X("--- Invoked hostfxr_get_native_search_directories [commit hash: %s] main"), _STRINGIFY(REPO_COMMIT_HASH));

    if (buffer_size < 0 || (buffer_size > 0 && buffer == nullptr) || required_buffer_size == nullptr)
    {
        trace::error(_X("hostfxr_get_native_search_directories received an invalid argument."));
        return InvalidArgFailure;
    }

    fx_muxer_t muxer;
    int rc = muxer.execute(_X("get-native-search-directories"), argc, argv, buffer, buffer_size, required_buffer_size);
    return rc;
}
<|endoftext|>


<commit_before><commit_msg>fastuidraw/tessellated_path: doxytag fix<commit_after><|endoftext|>


<commit_before><commit_msg>Fix an unbelievably old typo in llkeyboardmacosx.cpp<commit_after><|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2012, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include <sensor_msgs/PointCloud2.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/statistical_outlier_removal.h>

using namespace pcl;
using namespace pcl::io;
using namespace pcl::console;

std::string default_method = "radius";

int default_mean_k = 2;
double default_std_dev_mul = 0.0;
int default_negative = 1;

double default_radius = 0.0;
int default_min_pts = 0;

void
printHelp (int, char **argv)
{
  print_error ("Syntax is: %s input.pcd output.pcd <options>\n", argv[0]);
  print_info ("  where options are:\n");
  print_info ("                     -method X = the outlier removal method to be used (options: radius / statistical) (default: ");
  print_value ("%s", default_method.c_str ()); print_info (")\n");
  print_info ("                     -radius X = (RadiusOutlierRemoval) the sphere radius used for determining the k-nearest neighbors (default: ");
  print_value ("%d", default_min_pts); print_info (")\n");
  print_info ("                     -min_pts X = (RadiusOutlierRemoval) the minimum number of neighbors that a point needs to have in the given search radius in order to be considered an inlier (default: ");
  print_value ("%d", default_min_pts); print_info (")\n");
  print_info ("                     -mean_k X = (StatisticalOutlierRemoval only) the number of points to use for mean distance estimation (default: ");
  print_value ("%d", default_mean_k); print_info (")\n");
  print_info ("                     -std_dev_mul X = (StatisticalOutlierRemoval only) the standard deviation multiplier threshold (default: ");
  print_value ("%f", default_std_dev_mul); print_info (")\n");
  print_info ("                     -inliers X = (StatisticalOutlierRemoval only) decides whether the inliers should be returned (1), or the outliers (0). (default: ");
  print_value ("%d", default_negative); print_info (")\n");
  print_info ("                     -keep_organized = keep the filtered points in organized format.\n");
}

bool
loadCloud (const std::string &filename, sensor_msgs::PointCloud2 &cloud)
{
  TicToc tt;
  print_highlight ("Loading "); print_value ("%s ", filename.c_str ());

  tt.tic ();
  if (loadPCDFile (filename, cloud) < 0)
    return (false);
  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", cloud.width * cloud.height); print_info (" points]\n");
  print_info ("Available dimensions: "); print_value ("%s\n", pcl::getFieldsList (cloud).c_str ());

  return (true);
}

void
compute (const sensor_msgs::PointCloud2::ConstPtr &input, sensor_msgs::PointCloud2 &output,
         std::string method,
         int min_pts, double radius,
         int mean_k, double std_dev_mul, bool negative, bool keep_organized)
{

  PointCloud<PointXYZ>::Ptr xyz_cloud_pre (new pcl::PointCloud<PointXYZ> ()),
      xyz_cloud (new pcl::PointCloud<PointXYZ> ());
  fromROSMsg (*input, *xyz_cloud_pre);

  if (!keep_organized)
  {
    std::vector<int> index_vector;
    removeNaNFromPointCloud<PointXYZ> (*xyz_cloud_pre, *xyz_cloud, index_vector);
  }

  xyz_cloud = xyz_cloud_pre;

  TicToc tt;
  tt.tic ();
  PointCloud<PointXYZ>::Ptr xyz_cloud_filtered (new PointCloud<PointXYZ> ());
  if (method == "statistical")
  {
    StatisticalOutlierRemoval<PointXYZ> filter;
    filter.setInputCloud (xyz_cloud);
    filter.setMeanK (mean_k);
    filter.setStddevMulThresh (std_dev_mul);
    filter.setNegative (negative);
    filter.setKeepOrganized (keep_organized);
    PCL_INFO ("Computing filtered cloud with mean_k %d, std_dev_mul %f, inliers %d\n", filter.getMeanK (), filter.getStddevMulThresh (), filter.getNegative ());
    filter.filter (*xyz_cloud_filtered);
  }
  else if (method == "radius")
  {
    RadiusOutlierRemoval<PointXYZ> filter;
    filter.setInputCloud (xyz_cloud);
    filter.setRadiusSearch (radius);
    filter.setMinNeighborsInRadius (min_pts);
    filter.setKeepOrganized (keep_organized);
    PCL_INFO ("Computing filtered cloud with radius %f, min_pts %d\n", radius, min_pts);
    filter.filter (*xyz_cloud_filtered);
  }
  else
  {
    PCL_ERROR ("%s is not a valid filter name! Quitting!\n", method.c_str ());
    return;
  }

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", xyz_cloud_filtered->width * xyz_cloud_filtered->height); print_info (" points]\n");

  toROSMsg (*xyz_cloud_filtered, output);
}

void
saveCloud (const std::string &filename, const sensor_msgs::PointCloud2 &output)
{
  TicToc tt;
  tt.tic ();

  print_highlight ("Saving "); print_value ("%s ", filename.c_str ());

  pcl::io::savePCDFile (filename, output,  Eigen::Vector4f::Zero (),
                        Eigen::Quaternionf::Identity (), true);

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", output.width * output.height); print_info (" points]\n");
}

/* ---[ */
int
main (int argc, char** argv)
{
  print_info ("Statistical Outlier Removal filtering of a point cloud. For more information, use: %s -h\n", argv[0]);

  if (argc < 3)
  {
    printHelp (argc, argv);
    return (-1);
  }

  // Parse the command line arguments for .pcd files
  std::vector<int> p_file_indices;
  p_file_indices = parse_file_extension_argument (argc, argv, ".pcd");
  if (p_file_indices.size () != 2)
  {
    print_error ("Need one input PCD file and one output PCD file to continue.\n");
    return (-1);
  }

  // Command line parsing
  std::string method = default_method;
  int min_pts = default_min_pts;
  double radius = default_radius;
  int mean_k = default_mean_k;
  double std_dev_mul = default_std_dev_mul;
  int negative = default_negative;

  parse_argument (argc, argv, "-method", method);
  parse_argument (argc, argv, "-radius", radius);
  parse_argument (argc, argv, "-min_pts", min_pts);
  parse_argument (argc, argv, "-mean_k", mean_k);
  parse_argument (argc, argv, "-std_dev_mul", std_dev_mul);
  parse_argument (argc, argv, "-inliers", negative);
  bool keep_organized = find_switch (argc, argv, "-keep_organized");

  // Load the first file
  sensor_msgs::PointCloud2::Ptr cloud (new sensor_msgs::PointCloud2);
  if (!loadCloud (argv[p_file_indices[0]], *cloud))
    return (-1);

  // Do the smoothing
  sensor_msgs::PointCloud2 output;
  compute (cloud, output, method, min_pts, radius, mean_k, std_dev_mul, negative, keep_organized);

  // Save into the second file
  saveCloud (argv[p_file_indices[1]], output);
}
<commit_msg>enhancements for the outlier removal command line tool<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2012, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include <sensor_msgs/PointCloud2.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/extract_indices.h>

using namespace pcl;
using namespace pcl::io;
using namespace pcl::console;

std::string default_method = "radius";

int default_mean_k = 2;
double default_std_dev_mul = 0.0;
int default_negative = 0;

double default_radius = 0.0;
int default_min_pts = 0;

void
printHelp (int, char **argv)
{
  print_error ("Syntax is: %s input.pcd output.pcd <options>\n", argv[0]);
  print_info ("  where options are:\n");
  print_info ("                     -method X = the outlier removal method to be used (options: radius / statistical) (default: ");
  print_value ("%s", default_method.c_str ()); print_info (")\n");
  print_info ("                     -radius X = (RadiusOutlierRemoval) the sphere radius used for determining the k-nearest neighbors (default: ");
  print_value ("%d", default_min_pts); print_info (")\n");
  print_info ("                     -min_pts X = (RadiusOutlierRemoval) the minimum number of neighbors that a point needs to have in the given search radius in order to be considered an inlier (default: ");
  print_value ("%d", default_min_pts); print_info (")\n");
  print_info ("                     -mean_k X = (StatisticalOutlierRemoval only) the number of points to use for mean distance estimation (default: ");
  print_value ("%d", default_mean_k); print_info (")\n");
  print_info ("                     -std_dev_mul X = (StatisticalOutlierRemoval only) the standard deviation multiplier threshold (default: ");
  print_value ("%f", default_std_dev_mul); print_info (")\n\n");
  print_info ("                     -negative X = decides whether the inliers should be returned (1), or the outliers (0). (default: ");
  print_value ("%d", default_negative); print_info (")\n");
  print_info ("                     -keep_organized = keep the filtered points in organized format.\n");
}

bool
loadCloud (const std::string &filename, sensor_msgs::PointCloud2 &cloud,
           Eigen::Vector4f &translation, Eigen::Quaternionf &orientation)
{
  TicToc tt;
  print_highlight ("Loading "); print_value ("%s ", filename.c_str ());

  tt.tic ();
  if (loadPCDFile (filename, cloud, translation, orientation) < 0)
    return (false);
  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", cloud.width * cloud.height); print_info (" points]\n");
  print_info ("Available dimensions: "); print_value ("%s\n", pcl::getFieldsList (cloud).c_str ());

  return (true);
}

void
compute (const sensor_msgs::PointCloud2::ConstPtr &input, sensor_msgs::PointCloud2 &output,
         std::string method,
         int min_pts, double radius,
         int mean_k, double std_dev_mul, bool negative, bool keep_organized)
{

  PointCloud<PointXYZ>::Ptr xyz_cloud_pre (new pcl::PointCloud<PointXYZ> ()),
                            xyz_cloud (new pcl::PointCloud<PointXYZ> ());
  fromROSMsg (*input, *xyz_cloud_pre);

  pcl::PointIndices::Ptr removed_indices (new PointIndices),
                         indices (new PointIndices);
  std::vector<int> valid_indices;
  if (keep_organized)
  {
    xyz_cloud = xyz_cloud_pre;
    for (int i = 0; i < int (xyz_cloud->size ()); ++i)
      valid_indices.push_back (i);
  }
  else
    removeNaNFromPointCloud<PointXYZ> (*xyz_cloud_pre, *xyz_cloud, valid_indices);

  TicToc tt;
  tt.tic ();
  PointCloud<PointXYZ>::Ptr xyz_cloud_filtered (new PointCloud<PointXYZ> ());
  if (method == "statistical")
  {
    StatisticalOutlierRemoval<PointXYZ> filter (true);
    filter.setInputCloud (xyz_cloud);
    filter.setMeanK (mean_k);
    filter.setStddevMulThresh (std_dev_mul);
    filter.setNegative (negative);
    filter.setKeepOrganized (keep_organized);
    PCL_INFO ("Computing filtered cloud from %zu points with mean_k %d, std_dev_mul %f, inliers %d ...", xyz_cloud->size (), filter.getMeanK (), filter.getStddevMulThresh (), filter.getNegative ());
    filter.filter (*xyz_cloud_filtered);
    // Get the indices that have been explicitly removed
    filter.getRemovedIndices (*removed_indices);
  }
  else if (method == "radius")
  {
    RadiusOutlierRemoval<PointXYZ> filter (true);
    filter.setInputCloud (xyz_cloud);
    filter.setRadiusSearch (radius);
    filter.setMinNeighborsInRadius (min_pts);
    filter.setNegative (negative);
    filter.setKeepOrganized (keep_organized);
    PCL_INFO ("Computing filtered cloud from %zu points with radius %f, min_pts %d ...", xyz_cloud->size (), radius, min_pts);
    filter.filter (*xyz_cloud_filtered);
    // Get the indices that have been explicitly removed
    filter.getRemovedIndices (*removed_indices);
  }
  else
  {
    PCL_ERROR ("%s is not a valid filter name! Quitting!\n", method.c_str ());
    return;
  }

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", xyz_cloud_filtered->width * xyz_cloud_filtered->height); print_info (" points, %zu indices removed]\n", removed_indices->indices.size ());

  if (keep_organized)
  {
    sensor_msgs::PointCloud2 output_filtered;
    toROSMsg (*xyz_cloud_filtered, output_filtered);
    concatenateFields (*input, output_filtered, output);
  }
  else
  {
    // Make sure we are addressing values in the original index vector
    for (size_t i = 0; i < removed_indices->indices.size (); ++i)
      indices->indices.push_back (valid_indices[removed_indices->indices[i]]);

    // Extract the indices of the remaining points
    pcl::ExtractIndices<sensor_msgs::PointCloud2> ei;
    ei.setInputCloud (input);
    ei.setIndices (indices);
    ei.setNegative (true);
    ei.filter (output);
  }
}

void
saveCloud (const std::string &filename, const sensor_msgs::PointCloud2 &output,
           const Eigen::Vector4f &translation, const Eigen::Quaternionf &rotation)
{
  TicToc tt;
  tt.tic ();

  print_highlight ("Saving "); print_value ("%s ", filename.c_str ());

  PCDWriter w;
  w.writeBinaryCompressed (filename, output, translation, rotation);

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", output.width * output.height); print_info (" points]\n");
}

/* ---[ */
int
main (int argc, char** argv)
{
  print_info ("Statistical Outlier Removal filtering of a point cloud. For more information, use: %s -h\n", argv[0]);

  if (argc < 3)
  {
    printHelp (argc, argv);
    return (-1);
  }

  // Parse the command line arguments for .pcd files
  std::vector<int> p_file_indices;
  p_file_indices = parse_file_extension_argument (argc, argv, ".pcd");
  if (p_file_indices.size () != 2)
  {
    print_error ("Need one input PCD file and one output PCD file to continue.\n");
    return (-1);
  }

  // Command line parsing
  std::string method = default_method;
  int min_pts = default_min_pts;
  double radius = default_radius;
  int mean_k = default_mean_k;
  double std_dev_mul = default_std_dev_mul;
  int negative = default_negative;

  parse_argument (argc, argv, "-method", method);
  parse_argument (argc, argv, "-radius", radius);
  parse_argument (argc, argv, "-min_pts", min_pts);
  parse_argument (argc, argv, "-mean_k", mean_k);
  parse_argument (argc, argv, "-std_dev_mul", std_dev_mul);
  parse_argument (argc, argv, "-negative", negative);
  bool keep_organized = find_switch (argc, argv, "-keep_organized");

  // Load the first file
  Eigen::Vector4f translation;
  Eigen::Quaternionf rotation;
  sensor_msgs::PointCloud2::Ptr cloud (new sensor_msgs::PointCloud2);
  if (!loadCloud (argv[p_file_indices[0]], *cloud, translation, rotation))
    return (-1);

  if (keep_organized && cloud->height == 1)
  {
    print_error ("Point cloud dataset (%s) is not organized (height = %d), but -keep_organized requested!\n", argv[p_file_indices[0]], cloud->height);
    return (-1);
  }

  // Do the smoothing
  sensor_msgs::PointCloud2 output;
  compute (cloud, output, method, min_pts, radius, mean_k, std_dev_mul, negative, keep_organized);

  // Save into the second file
  saveCloud (argv[p_file_indices[1]], output, translation, rotation);
}
<|endoftext|>


<commit_before>// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// 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 "client/crashpad_info.h"

#include <mach-o/loader.h>

#include "util/stdlib/cxx.h"

#if CXX_LIBRARY_VERSION >= 2011
#include <type_traits>
#endif

namespace {

static const uint32_t kCrashpadInfoVersion = 1;

}  // namespace

namespace crashpad {

#if CXX_LIBRARY_VERSION >= 2011 || DOXYGEN
// In C++11, check that CrashpadInfo has standard layout, which is what is
// actually important.
static_assert(std::is_standard_layout<CrashpadInfo>::value,
              "CrashpadInfo must be standard layout");
#else
// In C++98 (ISO 14882), section 9.5.1 says that a union cannot have a member
// with a non-trivial ctor, copy ctor, dtor, or assignment operator. Use this
// property to ensure that CrashpadInfo remains POD. This doesn’t work for C++11
// because the requirements for unions have been relaxed.
union Compile_Assert {
  CrashpadInfo Compile_Assert__CrashpadInfo_must_be_pod;
};
#endif

// Put the structure in __DATA,__crashpad_info where it can be easily found
// without having to consult the symbol table. The “used” attribute prevents it
// from being dead-stripped. This isn’t placed in an unnamed namespace:
// hopefully, this will catch attempts to place multiple copies of this
// structure into the same module. If that’s attempted, and the name of the
// symbol is the same in each translation unit, it will result in a linker
// error, which is better than having multiple structures show up.
//
// This may result in a static module initializer in debug-mode builds, but
// because it’s POD, no code should need to run to initialize this under
// release-mode optimization.
__attribute__((section(SEG_DATA ",__crashpad_info"),
               used,
               visibility("hidden"))) CrashpadInfo g_crashpad_info;

// static
CrashpadInfo* CrashpadInfo::GetCrashpadInfo() {
  return &g_crashpad_info;
}

CrashpadInfo::CrashpadInfo()
    : signature_(kSignature),
      size_(sizeof(*this)),
      version_(kCrashpadInfoVersion),
      padding_0_(0),
      simple_annotations_(nullptr) {
}

const uint32_t CrashpadInfo::kSignature;

}  // namespace crashpad
<commit_msg>win: Get client/crashpad_info.cc to compile<commit_after>// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// 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 "client/crashpad_info.h"

#include "build/build_config.h"
#include "util/stdlib/cxx.h"

#if defined(OS_MACOSX)
#include <mach-o/loader.h>
#endif

#if CXX_LIBRARY_VERSION >= 2011
#include <type_traits>
#endif

namespace {

static const uint32_t kCrashpadInfoVersion = 1;

}  // namespace

namespace crashpad {

#if CXX_LIBRARY_VERSION >= 2011 || DOXYGEN
// In C++11, check that CrashpadInfo has standard layout, which is what is
// actually important.
static_assert(std::is_standard_layout<CrashpadInfo>::value,
              "CrashpadInfo must be standard layout");
#else
// In C++98 (ISO 14882), section 9.5.1 says that a union cannot have a member
// with a non-trivial ctor, copy ctor, dtor, or assignment operator. Use this
// property to ensure that CrashpadInfo remains POD. This doesn’t work for C++11
// because the requirements for unions have been relaxed.
union Compile_Assert {
  CrashpadInfo Compile_Assert__CrashpadInfo_must_be_pod;
};
#endif

// This structure needs to be stored somewhere that is easy to find without
// external information.
//
// It isn’t placed in an unnamed namespace: hopefully, this will catch attempts
// to place multiple copies of this structure into the same module. If that’s
// attempted, and the name of the symbol is the same in each translation unit,
// it will result in a linker error, which is better than having multiple
// structures show up.
//
// This may result in a static module initializer in debug-mode builds, but
// because it’s POD, no code should need to run to initialize this under
// release-mode optimization.
#if defined(OS_MACOSX)

// Put the structure in __DATA,__crashpad_info where it can be easily found
// without having to consult the symbol table. The “used” attribute prevents it
// from being dead-stripped.
__attribute__((section(SEG_DATA ",__crashpad_info"),
               used,
               visibility("hidden"))) CrashpadInfo g_crashpad_info;

#elif defined(OS_WIN)

// TODO(scottmg): Tag in a way that makes it easy to locate on Windows.
CrashpadInfo g_crashpad_info;

#endif

// static
CrashpadInfo* CrashpadInfo::GetCrashpadInfo() {
  return &g_crashpad_info;
}

CrashpadInfo::CrashpadInfo()
    : signature_(kSignature),
      size_(sizeof(*this)),
      version_(kCrashpadInfoVersion),
      padding_0_(0),
      simple_annotations_(nullptr) {
}

const uint32_t CrashpadInfo::kSignature;

}  // namespace crashpad
<|endoftext|>


<commit_before>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */

#include <cn24.h>

#include <iostream>
#include <fstream>

struct CompressedTensor {
public:
  unsigned int compressed_length;
  void* compressed_data;
};

const unsigned char rl_marker = 'X';
const unsigned char rl_doublemarker = 'X';
const unsigned char rl_rle = 'Y';
const unsigned int rl_bytes = 1;
const unsigned int chars_per_datum = sizeof(Conv::datum)/sizeof(char);
const unsigned int rl_max = (unsigned int)((1L << (8L * (unsigned long)rl_bytes)) - 3L);
const unsigned int rl_min = 1 + (5 + rl_bytes) / chars_per_datum;

void Compress(const Conv::Tensor& tensor, CompressedTensor* compressed);
unsigned int Decompress(Conv::Tensor& tensor, CompressedTensor* compressed);

int main(int argc, char** argv) {
  Conv::System::Init();

  if(argc != 2) {
    FATAL("Needs exactly two arguments!");
  }

  LOGINFO << "rl_bytes: " << rl_bytes;
  LOGINFO << "rl_max  : " << rl_max;
  LOGINFO << "rl_min  : " << rl_min;

  CompressedTensor compressed;
  std::string input_file_name(argv[1]);
  //std::string output_file_name(argv[2]);

  std::ifstream input_tensor_stream(input_file_name);
  //std::ofstream output_tensor_stream(output_file_name);
  if(!input_tensor_stream.good())
    FATAL("Cannot open " << input_file_name);

  long uncompressed_total = 0;
  long compressed_total = 0;

  Conv::Tensor tensor;
  while(!input_tensor_stream.eof()) {
    tensor.Deserialize(input_tensor_stream);

    LOGDEBUG << "Input tensor: " << tensor;

    LOGDEBUG << "Size: " << tensor.elements() * sizeof(Conv::datum)/sizeof(char);

    Compress(tensor, &compressed);
    LOGDEBUG << "RLE Size: " << compressed.compressed_length;
    unsigned int bytes_out = Decompress(tensor, &compressed);

    //tensor.Serialize(output_tensor_stream,false);

    free(compressed.compressed_data);

    if(bytes_out != (tensor.elements() * sizeof(Conv::datum)/sizeof(char))) {
      FATAL("Size mismatch! Expected: " << (tensor.elements() * sizeof(Conv::datum)/sizeof(char)) << ", actual: " << bytes_out);
    }

    LOGINFO << "Ratio: " << 100.0 * (double)compressed.compressed_length / (double)(tensor.elements() * sizeof(Conv::datum)/sizeof(char)) << "%" << std::flush;
    compressed_total += compressed.compressed_length;
    uncompressed_total += tensor.elements() * sizeof(Conv::datum)/sizeof(char);

    input_tensor_stream.peek();
  }
  LOGINFO << "Overall ratio: " << 100.0 * (double)compressed_total / (double)uncompressed_total << "%";
  LOGINFO << "Uncompressed: " << uncompressed_total;
  LOGINFO << "Compressed  : " << compressed_total;
  LOGEND;
}

void Compress(const Conv::Tensor& tensor, CompressedTensor* compressed) {

  unsigned int bytes_out = 0;

  Conv::datum last_symbol = 0;
  unsigned int running_length = 0;

  unsigned char* output_ptr = new unsigned char[2 * tensor.elements() * chars_per_datum];
  compressed->compressed_data = (void*)output_ptr;
  for(unsigned int pos = 0; pos <= tensor.elements(); pos++) {
    Conv::datum current_symbol;
    if(pos < tensor.elements()) {
      current_symbol = tensor.data_ptr_const()[pos];
      if(current_symbol == last_symbol) {
        // Increase running length
        running_length++;
      }
    } else {
      // Force emission of last symbol
    }

    if(
    // EOF reached
    (pos == (tensor.elements())) ||
    // Different symbol
    (current_symbol != last_symbol) ||
    // Maxmimum run length reached
    (running_length == rl_max)) {

      // Emit...
      if(running_length > 0 && running_length < rl_min) {
        // Emit single symbol(s)
        for(unsigned int r = 0; r < running_length; r++) {
          for(unsigned int b = 0; b < chars_per_datum; b++) {
            char char_to_emit = ((char*)&last_symbol)[b];
            if(char_to_emit == rl_marker) {
              // Emit escaped
              *output_ptr = rl_marker;
              output_ptr++; bytes_out++;
              *output_ptr = rl_doublemarker;
              output_ptr++; bytes_out++;
            } else {
              // Emit directly
              *output_ptr = char_to_emit;
              output_ptr++; bytes_out++;
            }
          }
        }
      } else if(running_length >= rl_min) {
        // Emit encoded
        *output_ptr = rl_marker;
        output_ptr++; bytes_out++;
        *output_ptr = rl_rle;
        output_ptr++; bytes_out++;

        // Running length output
        for(unsigned int b = 0; b < rl_bytes; b++) {
          *output_ptr = (running_length >> ((rl_bytes - (b+1)) * 8)) & 0xFF;
          output_ptr++; bytes_out++;
        }

        for(unsigned int b = 0; b < chars_per_datum; b++) {
          unsigned char char_to_emit = ((char*)&last_symbol)[b];
          *output_ptr = char_to_emit;
          output_ptr++; bytes_out++;
        }
      }

      // ...and reset
      if(running_length == rl_max)
        running_length = 0;
      else
        running_length = 1;
    }

    last_symbol = current_symbol;
  }
  LOGDEBUG << "Bytes out: " << bytes_out;
  compressed->compressed_length = bytes_out;

}

unsigned int Decompress(Conv::Tensor& tensor, CompressedTensor* compressed) {
  unsigned int bytes_out = 0;
  unsigned char* output_ptr = (unsigned char*)tensor.data_ptr();
  const unsigned char* input_ptr = (const unsigned char*)compressed->compressed_data;

  for(unsigned int pos = 0; pos < compressed->compressed_length; pos++) {
    unsigned char current_symbol = input_ptr[pos];
    if(current_symbol == rl_marker) {
      pos++; current_symbol = input_ptr[pos];
      if(current_symbol == rl_doublemarker) {
        // Emit single marker
        *output_ptr = rl_marker;
        output_ptr++; bytes_out++;
      } else if(current_symbol == rl_rle) {
        unsigned int running_length = 0;

        // Running length input
        for(unsigned int b = 0; b < rl_bytes; b++) {
          pos++; current_symbol = input_ptr[pos];
          running_length += current_symbol;
          if((b+1) != rl_bytes)
            running_length <<= 8;
        }

        for(unsigned int r = 0; r < running_length; r++) {
          for(unsigned int b = 0; b < chars_per_datum; b++) {
            pos++; current_symbol = input_ptr[pos];
            *output_ptr = current_symbol;
            output_ptr++; bytes_out++;
          }
          pos -= chars_per_datum;
        }
        pos += chars_per_datum;
      } else {
        FATAL("Incorrect encoding!");
      }
    } else {
      // Emit directly
      *output_ptr = current_symbol;
      output_ptr++; bytes_out++;
    }
  }
  LOGDEBUG << "Bytes out: " << bytes_out;
  return bytes_out;
}<commit_msg>testCompression: Now serializes a compressed TensorStream<commit_after>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */

#include <cn24.h>

#include <iostream>
#include <fstream>

int main(int argc, char** argv) {
  Conv::System::Init();

  if(argc != 3) {
    FATAL("Needs exactly two arguments");
  }

  std::string input_file_name(argv[1]);
  std::string output_file_name(argv[2]);

  std::ifstream input_tensor_stream(input_file_name, std::ios::in | std::ios::binary);
  std::ofstream output_tensor_stream(output_file_name, std::ios::out | std::ios::binary);

  if(!input_tensor_stream.good())
    FATAL("Cannot open " << input_file_name);

  if(!output_tensor_stream.good())
    FATAL("Cannot open " << output_file_name);

  long uncompressed_total = 0;
  long compressed_total = 0;

  Conv::Tensor tensor;
  while(!input_tensor_stream.eof()) {
    tensor.Deserialize(input_tensor_stream);

    LOGDEBUG << "Input tensor: " << tensor;

    unsigned int original_size = tensor.elements() * sizeof(Conv::datum)/sizeof(char);
    LOGDEBUG << "Size: " << original_size;

    Conv::CompressedTensor ctensor;
    ctensor.Compress(tensor);

    ctensor.Serialize(output_tensor_stream);

    LOGDEBUG << "RLE Size: " << ctensor.compressed_length();

    ctensor.Decompress(tensor);
    unsigned int bytes_out = tensor.elements() * sizeof(Conv::datum)/sizeof(char);

    if(bytes_out != original_size) {
      FATAL("Size mismatch! Expected: " << (tensor.elements() * sizeof(Conv::datum)/sizeof(char)) << ", actual: " << bytes_out);
    }

    LOGINFO << "Ratio: " << 100.0 * (double)ctensor.compressed_length() / (double)(tensor.elements() * sizeof(Conv::datum)/sizeof(char)) << "%" << std::flush;
    compressed_total += ctensor.compressed_length();
    uncompressed_total += tensor.elements() * sizeof(Conv::datum)/sizeof(char);

    input_tensor_stream.peek();
  }
  LOGINFO << "Overall ratio: " << 100.0 * (double)compressed_total / (double)uncompressed_total << "%";
  LOGINFO << "Uncompressed: " << uncompressed_total;
  LOGINFO << "Compressed  : " << compressed_total;
  LOGEND;
}<|endoftext|>


<commit_before>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/debug/leak_annotations.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/render_view_test.h"
#include "content/public/test/test_utils.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_view_impl.h"
#include "content/test/fake_compositor_dependencies.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"

namespace {
const int32 kSubframeRouteId = 20;
const int32 kSubframeWidgetRouteId = 21;
const int32 kFrameProxyRouteId = 22;
const int32 kSubframeSurfaceId = 43;
}  // namespace

namespace content {

// RenderFrameImplTest creates a RenderFrameImpl that is a child of the
// main frame, and has its own RenderWidget. This behaves like an out
// of process frame even though it is in the same process as its parent.
class RenderFrameImplTest : public RenderViewTest {
 public:
  ~RenderFrameImplTest() override {}

  void SetUp() override {
    RenderViewTest::SetUp();
    EXPECT_FALSE(static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame())
                     ->is_subframe_);

    FrameMsg_NewFrame_WidgetParams widget_params;
    widget_params.routing_id = kSubframeWidgetRouteId;
    widget_params.surface_id = kSubframeSurfaceId;
    widget_params.hidden = false;

    IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());

    LoadHTML("Parent frame ");

    RenderFrameImpl::FromWebFrame(
        view_->GetMainRenderFrame()->GetWebFrame()->firstChild())
        ->OnSwapOut(kFrameProxyRouteId, false, FrameReplicationState());

    RenderFrameImpl::CreateFrame(kSubframeRouteId, kFrameProxyRouteId,
                                 MSG_ROUTING_NONE, MSG_ROUTING_NONE,
                                 FrameReplicationState(), &compositor_deps_,
                                 widget_params);

    frame_ = RenderFrameImpl::FromRoutingID(kSubframeRouteId);
    EXPECT_TRUE(frame_->is_subframe_);
  }

  void TearDown() override {
#if defined(LEAK_SANITIZER)
     // Do this before shutting down V8 in RenderViewTest::TearDown().
     // http://crbug.com/328552
     __lsan_do_leak_check();
#endif
     RenderViewTest::TearDown();
  }

  RenderFrameImpl* frame() { return frame_; }

  content::RenderWidget* frame_widget() const {
    return frame_->render_widget_.get();
  }

 private:
  RenderFrameImpl* frame_;
  FakeCompositorDependencies compositor_deps_;
};

class RenderFrameTestObserver : public RenderFrameObserver {
 public:
  explicit RenderFrameTestObserver(RenderFrame* render_frame)
      : RenderFrameObserver(render_frame), visible_(false) {}

  ~RenderFrameTestObserver() override {}

  void WasShown() override { visible_ = true; }
  void WasHidden() override { visible_ = false; }

  bool visible() { return visible_; }

 private:
  bool visible_;
};

#if defined(OS_ANDROID)
// See https://crbug.com/472717
#define MAYBE_SubframeWidget DISABLED_SubframeWidget
#define MAYBE_FrameResize DISABLED_FrameResize
#define MAYBE_FrameWasShown DISABLED_FrameWasShown
#else
#define MAYBE_SubframeWidget SubframeWidget
#define MAYBE_FrameResize FrameResize
#define MAYBE_FrameWasShown FrameWasShown
#endif

// Verify that a frame with a RenderFrameProxy as a parent has its own
// RenderWidget.
TEST_F(RenderFrameImplTest, MAYBE_SubframeWidget) {
  EXPECT_TRUE(frame_widget());
  EXPECT_NE(frame_widget(), (content::RenderWidget*)view_);
}

// Verify a subframe RenderWidget properly processes its viewport being
// resized.
TEST_F(RenderFrameImplTest, MAYBE_FrameResize) {
  ViewMsg_Resize_Params resize_params;
  gfx::Size size(200, 200);
  resize_params.screen_info = blink::WebScreenInfo();
  resize_params.new_size = size;
  resize_params.physical_backing_size = size;
  resize_params.top_controls_height = 0.f;
  resize_params.top_controls_shrink_blink_size = false;
  resize_params.resizer_rect = gfx::Rect();
  resize_params.is_fullscreen_granted = false;

  ViewMsg_Resize resize_message(0, resize_params);
  frame_widget()->OnMessageReceived(resize_message);

  EXPECT_EQ(frame_widget()->webwidget()->size(), blink::WebSize(size));
}

// Verify a subframe RenderWidget properly processes a WasShown message.
TEST_F(RenderFrameImplTest, MAYBE_FrameWasShown) {
  RenderFrameTestObserver observer(frame());

  ViewMsg_WasShown was_shown_message(0, true, ui::LatencyInfo());
  frame_widget()->OnMessageReceived(was_shown_message);

  EXPECT_FALSE(frame_widget()->is_hidden());
  EXPECT_TRUE(observer.visible());
}

}  // namespace
<commit_msg>Fix invalid C-style cast in RenderFrameImplTest.<commit_after>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/debug/leak_annotations.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/render_view_test.h"
#include "content/public/test/test_utils.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_view_impl.h"
#include "content/test/fake_compositor_dependencies.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"

namespace {
const int32 kSubframeRouteId = 20;
const int32 kSubframeWidgetRouteId = 21;
const int32 kFrameProxyRouteId = 22;
const int32 kSubframeSurfaceId = 43;
}  // namespace

namespace content {

// RenderFrameImplTest creates a RenderFrameImpl that is a child of the
// main frame, and has its own RenderWidget. This behaves like an out
// of process frame even though it is in the same process as its parent.
class RenderFrameImplTest : public RenderViewTest {
 public:
  ~RenderFrameImplTest() override {}

  void SetUp() override {
    RenderViewTest::SetUp();
    EXPECT_FALSE(static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame())
                     ->is_subframe_);

    FrameMsg_NewFrame_WidgetParams widget_params;
    widget_params.routing_id = kSubframeWidgetRouteId;
    widget_params.surface_id = kSubframeSurfaceId;
    widget_params.hidden = false;

    IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());

    LoadHTML("Parent frame ");

    RenderFrameImpl::FromWebFrame(
        view_->GetMainRenderFrame()->GetWebFrame()->firstChild())
        ->OnSwapOut(kFrameProxyRouteId, false, FrameReplicationState());

    RenderFrameImpl::CreateFrame(kSubframeRouteId, kFrameProxyRouteId,
                                 MSG_ROUTING_NONE, MSG_ROUTING_NONE,
                                 FrameReplicationState(), &compositor_deps_,
                                 widget_params);

    frame_ = RenderFrameImpl::FromRoutingID(kSubframeRouteId);
    EXPECT_TRUE(frame_->is_subframe_);
  }

  void TearDown() override {
#if defined(LEAK_SANITIZER)
     // Do this before shutting down V8 in RenderViewTest::TearDown().
     // http://crbug.com/328552
     __lsan_do_leak_check();
#endif
     RenderViewTest::TearDown();
  }

  RenderFrameImpl* frame() { return frame_; }

  content::RenderWidget* frame_widget() const {
    return frame_->render_widget_.get();
  }

 private:
  RenderFrameImpl* frame_;
  FakeCompositorDependencies compositor_deps_;
};

class RenderFrameTestObserver : public RenderFrameObserver {
 public:
  explicit RenderFrameTestObserver(RenderFrame* render_frame)
      : RenderFrameObserver(render_frame), visible_(false) {}

  ~RenderFrameTestObserver() override {}

  void WasShown() override { visible_ = true; }
  void WasHidden() override { visible_ = false; }

  bool visible() { return visible_; }

 private:
  bool visible_;
};

#if defined(OS_ANDROID)
// See https://crbug.com/472717
#define MAYBE_SubframeWidget DISABLED_SubframeWidget
#define MAYBE_FrameResize DISABLED_FrameResize
#define MAYBE_FrameWasShown DISABLED_FrameWasShown
#else
#define MAYBE_SubframeWidget SubframeWidget
#define MAYBE_FrameResize FrameResize
#define MAYBE_FrameWasShown FrameWasShown
#endif

// Verify that a frame with a RenderFrameProxy as a parent has its own
// RenderWidget.
TEST_F(RenderFrameImplTest, MAYBE_SubframeWidget) {
  EXPECT_TRUE(frame_widget());
  // We can't convert to RenderWidget* directly, because
  // it and RenderView are two unrelated base classes
  // of RenderViewImpl. If a class has multiple base classes,
  // each base class pointer will be distinct, and direct casts
  // between unrelated base classes are undefined, even if they share
  // a common derived class. The compiler has no way in general of
  // determining the displacement between the two classes, so these
  // types of casts cannot be implemented in a type safe way.
  // To overcome this, we make two legal static casts:
  // first, downcast from RenderView* to RenderViewImpl*,
  // then upcast from RenderViewImpl* to RenderWidget*.
  EXPECT_NE(frame_widget(),
            static_cast<content::RenderWidget*>(
                static_cast<content::RenderViewImpl*>((view_))));
}

// Verify a subframe RenderWidget properly processes its viewport being
// resized.
TEST_F(RenderFrameImplTest, MAYBE_FrameResize) {
  ViewMsg_Resize_Params resize_params;
  gfx::Size size(200, 200);
  resize_params.screen_info = blink::WebScreenInfo();
  resize_params.new_size = size;
  resize_params.physical_backing_size = size;
  resize_params.top_controls_height = 0.f;
  resize_params.top_controls_shrink_blink_size = false;
  resize_params.resizer_rect = gfx::Rect();
  resize_params.is_fullscreen_granted = false;

  ViewMsg_Resize resize_message(0, resize_params);
  frame_widget()->OnMessageReceived(resize_message);

  EXPECT_EQ(frame_widget()->webwidget()->size(), blink::WebSize(size));
}

// Verify a subframe RenderWidget properly processes a WasShown message.
TEST_F(RenderFrameImplTest, MAYBE_FrameWasShown) {
  RenderFrameTestObserver observer(frame());

  ViewMsg_WasShown was_shown_message(0, true, ui::LatencyInfo());
  frame_widget()->OnMessageReceived(was_shown_message);

  EXPECT_FALSE(frame_widget()->is_hidden());
  EXPECT_TRUE(observer.visible());
}

}  // namespace
<|endoftext|>


<commit_before>// Copyright (C) 2017 - 2018 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2010 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"

#include "COptMethodSteepestDescent.h"
#include "COptProblem.h"
#include "COptItem.h"
#include "COptTask.h"

#include "FminBrent.h"

#include "copasi/core/CDataObjectReference.h"

COptMethodSteepestDescent::COptMethodSteepestDescent(const CDataContainer * pParent,
    const CTaskEnum::Method & methodType,
    const CTaskEnum::Task & taskType):
  COptMethod(pParent, methodType, taskType),
  mIterations(100),
  mTolerance(1e-6),
  mContinue(true),
  mBestValue(std::numeric_limits< C_FLOAT64 >::infinity()),
  mValue(0.0),
  mVariableSize(0),
  mIndividual(0),
  mGradient(0),
  mpDescent(new FDescentTemplate<COptMethodSteepestDescent>(this, &COptMethodSteepestDescent::descentLine)),
  mCurrentIteration(0)
{
  addParameter("Iteration Limit", CCopasiParameter::Type::UINT, (unsigned C_INT32) 100);
  addParameter("Tolerance", CCopasiParameter::Type::DOUBLE, (C_FLOAT64) 1e-6);
}

COptMethodSteepestDescent::COptMethodSteepestDescent(const COptMethodSteepestDescent & src,
    const CDataContainer * pParent): COptMethod(src, pParent),
  mIterations(src.mIterations),
  mTolerance(src.mTolerance),
  mContinue(src.mContinue),
  mBestValue(src.mBestValue),
  mValue(src.mValue),
  mVariableSize(src.mVariableSize),
  mIndividual(src.mIndividual),
  mGradient(src.mGradient),
  mpDescent(new FDescentTemplate<COptMethodSteepestDescent>(this, &COptMethodSteepestDescent::descentLine)),
  mCurrentIteration(src.mCurrentIteration)
{}

COptMethodSteepestDescent::~COptMethodSteepestDescent()
{
  pdelete(mpDescent);

  cleanup();
}

bool COptMethodSteepestDescent::optimise()
{
  if (!initialize()) return false;

  mMethodLog.enterLogItem(COptLogItem(COptLogItem::STD_start).with("Steepest_Descent/"));

  size_t i, k;
  C_FLOAT64 tmp, x0, alpha, mn, mx, fmn, fmx;
  bool calc_grad;

  // initial point is first guess but we have to make sure that we
  // are within the parameter domain
  bool pointInParameterDomain = true;

  for (i = 0; i < mVariableSize; i++)
    {
      const COptItem & OptItem = *(*mpOptItem)[i];

      switch (OptItem.checkConstraint(OptItem.getStartValue()))
        {
          case - 1:
            mIndividual[i] = *OptItem.getLowerBoundValue();
            pointInParameterDomain = false;
            break;

          case 1:
            mIndividual[i] = *OptItem.getUpperBoundValue();
            pointInParameterDomain = false;
            break;

          case 0:
            mIndividual[i] = OptItem.getStartValue();
            break;
        }

      *mContainerVariables[i] = mIndividual[i];
    }

  if (!pointInParameterDomain) mMethodLog.enterLogItem(COptLogItem(COptLogItem::STD_initial_point_out_of_domain));

  fmx = mBestValue = evaluate();

  mContinue = mpOptProblem->setSolution(mBestValue, mIndividual);

  // We found a new best value lets report it.
  //if (mpReport) mpReport->printBody();
  mpParentTask->output(COutputInterface::DURING);

  bool SolutionFound = false;

  for (mCurrentIteration = 0; mCurrentIteration < mIterations && mContinue && !SolutionFound; mCurrentIteration++)
    {
      // calculate the direction of steepest descent
      // by central finite differences
      gradient();
      // minimise the function in this direction
      // find brackets for the minimisation
      //  mn = 0.0; md = 1.0;
      //  mnbrak(&mn, &md, &mx, &fmn, &fmd, &fmx, descent_line);
      // make sure that no parameter will exceed its bounds
      x0 = std::numeric_limits< C_FLOAT64 >::max();

      for (i = 0; i < mVariableSize; i++)
        {
          if (fabs(mGradient[i]) > std::numeric_limits< C_FLOAT64 >::epsilon())
            {
              if (mGradient[i] > 0)
                {
                  tmp = *(*mpOptItem)[i]->getUpperBoundValue();
                }

              else
                {
                  tmp = *(*mpOptItem)[i]->getLowerBoundValue();
                }

              // calculate the size of the largest jump
              tmp = (tmp - mIndividual[i]) / mGradient[i];

              // keep it if it is the smallest
              if (tmp < x0) x0 = tmp;
            }
          else mGradient[i] = 0.0;
        }

      if (x0 < mTolerance) x0 = mTolerance;

      // we will move at a rate of 1/10 this size
      mn = mx = alpha = 0.0;

      for (k = 0, calc_grad = false; (k < 9) && !calc_grad && !SolutionFound; k++)
        {
          // set the minimum to the last successful step
          mn = mx;
          fmn = fmx;
          // increment alpha
          alpha += 0.1 * x0;
          // set the maximum to it
          mx = alpha;

          // take one step in that direction
          fmx = descentLine(alpha);

          fmx = evaluate();

          // if this was an upward step find the minimum
          if (fmx > fmn)
            {
              //md = mn + (mx-mn)/2;
              //Brent(mn, md, mx, descent_line, &alpha, &tmp, 1e-6, 50);

              FminBrent(mn, mx, mpDescent, &alpha, &tmp, mTolerance, 5);

              // take one step in that direction
              fmx = descentLine(alpha);

              // time to evaluate the new steepest descent direction
              calc_grad = true;
            }

          if (fabs(fmx - mBestValue) < mTolerance)
            SolutionFound = true;
        }

      for (i = 0; i < mVariableSize; i++)
        mIndividual[i] = *(*mpOptItem)[i]->getObjectValue();

      if (fmx < mBestValue)
        {
          mBestValue = fmx;

          mContinue = mpOptProblem->setSolution(mBestValue, mIndividual);

          // We found a new best value lets report it.
          //if (mpReport) mpReport->printBody();
          mpParentTask->output(COutputInterface::DURING);
        }
    }

  mMethodLog.enterLogItem(COptLogItem(COptLogItem::STD_finish_x_of_max_iter).iter(mCurrentIteration).with(mIterations));

  return true;
}

bool COptMethodSteepestDescent::cleanup()
{
  // pdelete all used variables
  return true;
}

bool COptMethodSteepestDescent::initialize()
{
  cleanup();

  if (!COptMethod::initialize()) return false;

  mIterations = getValue< unsigned C_INT32 >("Iteration Limit");
  mTolerance = getValue< C_FLOAT64 >("Tolerance");

  mContinue = true;
  mVariableSize = mpOptItem->size();
  mIndividual.resize(mVariableSize);
  mGradient.resize(mVariableSize);

  mBestValue = std::numeric_limits<C_FLOAT64>::infinity();

  return true;
}

void COptMethodSteepestDescent::gradient()
{

  C_FLOAT64 **ppContainerVariable = mContainerVariables.array();
  C_FLOAT64 **ppContainerVariableEnd = ppContainerVariable + mVariableSize;
  C_FLOAT64 * pGradient = mGradient.array();

  C_FLOAT64 y;
  C_FLOAT64 x;

  y = evaluate();

  for (; ppContainerVariable != ppContainerVariableEnd; ++ppContainerVariable, ++pGradient)
    {
      if ((x = **ppContainerVariable) != 0.0)
        {
          **ppContainerVariable = x * 1.001;
          *pGradient = (y - evaluate()) / (x * 0.001);
        }

      else
        {
          **ppContainerVariable = 1e-7;
          *pGradient = (y - evaluate()) / 1e-7;
        }

      **ppContainerVariable = x;
    }
}

C_FLOAT64 COptMethodSteepestDescent::descentLine(const C_FLOAT64 & x)
{
  C_FLOAT64 **ppContainerVariable = mContainerVariables.array();
  C_FLOAT64 **ppContainerVariableEnd = ppContainerVariable + mVariableSize;
  C_FLOAT64 * pGradient = mGradient.array();
  C_FLOAT64 * pIndividual = mIndividual.array();

  for (; ppContainerVariable != ppContainerVariableEnd; ++ppContainerVariable, ++pIndividual, ++pGradient)
    {
      **ppContainerVariable = *pIndividual + x **pGradient;
    }

  return evaluate();
}

// evaluate the fitness of one individual
const C_FLOAT64 & COptMethodSteepestDescent::evaluate()
{
  // evaluate the fitness
  mContinue = mpOptProblem->calculate();

  mValue = mpOptProblem->getCalculateValue();

  // when we leave the either the parameter or functional domain
  // we penalize the objective value by forcing it to be larger
  // than the best value recorded so far.
  if (mValue < mBestValue &&
      (!mpOptProblem->checkParametricConstraints() ||
       !mpOptProblem->checkFunctionalConstraints()))
    mValue = mBestValue + fabs(mBestValue - mValue);

  return mValue;
}

void COptMethodSteepestDescent::initObjects()
{
  addObjectReference("Current Iteration", mCurrentIteration, CDataObject::ValueInt);
}

unsigned C_INT32 COptMethodSteepestDescent::getMaxLogVerbosity() const
{
  return 0;
}
<commit_msg>changed log messages to use COptLogEntry class<commit_after>// Copyright (C) 2017 - 2018 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2010 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"

#include "COptMethodSteepestDescent.h"
#include "COptProblem.h"
#include "COptItem.h"
#include "COptTask.h"

#include "FminBrent.h"

#include "copasi/core/CDataObjectReference.h"

COptMethodSteepestDescent::COptMethodSteepestDescent(const CDataContainer * pParent,
    const CTaskEnum::Method & methodType,
    const CTaskEnum::Task & taskType):
  COptMethod(pParent, methodType, taskType),
  mIterations(100),
  mTolerance(1e-6),
  mContinue(true),
  mBestValue(std::numeric_limits< C_FLOAT64 >::infinity()),
  mValue(0.0),
  mVariableSize(0),
  mIndividual(0),
  mGradient(0),
  mpDescent(new FDescentTemplate<COptMethodSteepestDescent>(this, &COptMethodSteepestDescent::descentLine)),
  mCurrentIteration(0)
{
  addParameter("Iteration Limit", CCopasiParameter::Type::UINT, (unsigned C_INT32) 100);
  addParameter("Tolerance", CCopasiParameter::Type::DOUBLE, (C_FLOAT64) 1e-6);
}

COptMethodSteepestDescent::COptMethodSteepestDescent(const COptMethodSteepestDescent & src,
    const CDataContainer * pParent): COptMethod(src, pParent),
  mIterations(src.mIterations),
  mTolerance(src.mTolerance),
  mContinue(src.mContinue),
  mBestValue(src.mBestValue),
  mValue(src.mValue),
  mVariableSize(src.mVariableSize),
  mIndividual(src.mIndividual),
  mGradient(src.mGradient),
  mpDescent(new FDescentTemplate<COptMethodSteepestDescent>(this, &COptMethodSteepestDescent::descentLine)),
  mCurrentIteration(src.mCurrentIteration)
{}

COptMethodSteepestDescent::~COptMethodSteepestDescent()
{
  pdelete(mpDescent);

  cleanup();
}

bool COptMethodSteepestDescent::optimise()
{
  if (!initialize()) return false;

  if (mLogVerbosity > 0)
    mMethodLog.enterLogEntry(
      COptLogEntry(
        "Algorithm started.",
        "For more information about this method see: http://copasi.org/Support/User_Manual/Methods/Optimization_Methods/Steepest_Descent/"
      )
    );

  size_t i, k;
  C_FLOAT64 tmp, x0, alpha, mn, mx, fmn, fmx;
  bool calc_grad;

  // initial point is first guess but we have to make sure that we
  // are within the parameter domain
  bool pointInParameterDomain = true;

  for (i = 0; i < mVariableSize; i++)
    {
      const COptItem & OptItem = *(*mpOptItem)[i];

      switch (OptItem.checkConstraint(OptItem.getStartValue()))
        {
          case - 1:
            mIndividual[i] = *OptItem.getLowerBoundValue();
            pointInParameterDomain = false;
            break;

          case 1:
            mIndividual[i] = *OptItem.getUpperBoundValue();
            pointInParameterDomain = false;
            break;

          case 0:
            mIndividual[i] = OptItem.getStartValue();
            break;
        }

      *mContainerVariables[i] = mIndividual[i];
    }

  if (!pointInParameterDomain && (mLogVerbosity > 0))
    mMethodLog.enterLogEntry(COptLogEntry("Initial point outside parameter domain."));

  fmx = mBestValue = evaluate();

  mContinue = mpOptProblem->setSolution(mBestValue, mIndividual);

  // We found a new best value lets report it.
  //if (mpReport) mpReport->printBody();
  mpParentTask->output(COutputInterface::DURING);

  bool SolutionFound = false;

  for (mCurrentIteration = 0; mCurrentIteration < mIterations && mContinue && !SolutionFound; mCurrentIteration++)
    {
      // calculate the direction of steepest descent
      // by central finite differences
      gradient();
      // minimise the function in this direction
      // find brackets for the minimisation
      //  mn = 0.0; md = 1.0;
      //  mnbrak(&mn, &md, &mx, &fmn, &fmd, &fmx, descent_line);
      // make sure that no parameter will exceed its bounds
      x0 = std::numeric_limits< C_FLOAT64 >::max();

      for (i = 0; i < mVariableSize; i++)
        {
          if (fabs(mGradient[i]) > std::numeric_limits< C_FLOAT64 >::epsilon())
            {
              if (mGradient[i] > 0)
                {
                  tmp = *(*mpOptItem)[i]->getUpperBoundValue();
                }

              else
                {
                  tmp = *(*mpOptItem)[i]->getLowerBoundValue();
                }

              // calculate the size of the largest jump
              tmp = (tmp - mIndividual[i]) / mGradient[i];

              // keep it if it is the smallest
              if (tmp < x0) x0 = tmp;
            }
          else mGradient[i] = 0.0;
        }

      if (x0 < mTolerance) x0 = mTolerance;

      // we will move at a rate of 1/10 this size
      mn = mx = alpha = 0.0;

      for (k = 0, calc_grad = false; (k < 9) && !calc_grad && !SolutionFound; k++)
        {
          // set the minimum to the last successful step
          mn = mx;
          fmn = fmx;
          // increment alpha
          alpha += 0.1 * x0;
          // set the maximum to it
          mx = alpha;

          // take one step in that direction
          fmx = descentLine(alpha);

          fmx = evaluate();

          // if this was an upward step find the minimum
          if (fmx > fmn)
            {
              //md = mn + (mx-mn)/2;
              //Brent(mn, md, mx, descent_line, &alpha, &tmp, 1e-6, 50);

              FminBrent(mn, mx, mpDescent, &alpha, &tmp, mTolerance, 5);

              // take one step in that direction
              fmx = descentLine(alpha);

              // time to evaluate the new steepest descent direction
              calc_grad = true;
            }

          if (fabs(fmx - mBestValue) < mTolerance)
            SolutionFound = true;
        }

      for (i = 0; i < mVariableSize; i++)
        mIndividual[i] = *(*mpOptItem)[i]->getObjectValue();

      if (fmx < mBestValue)
        {
          mBestValue = fmx;

          mContinue = mpOptProblem->setSolution(mBestValue, mIndividual);

          // We found a new best value lets report it.
          //if (mpReport) mpReport->printBody();
          mpParentTask->output(COutputInterface::DURING);
        }
    }

  if (mLogVerbosity > 0)
    mMethodLog.enterLogEntry(
      COptLogEntry("Algorithm finished.",
                   "Terminated after " + std::to_string(mCurrentIteration) + " of " + std::to_string(mIterations) + " iterations."));

  return true;
}

bool COptMethodSteepestDescent::cleanup()
{
  // pdelete all used variables
  return true;
}

bool COptMethodSteepestDescent::initialize()
{
  cleanup();

  if (!COptMethod::initialize()) return false;

  mIterations = getValue< unsigned C_INT32 >("Iteration Limit");
  mTolerance = getValue< C_FLOAT64 >("Tolerance");

  mContinue = true;
  mVariableSize = mpOptItem->size();
  mIndividual.resize(mVariableSize);
  mGradient.resize(mVariableSize);

  mBestValue = std::numeric_limits<C_FLOAT64>::infinity();

  return true;
}

void COptMethodSteepestDescent::gradient()
{

  C_FLOAT64 **ppContainerVariable = mContainerVariables.array();
  C_FLOAT64 **ppContainerVariableEnd = ppContainerVariable + mVariableSize;
  C_FLOAT64 * pGradient = mGradient.array();

  C_FLOAT64 y;
  C_FLOAT64 x;

  y = evaluate();

  for (; ppContainerVariable != ppContainerVariableEnd; ++ppContainerVariable, ++pGradient)
    {
      if ((x = **ppContainerVariable) != 0.0)
        {
          **ppContainerVariable = x * 1.001;
          *pGradient = (y - evaluate()) / (x * 0.001);
        }

      else
        {
          **ppContainerVariable = 1e-7;
          *pGradient = (y - evaluate()) / 1e-7;
        }

      **ppContainerVariable = x;
    }
}

C_FLOAT64 COptMethodSteepestDescent::descentLine(const C_FLOAT64 & x)
{
  C_FLOAT64 **ppContainerVariable = mContainerVariables.array();
  C_FLOAT64 **ppContainerVariableEnd = ppContainerVariable + mVariableSize;
  C_FLOAT64 * pGradient = mGradient.array();
  C_FLOAT64 * pIndividual = mIndividual.array();

  for (; ppContainerVariable != ppContainerVariableEnd; ++ppContainerVariable, ++pIndividual, ++pGradient)
    {
      **ppContainerVariable = *pIndividual + x **pGradient;
    }

  return evaluate();
}

// evaluate the fitness of one individual
const C_FLOAT64 & COptMethodSteepestDescent::evaluate()
{
  // evaluate the fitness
  mContinue = mpOptProblem->calculate();

  mValue = mpOptProblem->getCalculateValue();

  // when we leave the either the parameter or functional domain
  // we penalize the objective value by forcing it to be larger
  // than the best value recorded so far.
  if (mValue < mBestValue &&
      (!mpOptProblem->checkParametricConstraints() ||
       !mpOptProblem->checkFunctionalConstraints()))
    mValue = mBestValue + fabs(mBestValue - mValue);

  return mValue;
}

void COptMethodSteepestDescent::initObjects()
{
  addObjectReference("Current Iteration", mCurrentIteration, CDataObject::ValueInt);
}

unsigned C_INT32 COptMethodSteepestDescent::getMaxLogVerbosity() const
{
  return 0;
}
<|endoftext|>


<commit_before>#include "rosplan_planning_system/PlannerInterface/FFPlannerInterface.h"

namespace KCL_rosplan {

	/*-------------*/
	/* constructor */
	/*-------------*/

	FFPlannerInterface::FFPlannerInterface(ros::NodeHandle& nh)
	{
		node_handle = &nh;

		plan_server = new actionlib::SimpleActionServer<rosplan_dispatch_msgs::PlanAction>((*node_handle), "start_planning", boost::bind(&PlannerInterface::runPlanningServerAction, this, _1), false);

		// publishing raw planner output
		std::string plannerTopic = "planner_output";
		node_handle->getParam("planner_topic", plannerTopic);
		plan_publisher = node_handle->advertise<std_msgs::String>(plannerTopic, 1, true);

		// start planning action server
		plan_server->start();
	}

	FFPlannerInterface::~FFPlannerInterface()
	{
		delete plan_server;
	}

	/**
	 * Runs external commands
	 */
	std::string FFPlannerInterface::runCommand(std::string cmd) {
		std::string data;
		FILE *stream;
		char buffer[1000];
		stream = popen(cmd.c_str(), "r");
		while ( fgets(buffer, 1000, stream) != NULL )
			data.append(buffer);
		pclose(stream);
		return data;
	}

	/*------------------*/
	/* Plan and process */
	/*------------------*/

	/**
	 * passes the problem to the Planner; the plan to post-processing.
	 */
	bool FFPlannerInterface::runPlanner() {

		// save problem to file for planner
		if(use_problem_topic && problem_instance_received) {
			ROS_INFO("KCL: (%s) (%s) Writing problem to file.", ros::this_node::getName().c_str(), problem_name.c_str());
			std::ofstream dest;
			dest.open((problem_path).c_str());
			dest << problem_instance;
			dest.close();
		}

		// prepare the planner command line
		std::string str = planner_command;
		std::size_t dit = str.find("DOMAIN");
		if(dit!=std::string::npos) str.replace(dit,6,domain_path);
		std::size_t pit = str.find("PROBLEM");
		if(pit!=std::string::npos) str.replace(pit,7,problem_path);
		std::string commandString = str + " > " + data_path + "plan.pddl";

		// call the planer
		ROS_INFO("KCL: (%s) (%s) Running: %s", ros::this_node::getName().c_str(), problem_name.c_str(),  commandString.c_str());
		std::string plan = runCommand(commandString.c_str());
		ROS_INFO("KCL: (%s) (%s) Planning complete", ros::this_node::getName().c_str(), problem_name.c_str());

		// check the planner solved the problem
		std::ifstream planfile;
		planfile.open((data_path + "plan.pddl").c_str());
		std::string line;
		std::stringstream ss;

		bool solved = false;

		while (std::getline(planfile, line)) {

			// skip lines until there is a plan
			if(line.compare("ff: found legal plan as follows") != 0) {
				continue;
			}

			// skip the empty line
			while (std::getline(planfile, line)) {
				if (line.length()<2) break;
			}

			// actions look like this:
			// step    0: got_place C1
			//         1: find_object V1 C1
			solved = true;
			while (std::getline(planfile, line)) {

				if (line.length()<2) break;

				unsigned int pos = line.find(' ');
				bool action = false;
				while(pos != std::string::npos && pos < line.length()) {
					if(line.substr(pos,1) != " ") {
						action = true;
						line = line.substr(pos);
						break;
					}
					pos++;
				}
				if(action) ss << line << " [0.001]" << std::endl;
			}
			planner_output = ss.str();
		}
		planfile.close();

		if(!solved) ROS_INFO("KCL: (%s) (%s) Plan was unsolvable.", ros::this_node::getName().c_str(), problem_name.c_str());
		else ROS_INFO("KCL: (%s) (%s) Plan was solved.", ros::this_node::getName().c_str(), problem_name.c_str());

		return solved;
	}

} // close namespace

	/*-------------*/
	/* Main method */
	/*-------------*/

	int main(int argc, char **argv) {

		srand (static_cast <unsigned> (time(0)));

		ros::init(argc,argv,"rosplan_planner_interface");
		ros::NodeHandle nh("~");

		KCL_rosplan::FFPlannerInterface pi(nh);

		// subscribe to problem instance
		std::string problemTopic = "problem_instance";
		nh.getParam("problem_topic", problemTopic);
		ros::Subscriber problem_sub = nh.subscribe(problemTopic, 1, &KCL_rosplan::PlannerInterface::problemCallback, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));

		// start the planning services
		ros::ServiceServer service1 = nh.advertiseService("planning_server", &KCL_rosplan::PlannerInterface::runPlanningServerDefault, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));
		ros::ServiceServer service2 = nh.advertiseService("planning_server_params", &KCL_rosplan::PlannerInterface::runPlanningServerParams, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));

		ROS_INFO("KCL: (%s) Ready to receive", ros::this_node::getName().c_str());
		ros::spin();

		return 0;
	}
<commit_msg>Fixed FF plan parser<commit_after>#include "rosplan_planning_system/PlannerInterface/FFPlannerInterface.h"

namespace KCL_rosplan {

	/*-------------*/
	/* constructor */
	/*-------------*/

	FFPlannerInterface::FFPlannerInterface(ros::NodeHandle& nh)
	{
		node_handle = &nh;

		plan_server = new actionlib::SimpleActionServer<rosplan_dispatch_msgs::PlanAction>((*node_handle), "start_planning", boost::bind(&PlannerInterface::runPlanningServerAction, this, _1), false);

		// publishing raw planner output
		std::string plannerTopic = "planner_output";
		node_handle->getParam("planner_topic", plannerTopic);
		plan_publisher = node_handle->advertise<std_msgs::String>(plannerTopic, 1, true);

		// start planning action server
		plan_server->start();
	}

	FFPlannerInterface::~FFPlannerInterface()
	{
		delete plan_server;
	}

	/**
	 * Runs external commands
	 */
	std::string FFPlannerInterface::runCommand(std::string cmd) {
		std::string data;
		FILE *stream;
		char buffer[1000];
		stream = popen(cmd.c_str(), "r");
		while ( fgets(buffer, 1000, stream) != NULL )
			data.append(buffer);
		pclose(stream);
		return data;
	}

	/*------------------*/
	/* Plan and process */
	/*------------------*/

	/**
	 * passes the problem to the Planner; the plan to post-processing.
	 */
	bool FFPlannerInterface::runPlanner() {

		// save problem to file for planner
		if(use_problem_topic && problem_instance_received) {
			ROS_INFO("KCL: (%s) (%s) Writing problem to file.", ros::this_node::getName().c_str(), problem_name.c_str());
			std::ofstream dest;
			dest.open((problem_path).c_str());
			dest << problem_instance;
			dest.close();
		}

		// prepare the planner command line
		std::string str = planner_command;
		std::size_t dit = str.find("DOMAIN");
		if(dit!=std::string::npos) str.replace(dit,6,domain_path);
		std::size_t pit = str.find("PROBLEM");
		if(pit!=std::string::npos) str.replace(pit,7,problem_path);
		std::string commandString = str + " > " + data_path + "plan.pddl";

		// call the planer
		ROS_INFO("KCL: (%s) (%s) Running: %s", ros::this_node::getName().c_str(), problem_name.c_str(),  commandString.c_str());
		std::string plan = runCommand(commandString.c_str());
		ROS_INFO("KCL: (%s) (%s) Planning complete", ros::this_node::getName().c_str(), problem_name.c_str());

		// check the planner solved the problem
		std::ifstream planfile;
		planfile.open((data_path + "plan.pddl").c_str());
		std::string line;

		bool solved = false;
		while (not solved and std::getline(planfile, line)) {
			// skip lines until there is a plan
			if (line.compare("ff: found legal plan as follows") == 0) {
				solved = true;
			}
		}

		// Parse the solved plan
		if (solved) {
			// actions look like this:
			// step    0: got_place C1
			//         1: find_object V1 C1
			// plan cost: XX
			while (std::getline(planfile, line)) { // Move to the beginning of the plan
				if (line.substr(0, 4) == "step") {
					line = line.substr(4); // Remove the step
					break;
				}
			}

			// First iteration line will be like   0: got_place C1
			while (line.find("plan cost") == line.npos and line.find("time spend") == line.npos and line.size() > 0) {
				std::stringstream ss(line); // To trim whitespaces
				std::string aux;
				// Read the action number X:
				ss >> aux;
				planner_output += aux + " ("; // Add parenthesis before the action
				while (ss >> aux) { // Read the rest
					planner_output += aux;
					if (ss.good()) planner_output += " "; // Add a whitespace unless we have processed all the line
				}
				planner_output += ")  [0.001]\n"; // Close parenthesis and add duration
				std::getline(planfile, line);
			}
			// Convert to lowercase as FF prints all the actions and parameters in uppercase
			std::transform(planner_output.begin(), planner_output.end(), planner_output.begin(), ::tolower);
		}
		planfile.close();

		if(!solved) ROS_INFO("KCL: (%s) (%s) Plan was unsolvable.", ros::this_node::getName().c_str(), problem_name.c_str());
		else ROS_INFO("KCL: (%s) (%s) Plan was solved.", ros::this_node::getName().c_str(), problem_name.c_str());

		return solved;
	}

} // close namespace

	/*-------------*/
	/* Main method */
	/*-------------*/

	int main(int argc, char **argv) {

		srand (static_cast <unsigned> (time(0)));

		ros::init(argc,argv,"rosplan_planner_interface");
		ros::NodeHandle nh("~");

		KCL_rosplan::FFPlannerInterface pi(nh);

		// subscribe to problem instance
		std::string problemTopic = "problem_instance";
		nh.getParam("problem_topic", problemTopic);
		ros::Subscriber problem_sub = nh.subscribe(problemTopic, 1, &KCL_rosplan::PlannerInterface::problemCallback, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));

		// start the planning services
		ros::ServiceServer service1 = nh.advertiseService("planning_server", &KCL_rosplan::PlannerInterface::runPlanningServerDefault, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));
		ros::ServiceServer service2 = nh.advertiseService("planning_server_params", &KCL_rosplan::PlannerInterface::runPlanningServerParams, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));

		ROS_INFO("KCL: (%s) Ready to receive", ros::this_node::getName().c_str());
		ros::spin();

		return 0;
	}
<|endoftext|>