<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2013 Viktor Gal
 * Copyright (C) 2013 Viktor Gal
 */

#include <shogun/mathematics/Random.h>
#include <shogun/base/Parameter.h>
#include <shogun/lib/external/SFMT/SFMT.h>
#include <shogun/lib/external/dSFMT/dSFMT.h>
#include <shogun/lib/Time.h>
#include <shogun/lib/Lock.h>

#ifdef DEV_RANDOM
#include <fcntl.h>
#endif

#ifdef _WIN32
#define _CRT_RAND_S
#include <stdlib.h>
#endif

using namespace shogun;

CRandom::CRandom()
 : m_sfmt_32(NULL),
 m_sfmt_64(NULL),
 m_dsfmt(NULL)
{
	m_seed = CRandom::generate_seed();
	init();
}

CRandom::CRandom(uint32_t seed)
 : m_seed(seed),
 m_sfmt_32(NULL),
 m_sfmt_64(NULL),
 m_dsfmt(NULL)
{
	init();
}

CRandom::~CRandom()
{
	SG_FREE(m_x);
	SG_FREE(m_y);
	SG_FREE(m_xComp);
	SG_FREE(m_sfmt_32);
	SG_FREE(m_sfmt_64);
	SG_FREE(m_dsfmt);
}

void CRandom::set_seed(uint32_t seed)
{
	reinit(seed);
}

uint32_t CRandom::get_seed() const
{
	return m_seed;
}

void CRandom::init()
{
	/** init ziggurat variables */
	m_blockCount = 128;
	m_R = 3.442619855899;
	m_A = 9.91256303526217e-3;
	m_uint32ToU = 1.0 / (float64_t)std::numeric_limits<uint32_t>::max();

	m_x = SG_MALLOC(float64_t, m_blockCount + 1);
	m_y = SG_MALLOC(float64_t, m_blockCount);
	m_xComp = SG_MALLOC(uint32_t, m_blockCount);

	// Initialise rectangle position data.
	// m_x[i] and m_y[i] describe the top-right position ox Box i.

	// Determine top right position of the base rectangle/box (the rectangle with the Gaussian tale attached).
	// We call this Box 0 or B0 for short.
	// Note. x[0] also describes the right-hand edge of B1. (See diagram).
	m_x[0] = m_R;
	m_y[0] = GaussianPdfDenorm(m_R);

	// The next box (B1) has a right hand X edge the same as B0.
	// Note. B1's height is the box area divided by its width, hence B1 has a smaller height than B0 because
	// B0's total area includes the attached distribution tail.
	m_x[1] = m_R;
	m_y[1] = m_y[0] + (m_A / m_x[1]);

	// Calc positions of all remaining rectangles.
	for(int i=2; i < m_blockCount; i++)
	{
		m_x[i] = GaussianPdfDenormInv(m_y[i-1]);
		m_y[i] = m_y[i-1] + (m_A / m_x[i]);
	}

	// For completeness we define the right-hand edge of a notional box 6 as being zero (a box with no area).
	m_x[m_blockCount] = 0.0;

	// Useful precomputed values.
	m_A_div_y0 = m_A / m_y[0];

	// Special case for base box. m_xComp[0] stores the area of B0 as a proportion of R
	// (recalling that all segments have area A, but that the base segment is the combination of B0 and the distribution tail).
	// Thus -m_xComp[0] is the probability that a sample point is within the box part of the segment.
	m_xComp[0] = (uint32_t)(((m_R * m_y[0]) / m_A) * (float64_t)std::numeric_limits<uint32_t>::max());

	for(int32_t i=1; i < m_blockCount-1; i++)
	{
		m_xComp[i] = (uint32_t)((m_x[i+1] / m_x[i]) * (float64_t)std::numeric_limits<uint32_t>::max());
	}
	m_xComp[m_blockCount-1] = 0;  // Shown for completeness.

	// Sanity check. Test that the top edge of the topmost rectangle is at y=1.0.
	// Note. We expect there to be a tiny drift away from 1.0 due to the inexactness of floating
	// point arithmetic.
	ASSERT(CMath::abs(1.0 - m_y[m_blockCount-1]) < 1e-10);

	/** init SFMT and dSFMT */
	m_sfmt_32 = SG_MALLOC(sfmt_t, 1);
	m_sfmt_64 = SG_MALLOC(sfmt_t, 1);
	m_dsfmt = SG_MALLOC(dsfmt_t, 1);
	reinit(m_seed);
}

uint32_t CRandom::random_32() const
{
	return sfmt_genrand_uint32(m_sfmt_32);
}

uint64_t CRandom::random_64() const
{
	return sfmt_genrand_uint64(m_sfmt_64);
}

void CRandom::fill_array(uint32_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= sfmt_get_min_array_size32(m_sfmt_32)) && (size % 4) == 0)
	{
		sfmt_fill_array32(m_sfmt_32, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = random_32();
}

void CRandom::fill_array(uint64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= sfmt_get_min_array_size64(m_sfmt_64)) && (size % 2) == 0)
	{
		sfmt_fill_array64(m_sfmt_64, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = random_64();
}

void CRandom::fill_array_oc(float64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= dsfmt_get_min_array_size()) && (size % 2) == 0)
	{
		dsfmt_fill_array_open_close(m_dsfmt, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = dsfmt_genrand_open_close(m_dsfmt);
}

void CRandom::fill_array_co(float64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= dsfmt_get_min_array_size()) && (size % 2) == 0)
	{
		dsfmt_fill_array_close_open(m_dsfmt, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = dsfmt_genrand_close_open(m_dsfmt);
}

void CRandom::fill_array_oo(float64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= dsfmt_get_min_array_size()) && (size % 2) == 0)
	{
		dsfmt_fill_array_open_open(m_dsfmt, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = dsfmt_genrand_open_open(m_dsfmt);
}

void CRandom::fill_array_c1o2(float64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= dsfmt_get_min_array_size()) && (size % 2) == 0)
	{
		dsfmt_fill_array_close1_open2(m_dsfmt, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = dsfmt_genrand_close1_open2(m_dsfmt);
}

float64_t CRandom::random_close() const
{
	return sfmt_genrand_real1(m_sfmt_32);
}

float64_t CRandom::random_open() const
{
	return dsfmt_genrand_open_open(m_dsfmt);
}

float64_t CRandom::random_half_open() const
{
	return dsfmt_genrand_close_open(m_dsfmt);
}

float64_t CRandom::normal_distrib(float64_t mu, float64_t sigma) const
{
	return mu + (std_normal_distrib() * sigma);
}

float64_t CRandom::std_normal_distrib() const
{
	for (;;)
	{
		// Select box at random.
		uint8_t u = random_32();
		int32_t i = (int32_t)(u & 0x7F);
		float64_t sign = ((u & 0x80) == 0) ? -1.0 : 1.0;

		// Generate uniform random value with range [0,0xffffffff].
		uint32_t u2 = random_32();

		// Special case for the base segment.
		if(0 == i)
		{
			if(u2 < m_xComp[0])
			{
				// Generated x is within R0.
				return u2 * m_uint32ToU * m_A_div_y0 * sign;
			}
			// Generated x is in the tail of the distribution.
			return sample_tail() * sign;
		}

		// All other segments.
		if(u2 < m_xComp[i])
		{   // Generated x is within the rectangle.
			return u2 * m_uint32ToU * m_x[i] * sign;
		}

		// Generated x is outside of the rectangle.
		// Generate a random y coordinate and test if our (x,y) is within the distribution curve.
		// This execution path is relatively slow/expensive (makes a call to Math.Exp()) but relatively rarely executed,
		// although more often than the 'tail' path (above).
		float64_t x = u2 * m_uint32ToU * m_x[i];
		if(m_y[i-1] + ((m_y[i] - m_y[i-1]) * random_half_open()) < GaussianPdfDenorm(x) ) {
			return x * sign;
		}
	}
}

float64_t CRandom::sample_tail() const
{
	float64_t x, y;
	do
	{
	    x = -CMath::log(random_half_open()) / m_R;
	    y = -CMath::log(random_half_open());
	} while(y+y < x*x);
	return m_R + x;
}

float64_t CRandom::GaussianPdfDenorm(float64_t x) const
{
	return CMath::exp(-(x*x / 2.0));
}

float64_t CRandom::GaussianPdfDenormInv(float64_t y) const
{
    // Operates over the y range (0,1], which happens to be the y range of the pdf,
    // with the exception that it does not include y=0, but we would never call with
    // y=0 so it doesn't matter. Remember that a Gaussian effectively has a tail going
    // off into x == infinity, hence asking what is x when y=0 is an invalid question
    // in the context of this class.
    return CMath::sqrt(-2.0 * CMath::log(y));
}

void CRandom::reinit(uint32_t seed)
{
	m_state_lock.lock();
	m_seed = seed;
	sfmt_init_gen_rand(m_sfmt_32, m_seed);
	sfmt_init_gen_rand(m_sfmt_64, m_seed);
	dsfmt_init_gen_rand(m_dsfmt, m_seed);
	m_state_lock.unlock();
}

uint32_t CRandom::generate_seed()
{
	uint32_t seed;
#if defined(_WIN32)
	rand_s(&seed);
#elif defined(HAVE_ARC4RANDOM)
	seed = arc4random();
#elif defined(DEV_RANDOM)
	int fd = open(DEV_RANDOM, O_RDONLY);
	ASSERT(fd > 0);
	ssize_t actual_read =
		read(fd, reinterpret_cast<char*>(&seed), sizeof(seed));
	close(fd);
	ASSERT(actual_read == sizeof(seed));
#else
	SG_SWARNING("Not safe seed for the PRNG\n");
	struct timeval tv;
	gettimeofday(&tv, NULL);
	seed=(uint32_t) (4223517*getpid()*tv.tv_sec*tv.tv_usec);
#endif
	return seed;
}
<commit_msg>Fix assertion - open() can return "0", which is a valid file descriptor.<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2013 Viktor Gal
 * Copyright (C) 2013 Viktor Gal
 */

#include <shogun/mathematics/Random.h>
#include <shogun/base/Parameter.h>
#include <shogun/lib/external/SFMT/SFMT.h>
#include <shogun/lib/external/dSFMT/dSFMT.h>
#include <shogun/lib/Time.h>
#include <shogun/lib/Lock.h>

#ifdef DEV_RANDOM
#include <fcntl.h>
#endif

#ifdef _WIN32
#define _CRT_RAND_S
#include <stdlib.h>
#endif

using namespace shogun;

CRandom::CRandom()
 : m_sfmt_32(NULL),
 m_sfmt_64(NULL),
 m_dsfmt(NULL)
{
	m_seed = CRandom::generate_seed();
	init();
}

CRandom::CRandom(uint32_t seed)
 : m_seed(seed),
 m_sfmt_32(NULL),
 m_sfmt_64(NULL),
 m_dsfmt(NULL)
{
	init();
}

CRandom::~CRandom()
{
	SG_FREE(m_x);
	SG_FREE(m_y);
	SG_FREE(m_xComp);
	SG_FREE(m_sfmt_32);
	SG_FREE(m_sfmt_64);
	SG_FREE(m_dsfmt);
}

void CRandom::set_seed(uint32_t seed)
{
	reinit(seed);
}

uint32_t CRandom::get_seed() const
{
	return m_seed;
}

void CRandom::init()
{
	/** init ziggurat variables */
	m_blockCount = 128;
	m_R = 3.442619855899;
	m_A = 9.91256303526217e-3;
	m_uint32ToU = 1.0 / (float64_t)std::numeric_limits<uint32_t>::max();

	m_x = SG_MALLOC(float64_t, m_blockCount + 1);
	m_y = SG_MALLOC(float64_t, m_blockCount);
	m_xComp = SG_MALLOC(uint32_t, m_blockCount);

	// Initialise rectangle position data.
	// m_x[i] and m_y[i] describe the top-right position ox Box i.

	// Determine top right position of the base rectangle/box (the rectangle with the Gaussian tale attached).
	// We call this Box 0 or B0 for short.
	// Note. x[0] also describes the right-hand edge of B1. (See diagram).
	m_x[0] = m_R;
	m_y[0] = GaussianPdfDenorm(m_R);

	// The next box (B1) has a right hand X edge the same as B0.
	// Note. B1's height is the box area divided by its width, hence B1 has a smaller height than B0 because
	// B0's total area includes the attached distribution tail.
	m_x[1] = m_R;
	m_y[1] = m_y[0] + (m_A / m_x[1]);

	// Calc positions of all remaining rectangles.
	for(int i=2; i < m_blockCount; i++)
	{
		m_x[i] = GaussianPdfDenormInv(m_y[i-1]);
		m_y[i] = m_y[i-1] + (m_A / m_x[i]);
	}

	// For completeness we define the right-hand edge of a notional box 6 as being zero (a box with no area).
	m_x[m_blockCount] = 0.0;

	// Useful precomputed values.
	m_A_div_y0 = m_A / m_y[0];

	// Special case for base box. m_xComp[0] stores the area of B0 as a proportion of R
	// (recalling that all segments have area A, but that the base segment is the combination of B0 and the distribution tail).
	// Thus -m_xComp[0] is the probability that a sample point is within the box part of the segment.
	m_xComp[0] = (uint32_t)(((m_R * m_y[0]) / m_A) * (float64_t)std::numeric_limits<uint32_t>::max());

	for(int32_t i=1; i < m_blockCount-1; i++)
	{
		m_xComp[i] = (uint32_t)((m_x[i+1] / m_x[i]) * (float64_t)std::numeric_limits<uint32_t>::max());
	}
	m_xComp[m_blockCount-1] = 0;  // Shown for completeness.

	// Sanity check. Test that the top edge of the topmost rectangle is at y=1.0.
	// Note. We expect there to be a tiny drift away from 1.0 due to the inexactness of floating
	// point arithmetic.
	ASSERT(CMath::abs(1.0 - m_y[m_blockCount-1]) < 1e-10);

	/** init SFMT and dSFMT */
	m_sfmt_32 = SG_MALLOC(sfmt_t, 1);
	m_sfmt_64 = SG_MALLOC(sfmt_t, 1);
	m_dsfmt = SG_MALLOC(dsfmt_t, 1);
	reinit(m_seed);
}

uint32_t CRandom::random_32() const
{
	return sfmt_genrand_uint32(m_sfmt_32);
}

uint64_t CRandom::random_64() const
{
	return sfmt_genrand_uint64(m_sfmt_64);
}

void CRandom::fill_array(uint32_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= sfmt_get_min_array_size32(m_sfmt_32)) && (size % 4) == 0)
	{
		sfmt_fill_array32(m_sfmt_32, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = random_32();
}

void CRandom::fill_array(uint64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= sfmt_get_min_array_size64(m_sfmt_64)) && (size % 2) == 0)
	{
		sfmt_fill_array64(m_sfmt_64, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = random_64();
}

void CRandom::fill_array_oc(float64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= dsfmt_get_min_array_size()) && (size % 2) == 0)
	{
		dsfmt_fill_array_open_close(m_dsfmt, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = dsfmt_genrand_open_close(m_dsfmt);
}

void CRandom::fill_array_co(float64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= dsfmt_get_min_array_size()) && (size % 2) == 0)
	{
		dsfmt_fill_array_close_open(m_dsfmt, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = dsfmt_genrand_close_open(m_dsfmt);
}

void CRandom::fill_array_oo(float64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= dsfmt_get_min_array_size()) && (size % 2) == 0)
	{
		dsfmt_fill_array_open_open(m_dsfmt, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = dsfmt_genrand_open_open(m_dsfmt);
}

void CRandom::fill_array_c1o2(float64_t* array, int32_t size) const
{
#if defined(USE_ALIGNED_MEMORY) || defined(DARWIN)
	if ((size >= dsfmt_get_min_array_size()) && (size % 2) == 0)
	{
		dsfmt_fill_array_close1_open2(m_dsfmt, array, size);
		return;
	}
#endif
	for (int32_t i=0; i < size; i++)
		array[i] = dsfmt_genrand_close1_open2(m_dsfmt);
}

float64_t CRandom::random_close() const
{
	return sfmt_genrand_real1(m_sfmt_32);
}

float64_t CRandom::random_open() const
{
	return dsfmt_genrand_open_open(m_dsfmt);
}

float64_t CRandom::random_half_open() const
{
	return dsfmt_genrand_close_open(m_dsfmt);
}

float64_t CRandom::normal_distrib(float64_t mu, float64_t sigma) const
{
	return mu + (std_normal_distrib() * sigma);
}

float64_t CRandom::std_normal_distrib() const
{
	for (;;)
	{
		// Select box at random.
		uint8_t u = random_32();
		int32_t i = (int32_t)(u & 0x7F);
		float64_t sign = ((u & 0x80) == 0) ? -1.0 : 1.0;

		// Generate uniform random value with range [0,0xffffffff].
		uint32_t u2 = random_32();

		// Special case for the base segment.
		if(0 == i)
		{
			if(u2 < m_xComp[0])
			{
				// Generated x is within R0.
				return u2 * m_uint32ToU * m_A_div_y0 * sign;
			}
			// Generated x is in the tail of the distribution.
			return sample_tail() * sign;
		}

		// All other segments.
		if(u2 < m_xComp[i])
		{   // Generated x is within the rectangle.
			return u2 * m_uint32ToU * m_x[i] * sign;
		}

		// Generated x is outside of the rectangle.
		// Generate a random y coordinate and test if our (x,y) is within the distribution curve.
		// This execution path is relatively slow/expensive (makes a call to Math.Exp()) but relatively rarely executed,
		// although more often than the 'tail' path (above).
		float64_t x = u2 * m_uint32ToU * m_x[i];
		if(m_y[i-1] + ((m_y[i] - m_y[i-1]) * random_half_open()) < GaussianPdfDenorm(x) ) {
			return x * sign;
		}
	}
}

float64_t CRandom::sample_tail() const
{
	float64_t x, y;
	do
	{
	    x = -CMath::log(random_half_open()) / m_R;
	    y = -CMath::log(random_half_open());
	} while(y+y < x*x);
	return m_R + x;
}

float64_t CRandom::GaussianPdfDenorm(float64_t x) const
{
	return CMath::exp(-(x*x / 2.0));
}

float64_t CRandom::GaussianPdfDenormInv(float64_t y) const
{
    // Operates over the y range (0,1], which happens to be the y range of the pdf,
    // with the exception that it does not include y=0, but we would never call with
    // y=0 so it doesn't matter. Remember that a Gaussian effectively has a tail going
    // off into x == infinity, hence asking what is x when y=0 is an invalid question
    // in the context of this class.
    return CMath::sqrt(-2.0 * CMath::log(y));
}

void CRandom::reinit(uint32_t seed)
{
	m_state_lock.lock();
	m_seed = seed;
	sfmt_init_gen_rand(m_sfmt_32, m_seed);
	sfmt_init_gen_rand(m_sfmt_64, m_seed);
	dsfmt_init_gen_rand(m_dsfmt, m_seed);
	m_state_lock.unlock();
}

uint32_t CRandom::generate_seed()
{
	uint32_t seed;
#if defined(_WIN32)
	rand_s(&seed);
#elif defined(HAVE_ARC4RANDOM)
	seed = arc4random();
#elif defined(DEV_RANDOM)
	int fd = open(DEV_RANDOM, O_RDONLY);
	ASSERT(fd >= 0);
	ssize_t actual_read =
		read(fd, reinterpret_cast<char*>(&seed), sizeof(seed));
	close(fd);
	ASSERT(actual_read == sizeof(seed));
#else
	SG_SWARNING("Not safe seed for the PRNG\n");
	struct timeval tv;
	gettimeofday(&tv, NULL);
	seed=(uint32_t) (4223517*getpid()*tv.tv_sec*tv.tv_usec);
#endif
	return seed;
}
<|endoftext|>


<commit_before>#pragma once

#include <cassert>
#include <vector>
#include "graph.hpp"

namespace simple_graph {

template<typename E>
bool check_distance(const E &d, const E &w)
{
    if ((d > 0) && (w >0) && (std::numeric_limits<E>::max() - d < w)) {
        return false;
    }
    return true;
}

template<typename V, typename E>
bool bellman_ford(const Graph<V, E> &g, vertex_index_t start_idx, vertex_index_t goal_idx,
        std::vector<vertex_index_t> *path)
{
    // TODO add utility function to check passed vertex indices
    if ((start_idx < 0) || (goal_idx < 0)) {
        return false;
    }

    std::vector<E> distance(g.vertex_num(), std::numeric_limits<E>::max());
    std::vector<vertex_index_t> predecessor(g.vertex_num(), -1);

    distance[start_idx] = 0;

    Graph<V, E> *fg = const_cast<Graph<V, E>*>(&g);
    for (size_t i = 0; i < g.vertex_num(); ++i) {
        bool changed = false;
        for (auto e : fg->edges()) {
            if (check_distance(distance[e.idx1()], e.weight())
                    && (distance[e.idx1()] + e.weight() < distance[e.idx2()])) {
                distance[e.idx2()] = distance[e.idx1()] + e.weight();
                predecessor[e.idx2()] = e.idx1();
                changed = true;
            }
        }
        if (!changed) {
            break;
        }
    }

    for (auto e : fg->edges()) {
        if (check_distance(distance[e.idx1()], e.weight())
                && (distance[e.idx1()] + e.weight() < distance[e.idx2()])) {
            return false;
        }
    }

    if (distance[goal_idx] == std::numeric_limits<E>::max()) {
        return false;
    }

    vertex_index_t idx = goal_idx;
    while (idx != start_idx) {
        path->push_back(idx);
        idx = predecessor[idx];
        assert(idx != -1);
    }
    path->push_back(idx);
    std::reverse(path->begin(), path->end());

    return true;
}

}  // simple_graph
<commit_msg>Reduce object copying in Bellman-Ford algorithm<commit_after>#pragma once

#include <cassert>
#include <vector>
#include "graph.hpp"

namespace simple_graph {

template<typename E>
bool check_distance(const E &d, const E &w)
{
    if ((d > 0) && (w >0) && (std::numeric_limits<E>::max() - d < w)) {
        return false;
    }
    return true;
}

template<typename V, typename E>
bool bellman_ford(const Graph<V, E> &g, vertex_index_t start_idx, vertex_index_t goal_idx,
        std::vector<vertex_index_t> *path)
{
    // TODO add utility function to check passed vertex indices
    if ((start_idx < 0) || (goal_idx < 0)) {
        return false;
    }

    std::vector<E> distance(g.vertex_num(), std::numeric_limits<E>::max());
    std::vector<vertex_index_t> predecessor(g.vertex_num(), -1);

    distance[start_idx] = 0;

    Graph<V, E> *fg = const_cast<Graph<V, E>*>(&g);
    for (size_t i = 0; i < g.vertex_num(); ++i) {
        bool changed = false;
        for (const auto &edge : fg->edges()) {
            if (check_distance(distance[edge.idx1()], edge.weight())
                    && (distance[edge.idx1()] + edge.weight() < distance[edge.idx2()])) {
                distance[edge.idx2()] = distance[edge.idx1()] + edge.weight();
                predecessor[edge.idx2()] = edge.idx1();
                changed = true;
            }
        }
        if (!changed) {
            break;
        }
    }

    for (const auto &edge : fg->edges()) {
        if (check_distance(distance[edge.idx1()], edge.weight())
                && (distance[edge.idx1()] + edge.weight() < distance[edge.idx2()])) {
            return false;
        }
    }

    if (distance[goal_idx] == std::numeric_limits<E>::max()) {
        return false;
    }

    vertex_index_t idx = goal_idx;
    while (idx != start_idx) {
        path->push_back(idx);
        idx = predecessor[idx];
        assert(idx != -1);
    }
    path->push_back(idx);
    std::reverse(path->begin(), path->end());

    return true;
}

}  // simple_graph
<|endoftext|>


<commit_before>#include <ctype.h>
#include <iostream>
#include <fstream>
#include <string>

#include <string.h>	/* strcmp() */
#include <stdlib.h>	/* exit() */
#include "ptbl_funct.h"
#include "pri.h"
#include "gts_master.h"
#include "gts_gui.h"
#include "memory_desktop.h"

#if defined(HAVE_CONFIG_H)
#  include <config.h>
#endif

static void print_version( char *title )
{
pri_funct_msg_vr( "%s  %s  %s",
	title,
	cl_gts_master.cp_release_date(),
	cl_gts_master.cp_release_number()
);
}

static void print_help( char *title, gts_master *clp_master )
{
pri_funct_msg_vr( "Usage : %s [option]", title );
pri_funct_msg_vr( "Option");
pri_funct_msg_vr( " -version : print VERSION");
pri_funct_msg_vr( " -help    : print HELP");
pri_funct_msg_vr( " -bv      : Basic Verbose on");
pri_funct_msg_vr( " -cv      : Counter Verbose on");
pri_funct_msg_vr( "File Format");
pri_funct_msg_vr( " TIFF          (8,16bits)(.tif)" );
pri_funct_msg_vr( " Targa            (8bits)(.tga,.TGA)" );
}

static int argument_analyzer( int argc, char *argv[], char *cp_comm, gts_master *clp_master )
{
	int	ii;

	for (ii = 1; ii < argc; ++ii) {
		if      (!strcmp( argv[ii], "-version" )) {
			print_version( cp_comm ); exit (0);
		}
		else if (!strcmp( argv[ii], "-help"    )) {
			print_help( cp_comm, clp_master ); exit (0);
		}
		else if (!strcmp( argv[ii], "-bv" )) {
			clp_master->i_pv_sw( ON );
			clp_master->i_mv_sw( ON );
		}
		else if (!strcmp( argv[ii], "-cv" )) {
			clp_master->i_cv_sw( ON );
		}

		else if ('-' == argv[ii][0]) {
			pri_funct_err_bttvr(
				"Error: bad option<%s>", argv[ii]  );
			print_help( cp_comm, clp_master );
			return NG;
		}
		else {
			pri_funct_err_bttvr(
				"Error: bad argument<%s>",argv[ii] );
			print_help( cp_comm, clp_master );
			return NG;
		}
	}
	return OK;
}

/* リリース名、版、日付 */
#ifdef PACKAGE_NAME
gts_master cl_gts_master(PACKAGE_NAME, PACKAGE_VERSION, CONFIGURATION_DATE);
# else
gts_master cl_gts_master( "gts" ,"2.4.0.041" ,"2017-12-18" );
# endif

int main( int argc, char **argv )
{
	/* 以後のプリント表示にコマンド名を付加する */
	pri_funct_set_cp_title( (char *)cl_gts_master.cp_release_name() );

	/* 初期化設定を設定ファイルから行なう */
	//setup_gts_( argv[0] );
	//cl_gts_master.cl_memo_install_setup.load( argv[0] );

	/* 引数による設定や実行 */
	if (OK != argument_analyzer(
	argc, argv,
	(char *)cl_gts_master.cp_release_name(), &cl_gts_master )) {
		pri_funct_err_bttvr(
	 "Error : argument_analyzer(-) returns NG"  );
		return 2;
	}

	/* 全実行 */
	return cl_gts_master.exec( argv[0] );
}

<commit_msg>set version 2.4.0.042<commit_after>#include <ctype.h>
#include <iostream>
#include <fstream>
#include <string>

#include <string.h>	/* strcmp() */
#include <stdlib.h>	/* exit() */
#include "ptbl_funct.h"
#include "pri.h"
#include "gts_master.h"
#include "gts_gui.h"
#include "memory_desktop.h"

#if defined(HAVE_CONFIG_H)
#  include <config.h>
#endif

static void print_version( char *title )
{
pri_funct_msg_vr( "%s  %s  %s",
	title,
	cl_gts_master.cp_release_date(),
	cl_gts_master.cp_release_number()
);
}

static void print_help( char *title, gts_master *clp_master )
{
pri_funct_msg_vr( "Usage : %s [option]", title );
pri_funct_msg_vr( "Option");
pri_funct_msg_vr( " -version : print VERSION");
pri_funct_msg_vr( " -help    : print HELP");
pri_funct_msg_vr( " -bv      : Basic Verbose on");
pri_funct_msg_vr( " -cv      : Counter Verbose on");
pri_funct_msg_vr( "File Format");
pri_funct_msg_vr( " TIFF          (8,16bits)(.tif)" );
pri_funct_msg_vr( " Targa            (8bits)(.tga,.TGA)" );
}

static int argument_analyzer( int argc, char *argv[], char *cp_comm, gts_master *clp_master )
{
	int	ii;

	for (ii = 1; ii < argc; ++ii) {
		if      (!strcmp( argv[ii], "-version" )) {
			print_version( cp_comm ); exit (0);
		}
		else if (!strcmp( argv[ii], "-help"    )) {
			print_help( cp_comm, clp_master ); exit (0);
		}
		else if (!strcmp( argv[ii], "-bv" )) {
			clp_master->i_pv_sw( ON );
			clp_master->i_mv_sw( ON );
		}
		else if (!strcmp( argv[ii], "-cv" )) {
			clp_master->i_cv_sw( ON );
		}

		else if ('-' == argv[ii][0]) {
			pri_funct_err_bttvr(
				"Error: bad option<%s>", argv[ii]  );
			print_help( cp_comm, clp_master );
			return NG;
		}
		else {
			pri_funct_err_bttvr(
				"Error: bad argument<%s>",argv[ii] );
			print_help( cp_comm, clp_master );
			return NG;
		}
	}
	return OK;
}

/* リリース名、版、日付 */
#ifdef PACKAGE_NAME
gts_master cl_gts_master(PACKAGE_NAME, PACKAGE_VERSION, CONFIGURATION_DATE);
# else
gts_master cl_gts_master( "gts" ,"2.4.0.042" ,"2017-12-19" );
# endif

int main( int argc, char **argv )
{
	/* 以後のプリント表示にコマンド名を付加する */
	pri_funct_set_cp_title( (char *)cl_gts_master.cp_release_name() );

	/* 初期化設定を設定ファイルから行なう */
	//setup_gts_( argv[0] );
	//cl_gts_master.cl_memo_install_setup.load( argv[0] );

	/* 引数による設定や実行 */
	if (OK != argument_analyzer(
	argc, argv,
	(char *)cl_gts_master.cp_release_name(), &cl_gts_master )) {
		pri_funct_err_bttvr(
	 "Error : argument_analyzer(-) returns NG"  );
		return 2;
	}

	/* 全実行 */
	return cl_gts_master.exec( argv[0] );
}

<|endoftext|>


<commit_before>#include "worker.h"
#include "service.h"
#include "router.h"

#include <csignal>
#include <iostream>

namespace REST {

int Worker::POOL_SIZE = 256;

Worker::Worker(int i, int sc, size_t* cc) :
 id(i), streamers_count(sc), clients_count(cc) {
  THREAD_NAME("rest-cpp - main thread");
  *cc = 0;
  server_header = "rest-cpp, worker " + std::to_string(id);
  run();
}

void Worker::run() {
  should_run = true;

  thread = std::thread([this] () {
    THREAD_NAME(server_header.c_str());

    signal(SIGPIPE, SIG_IGN);

    // while worker is alive
    while (should_run) {
      Request::client client;
      {
        std::unique_lock<std::mutex> queue_lock(clients_queue_lock);

        // wait for new request
        clients_queue_ready.wait(queue_lock, [this] { return !should_run || !clients_queue.empty(); });
        client = clients_queue.front();
        clients_queue.pop();
      }

      if (!should_run)
        break;

      // make request
      Request::shared request = Request::make(client);

      Response::shared response(new Response(request, &streamers));
      response->headers["Server"] = server_header + ", waiting " + std::to_string(*clients_count);

      try {
        // std::cout << "Request '" << request->path << "' - worker #"<<id<<", handle #"<<request->handle<<"\n";

        make_action(request, response);

        response->send();

      } catch (HTTP::Error &e) {
        Response::unique error_response(new Response(request, e));
        error_response->headers.insert(response->headers.begin(), response->headers.end());
        error_response->send();
      }

      if (streamers.size() >= streamers_count) {
        for (auto& s : streamers)
          s.join();
        streamers.clear();
      }

      if ((*clients_count) > 0)
        (*clients_count)--;
    }

    std::cout << "Stopped worker #" << id << std::endl;
  });
}

void Worker::make_action(Request::shared request, Response::shared response) {
  std::shared_ptr<Service> service = Router::find(request, id);

  if (service == nullptr)
    throw HTTP::NotFound();

  service->request = request;
  service->response = response;

  service->make_action();
}

void Worker::stop() {
  should_run = false;
  for (auto& s : streamers)
    s.join();
  streamers.clear();
  clients_queue_ready.notify_one();
  thread.join();
}

}
<commit_msg>guard is requiered<commit_after>#include "worker.h"
#include "service.h"
#include "router.h"

#include <csignal>
#include <iostream>

namespace REST {

int Worker::POOL_SIZE = 256;

Worker::Worker(int i, int sc, size_t* cc) :
 id(i), streamers_count(sc), clients_count(cc) {
  THREAD_NAME("rest-cpp - main thread");
  *cc = 0;
  server_header = "rest-cpp, worker " + std::to_string(id);
  streamers.reserve(sc);
  run();
}

void Worker::run() {
  should_run = true;

  thread = std::thread([this] () {
    THREAD_NAME(server_header.c_str());

    signal(SIGPIPE, SIG_IGN);

    // while worker is alive
    while (should_run) {
      Request::client client;
      {
        std::unique_lock<std::mutex> queue_lock(clients_queue_lock);

        // wait for new request
        clients_queue_ready.wait(queue_lock, [this] { return !should_run || !clients_queue.empty(); });
        client = clients_queue.front();
        clients_queue.pop();
      }

      if (!should_run)
        break;

      // make request
      Request::shared request = Request::make(client);

      Response::shared response(new Response(request, &streamers));
      response->headers["Server"] = server_header + ", waiting " + std::to_string(*clients_count);

      try {
        // std::cout << "Request '" << request->path << "' - worker #"<<id<<", handle #"<<request->handle<<"\n";

        make_action(request, response);

        response->send();

      } catch (HTTP::Error &e) {
        Response::unique error_response(new Response(request, e));
        error_response->headers.insert(response->headers.begin(), response->headers.end());
        error_response->send();
      }

      if (streamers.size() >= streamers_count) {
        for (auto& s : streamers)
          s.join();
        streamers.clear();
      }

      if ((*clients_count) > 0)
        (*clients_count)--;
    }

    std::cout << "Stopped worker #" << id << std::endl;
  });
}

void Worker::make_action(Request::shared request, Response::shared response) {
  std::shared_ptr<Service> service = Router::find(request, id);

  if (service == nullptr)
    throw HTTP::NotFound();

  service->request = request;
  service->response = response;

  service->make_action();
}

void Worker::stop() {
  should_run = false;
  for (auto& s : streamers)
    s.join();
  streamers.clear();
  clients_queue_ready.notify_one();
  thread.join();
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "chrome/browser/chrome_browser_main_win.h"

#include <windows.h>
#include <shellapi.h>

#include <algorithm>

#include "base/command_line.h"
#include "base/environment.h"
#include "base/i18n/rtl.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/scoped_native_library.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/win/metro.h"
#include "base/win/windows_version.h"
#include "base/win/wrapped_window_proc.h"
#include "chrome/browser/browser_util_win.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/media_gallery/media_device_notifications_window_win.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_shortcut_manager_win.h"
#include "chrome/browser/ui/simple_message_box.h"
#include "chrome/browser/ui/uninstall_browser_prompt.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_result_codes.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/l10n_string_util.h"
#include "chrome/installer/util/shell_util.h"
#include "content/public/common/main_function_params.h"
#include "grit/app_locale_settings.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "installer_util_strings/installer_util_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/win/message_box_win.h"
#include "ui/gfx/platform_font_win.h"

namespace {

typedef HRESULT (STDAPICALLTYPE* RegisterApplicationRestartProc)(
    const wchar_t* command_line,
    DWORD flags);

void InitializeWindowProcExceptions() {
  // Get the breakpad pointer from chrome.exe
  base::win::WinProcExceptionFilter exception_filter =
      reinterpret_cast<base::win::WinProcExceptionFilter>(
          ::GetProcAddress(::GetModuleHandle(
                               chrome::kBrowserProcessExecutableName),
                           "CrashForException"));
  exception_filter = base::win::SetWinProcExceptionFilter(exception_filter);
  DCHECK(!exception_filter);
}

// gfx::Font callbacks
void AdjustUIFont(LOGFONT* logfont) {
  l10n_util::AdjustUIFont(logfont);
}

int GetMinimumFontSize() {
  int min_font_size;
  base::StringToInt(l10n_util::GetStringUTF16(IDS_MINIMUM_UI_FONT_SIZE),
                    &min_font_size);
  return min_font_size;
}

class TranslationDelegate : public installer::TranslationDelegate {
 public:
  virtual string16 GetLocalizedString(int installer_string_id) OVERRIDE;
};

}  // namespace

void RecordBreakpadStatusUMA(MetricsService* metrics) {
  metrics->RecordBreakpadHasDebugger(TRUE == ::IsDebuggerPresent());
}

void WarnAboutMinimumSystemRequirements() {
  if (base::win::GetVersion() < base::win::VERSION_XP) {
    const string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
    const string16 message =
        l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP);
    browser::ShowMessageBox(NULL, title, message,
                            browser::MESSAGE_BOX_TYPE_WARNING);
  }
}

void RecordBrowserStartupTime() {
  // Calculate the time that has elapsed from our own process creation.
  FILETIME creation_time = {};
  FILETIME ignore = {};
  ::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore, &ignore,
      &ignore);

  RecordPreReadExperimentTime("Startup.BrowserMessageLoopStartTime",
      base::Time::Now() - base::Time::FromFileTime(creation_time));
}

void ShowCloseBrowserFirstMessageBox() {
  const string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
  const string16 message = l10n_util::GetStringUTF16(IDS_UNINSTALL_CLOSE_APP);
  browser::ShowMessageBox(NULL, title, message,
                          browser::MESSAGE_BOX_TYPE_WARNING);
}

int DoUninstallTasks(bool chrome_still_running) {
  // We want to show a warning to user (and exit) if Chrome is already running
  // *before* we show the uninstall confirmation dialog box. But while the
  // uninstall confirmation dialog is up, user might start Chrome, so we
  // check once again after user acknowledges Uninstall dialog.
  if (chrome_still_running) {
    ShowCloseBrowserFirstMessageBox();
    return chrome::RESULT_CODE_UNINSTALL_CHROME_ALIVE;
  }
  int result = browser::ShowUninstallBrowserPrompt();
  if (browser_util::IsBrowserAlreadyRunning()) {
    ShowCloseBrowserFirstMessageBox();
    return chrome::RESULT_CODE_UNINSTALL_CHROME_ALIVE;
  }

  if (result != chrome::RESULT_CODE_UNINSTALL_USER_CANCEL) {
    // The following actions are just best effort.
    VLOG(1) << "Executing uninstall actions";
    if (!first_run::RemoveSentinel())
      VLOG(1) << "Failed to delete sentinel file.";
    // We want to remove user level shortcuts and we only care about the ones
    // created by us and not by the installer so |alternate| is false.
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    if (!ShellUtil::RemoveChromeDesktopShortcut(
            dist, ShellUtil::CURRENT_USER, ShellUtil::SHORTCUT_NO_OPTIONS)) {
      VLOG(1) << "Failed to delete desktop shortcut.";
    }
    if (!ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames(
        ProfileShortcutManagerWin::GenerateShortcutsFromProfiles(
            ProfileInfoCache::GetProfileNames()))) {
      VLOG(1) << "Failed to delete desktop profiles shortcuts.";
    }
    if (!ShellUtil::RemoveChromeQuickLaunchShortcut(dist,
                                                    ShellUtil::CURRENT_USER)) {
      VLOG(1) << "Failed to delete quick launch shortcut.";
    }
  }
  return result;
}

// ChromeBrowserMainPartsWin ---------------------------------------------------

ChromeBrowserMainPartsWin::ChromeBrowserMainPartsWin(
    const content::MainFunctionParams& parameters)
    : ChromeBrowserMainParts(parameters) {
  if (base::win::GetMetroModule()) {
    CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kEnableTouchEvents);
  }
}

ChromeBrowserMainPartsWin::~ChromeBrowserMainPartsWin() {
}

void ChromeBrowserMainPartsWin::ToolkitInitialized() {
  ChromeBrowserMainParts::ToolkitInitialized();
  gfx::PlatformFontWin::adjust_font_callback = &AdjustUIFont;
  gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize;
}

void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() {
  // installer_util references strings that are normally compiled into
  // setup.exe.  In Chrome, these strings are in the locale files.
  SetupInstallerUtilStrings();

  ChromeBrowserMainParts::PreMainMessageLoopStart();
  if (!parameters().ui_task) {
    // Make sure that we know how to handle exceptions from the message loop.
    InitializeWindowProcExceptions();
  }
  media_device_notifications_window_.reset(
      new chrome::MediaDeviceNotificationsWindowWin());
}

// static
void ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment(
    const CommandLine& parsed_command_line) {
  // Clear this var so child processes don't show the dialog by default.
  scoped_ptr<base::Environment> env(base::Environment::Create());
  env->UnSetVar(env_vars::kShowRestart);

  // For non-interactive tests we don't restart on crash.
  if (env->HasVar(env_vars::kHeadless))
    return;

  // If the known command-line test options are used we don't create the
  // environment block which means we don't get the restart dialog.
  if (parsed_command_line.HasSwitch(switches::kBrowserCrashTest) ||
      parsed_command_line.HasSwitch(switches::kBrowserAssertTest) ||
      parsed_command_line.HasSwitch(switches::kNoErrorDialogs))
    return;

  // The encoding we use for the info is "title|context|direction" where
  // direction is either env_vars::kRtlLocale or env_vars::kLtrLocale depending
  // on the current locale.
  string16 dlg_strings(l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_TITLE));
  dlg_strings.push_back('|');
  string16 adjusted_string(
      l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_CONTENT));
  base::i18n::AdjustStringForLocaleDirection(&adjusted_string);
  dlg_strings.append(adjusted_string);
  dlg_strings.push_back('|');
  dlg_strings.append(ASCIIToUTF16(
      base::i18n::IsRTL() ? env_vars::kRtlLocale : env_vars::kLtrLocale));

  env->SetVar(env_vars::kRestartInfo, UTF16ToUTF8(dlg_strings));
}

// static
void ChromeBrowserMainPartsWin::RegisterApplicationRestart(
    const CommandLine& parsed_command_line) {
  DCHECK(base::win::GetVersion() >= base::win::VERSION_VISTA);
  base::ScopedNativeLibrary library(FilePath(L"kernel32.dll"));
  // Get the function pointer for RegisterApplicationRestart.
  RegisterApplicationRestartProc register_application_restart =
      static_cast<RegisterApplicationRestartProc>(
          library.GetFunctionPointer("RegisterApplicationRestart"));
  if (!register_application_restart) {
    LOG(WARNING) << "Cannot find RegisterApplicationRestart in kernel32.dll";
    return;
  }
  // The Windows Restart Manager expects a string of command line flags only,
  // without the program.
  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendArguments(parsed_command_line, false);
  if (!command_line.HasSwitch(switches::kRestoreLastSession))
    command_line.AppendSwitch(switches::kRestoreLastSession);

  // Restart Chrome if the computer is restarted as the result of an update.
  // This could be extended to handle crashes, hangs, and patches.
  HRESULT hr = register_application_restart(
      command_line.GetCommandLineString().c_str(),
      RESTART_NO_CRASH | RESTART_NO_HANG | RESTART_NO_PATCH);
  if (FAILED(hr)) {
    if (hr == E_INVALIDARG) {
      LOG(WARNING) << "Command line too long for RegisterApplicationRestart";
    } else {
      NOTREACHED() << "RegisterApplicationRestart failed. hr: " << hr <<
                      ", command_line: " << command_line.GetCommandLineString();
    }
  }
}

void ChromeBrowserMainPartsWin::ShowMissingLocaleMessageBox() {
  ui::MessageBox(NULL, ASCIIToUTF16(chrome_browser::kMissingLocaleDataMessage),
                 ASCIIToUTF16(chrome_browser::kMissingLocaleDataTitle),
                 MB_OK | MB_ICONERROR | MB_TOPMOST);
}

// static
int ChromeBrowserMainPartsWin::HandleIconsCommands(
    const CommandLine& parsed_command_line) {
  if (parsed_command_line.HasSwitch(switches::kHideIcons)) {
    string16 cp_applet;
    base::win::Version version = base::win::GetVersion();
    if (version >= base::win::VERSION_VISTA) {
      cp_applet.assign(L"Programs and Features");  // Windows Vista and later.
    } else if (version >= base::win::VERSION_XP) {
      cp_applet.assign(L"Add/Remove Programs");  // Windows XP.
    } else {
      return chrome::RESULT_CODE_UNSUPPORTED_PARAM;  // Not supported
    }

    const string16 msg =
        l10n_util::GetStringFUTF16(IDS_HIDE_ICONS_NOT_SUPPORTED, cp_applet);
    const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
    const UINT flags = MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST;
    if (IDOK == ui::MessageBox(NULL, msg, caption, flags))
      ShellExecute(NULL, NULL, L"appwiz.cpl", NULL, NULL, SW_SHOWNORMAL);

    // Exit as we are not launching the browser.
    return content::RESULT_CODE_NORMAL_EXIT;
  }
  // We don't hide icons so we shouldn't do anything special to show them
  return chrome::RESULT_CODE_UNSUPPORTED_PARAM;
}

// static
bool ChromeBrowserMainPartsWin::CheckMachineLevelInstall() {
  // TODO(tommi): Check if using the default distribution is always the right
  // thing to do.
  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
  scoped_ptr<Version> version(InstallUtil::GetChromeVersion(dist, true));
  if (version.get()) {
    FilePath exe_path;
    PathService::Get(base::DIR_EXE, &exe_path);
    std::wstring exe = exe_path.value();
    FilePath user_exe_path(installer::GetChromeInstallPath(false, dist));
    if (FilePath::CompareEqualIgnoreCase(exe, user_exe_path.value())) {
      const string16 text =
          l10n_util::GetStringUTF16(IDS_MACHINE_LEVEL_INSTALL_CONFLICT);
      const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
      const UINT flags = MB_OK | MB_ICONERROR | MB_TOPMOST;
      ui::MessageBox(NULL, text, caption, flags);
      CommandLine uninstall_cmd(
          InstallUtil::GetChromeUninstallCmd(false, dist->GetType()));
      if (!uninstall_cmd.GetProgram().empty()) {
        uninstall_cmd.AppendSwitch(installer::switches::kForceUninstall);
        uninstall_cmd.AppendSwitch(
            installer::switches::kDoNotRemoveSharedItems);
        base::LaunchProcess(uninstall_cmd, base::LaunchOptions(), NULL);
      }
      return true;
    }
  }
  return false;
}

string16 TranslationDelegate::GetLocalizedString(int installer_string_id) {
  int resource_id = 0;
  switch (installer_string_id) {
  // HANDLE_STRING is used by the DO_INSTALLER_STRING_MAPPING macro which is in
  // the generated header installer_util_strings.h.
#define HANDLE_STRING(base_id, chrome_id) \
  case base_id: \
    resource_id = chrome_id; \
    break;
  DO_INSTALLER_STRING_MAPPING
#undef HANDLE_STRING
  default:
    NOTREACHED();
  }
  if (resource_id)
    return l10n_util::GetStringUTF16(resource_id);
  return string16();
}

// static
void ChromeBrowserMainPartsWin::SetupInstallerUtilStrings() {
  CR_DEFINE_STATIC_LOCAL(TranslationDelegate, delegate, ());
  installer::SetTranslationDelegate(&delegate);
}
<commit_msg>Removing the enable-touch-events flag temporarily from metro mode as touch is currently broken.<commit_after>// Copyright (c) 2012 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 "chrome/browser/chrome_browser_main_win.h"

#include <windows.h>
#include <shellapi.h>

#include <algorithm>

#include "base/command_line.h"
#include "base/environment.h"
#include "base/i18n/rtl.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/scoped_native_library.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/win/metro.h"
#include "base/win/windows_version.h"
#include "base/win/wrapped_window_proc.h"
#include "chrome/browser/browser_util_win.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/media_gallery/media_device_notifications_window_win.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_shortcut_manager_win.h"
#include "chrome/browser/ui/simple_message_box.h"
#include "chrome/browser/ui/uninstall_browser_prompt.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_result_codes.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/l10n_string_util.h"
#include "chrome/installer/util/shell_util.h"
#include "content/public/common/main_function_params.h"
#include "grit/app_locale_settings.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "installer_util_strings/installer_util_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/win/message_box_win.h"
#include "ui/gfx/platform_font_win.h"

namespace {

typedef HRESULT (STDAPICALLTYPE* RegisterApplicationRestartProc)(
    const wchar_t* command_line,
    DWORD flags);

void InitializeWindowProcExceptions() {
  // Get the breakpad pointer from chrome.exe
  base::win::WinProcExceptionFilter exception_filter =
      reinterpret_cast<base::win::WinProcExceptionFilter>(
          ::GetProcAddress(::GetModuleHandle(
                               chrome::kBrowserProcessExecutableName),
                           "CrashForException"));
  exception_filter = base::win::SetWinProcExceptionFilter(exception_filter);
  DCHECK(!exception_filter);
}

// gfx::Font callbacks
void AdjustUIFont(LOGFONT* logfont) {
  l10n_util::AdjustUIFont(logfont);
}

int GetMinimumFontSize() {
  int min_font_size;
  base::StringToInt(l10n_util::GetStringUTF16(IDS_MINIMUM_UI_FONT_SIZE),
                    &min_font_size);
  return min_font_size;
}

class TranslationDelegate : public installer::TranslationDelegate {
 public:
  virtual string16 GetLocalizedString(int installer_string_id) OVERRIDE;
};

}  // namespace

void RecordBreakpadStatusUMA(MetricsService* metrics) {
  metrics->RecordBreakpadHasDebugger(TRUE == ::IsDebuggerPresent());
}

void WarnAboutMinimumSystemRequirements() {
  if (base::win::GetVersion() < base::win::VERSION_XP) {
    const string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
    const string16 message =
        l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP);
    browser::ShowMessageBox(NULL, title, message,
                            browser::MESSAGE_BOX_TYPE_WARNING);
  }
}

void RecordBrowserStartupTime() {
  // Calculate the time that has elapsed from our own process creation.
  FILETIME creation_time = {};
  FILETIME ignore = {};
  ::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore, &ignore,
      &ignore);

  RecordPreReadExperimentTime("Startup.BrowserMessageLoopStartTime",
      base::Time::Now() - base::Time::FromFileTime(creation_time));
}

void ShowCloseBrowserFirstMessageBox() {
  const string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
  const string16 message = l10n_util::GetStringUTF16(IDS_UNINSTALL_CLOSE_APP);
  browser::ShowMessageBox(NULL, title, message,
                          browser::MESSAGE_BOX_TYPE_WARNING);
}

int DoUninstallTasks(bool chrome_still_running) {
  // We want to show a warning to user (and exit) if Chrome is already running
  // *before* we show the uninstall confirmation dialog box. But while the
  // uninstall confirmation dialog is up, user might start Chrome, so we
  // check once again after user acknowledges Uninstall dialog.
  if (chrome_still_running) {
    ShowCloseBrowserFirstMessageBox();
    return chrome::RESULT_CODE_UNINSTALL_CHROME_ALIVE;
  }
  int result = browser::ShowUninstallBrowserPrompt();
  if (browser_util::IsBrowserAlreadyRunning()) {
    ShowCloseBrowserFirstMessageBox();
    return chrome::RESULT_CODE_UNINSTALL_CHROME_ALIVE;
  }

  if (result != chrome::RESULT_CODE_UNINSTALL_USER_CANCEL) {
    // The following actions are just best effort.
    VLOG(1) << "Executing uninstall actions";
    if (!first_run::RemoveSentinel())
      VLOG(1) << "Failed to delete sentinel file.";
    // We want to remove user level shortcuts and we only care about the ones
    // created by us and not by the installer so |alternate| is false.
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    if (!ShellUtil::RemoveChromeDesktopShortcut(
            dist, ShellUtil::CURRENT_USER, ShellUtil::SHORTCUT_NO_OPTIONS)) {
      VLOG(1) << "Failed to delete desktop shortcut.";
    }
    if (!ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames(
        ProfileShortcutManagerWin::GenerateShortcutsFromProfiles(
            ProfileInfoCache::GetProfileNames()))) {
      VLOG(1) << "Failed to delete desktop profiles shortcuts.";
    }
    if (!ShellUtil::RemoveChromeQuickLaunchShortcut(dist,
                                                    ShellUtil::CURRENT_USER)) {
      VLOG(1) << "Failed to delete quick launch shortcut.";
    }
  }
  return result;
}

// ChromeBrowserMainPartsWin ---------------------------------------------------

ChromeBrowserMainPartsWin::ChromeBrowserMainPartsWin(
    const content::MainFunctionParams& parameters)
    : ChromeBrowserMainParts(parameters) {
}

ChromeBrowserMainPartsWin::~ChromeBrowserMainPartsWin() {
}

void ChromeBrowserMainPartsWin::ToolkitInitialized() {
  ChromeBrowserMainParts::ToolkitInitialized();
  gfx::PlatformFontWin::adjust_font_callback = &AdjustUIFont;
  gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize;
}

void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() {
  // installer_util references strings that are normally compiled into
  // setup.exe.  In Chrome, these strings are in the locale files.
  SetupInstallerUtilStrings();

  ChromeBrowserMainParts::PreMainMessageLoopStart();
  if (!parameters().ui_task) {
    // Make sure that we know how to handle exceptions from the message loop.
    InitializeWindowProcExceptions();
  }
  media_device_notifications_window_.reset(
      new chrome::MediaDeviceNotificationsWindowWin());
}

// static
void ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment(
    const CommandLine& parsed_command_line) {
  // Clear this var so child processes don't show the dialog by default.
  scoped_ptr<base::Environment> env(base::Environment::Create());
  env->UnSetVar(env_vars::kShowRestart);

  // For non-interactive tests we don't restart on crash.
  if (env->HasVar(env_vars::kHeadless))
    return;

  // If the known command-line test options are used we don't create the
  // environment block which means we don't get the restart dialog.
  if (parsed_command_line.HasSwitch(switches::kBrowserCrashTest) ||
      parsed_command_line.HasSwitch(switches::kBrowserAssertTest) ||
      parsed_command_line.HasSwitch(switches::kNoErrorDialogs))
    return;

  // The encoding we use for the info is "title|context|direction" where
  // direction is either env_vars::kRtlLocale or env_vars::kLtrLocale depending
  // on the current locale.
  string16 dlg_strings(l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_TITLE));
  dlg_strings.push_back('|');
  string16 adjusted_string(
      l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_CONTENT));
  base::i18n::AdjustStringForLocaleDirection(&adjusted_string);
  dlg_strings.append(adjusted_string);
  dlg_strings.push_back('|');
  dlg_strings.append(ASCIIToUTF16(
      base::i18n::IsRTL() ? env_vars::kRtlLocale : env_vars::kLtrLocale));

  env->SetVar(env_vars::kRestartInfo, UTF16ToUTF8(dlg_strings));
}

// static
void ChromeBrowserMainPartsWin::RegisterApplicationRestart(
    const CommandLine& parsed_command_line) {
  DCHECK(base::win::GetVersion() >= base::win::VERSION_VISTA);
  base::ScopedNativeLibrary library(FilePath(L"kernel32.dll"));
  // Get the function pointer for RegisterApplicationRestart.
  RegisterApplicationRestartProc register_application_restart =
      static_cast<RegisterApplicationRestartProc>(
          library.GetFunctionPointer("RegisterApplicationRestart"));
  if (!register_application_restart) {
    LOG(WARNING) << "Cannot find RegisterApplicationRestart in kernel32.dll";
    return;
  }
  // The Windows Restart Manager expects a string of command line flags only,
  // without the program.
  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendArguments(parsed_command_line, false);
  if (!command_line.HasSwitch(switches::kRestoreLastSession))
    command_line.AppendSwitch(switches::kRestoreLastSession);

  // Restart Chrome if the computer is restarted as the result of an update.
  // This could be extended to handle crashes, hangs, and patches.
  HRESULT hr = register_application_restart(
      command_line.GetCommandLineString().c_str(),
      RESTART_NO_CRASH | RESTART_NO_HANG | RESTART_NO_PATCH);
  if (FAILED(hr)) {
    if (hr == E_INVALIDARG) {
      LOG(WARNING) << "Command line too long for RegisterApplicationRestart";
    } else {
      NOTREACHED() << "RegisterApplicationRestart failed. hr: " << hr <<
                      ", command_line: " << command_line.GetCommandLineString();
    }
  }
}

void ChromeBrowserMainPartsWin::ShowMissingLocaleMessageBox() {
  ui::MessageBox(NULL, ASCIIToUTF16(chrome_browser::kMissingLocaleDataMessage),
                 ASCIIToUTF16(chrome_browser::kMissingLocaleDataTitle),
                 MB_OK | MB_ICONERROR | MB_TOPMOST);
}

// static
int ChromeBrowserMainPartsWin::HandleIconsCommands(
    const CommandLine& parsed_command_line) {
  if (parsed_command_line.HasSwitch(switches::kHideIcons)) {
    string16 cp_applet;
    base::win::Version version = base::win::GetVersion();
    if (version >= base::win::VERSION_VISTA) {
      cp_applet.assign(L"Programs and Features");  // Windows Vista and later.
    } else if (version >= base::win::VERSION_XP) {
      cp_applet.assign(L"Add/Remove Programs");  // Windows XP.
    } else {
      return chrome::RESULT_CODE_UNSUPPORTED_PARAM;  // Not supported
    }

    const string16 msg =
        l10n_util::GetStringFUTF16(IDS_HIDE_ICONS_NOT_SUPPORTED, cp_applet);
    const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
    const UINT flags = MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST;
    if (IDOK == ui::MessageBox(NULL, msg, caption, flags))
      ShellExecute(NULL, NULL, L"appwiz.cpl", NULL, NULL, SW_SHOWNORMAL);

    // Exit as we are not launching the browser.
    return content::RESULT_CODE_NORMAL_EXIT;
  }
  // We don't hide icons so we shouldn't do anything special to show them
  return chrome::RESULT_CODE_UNSUPPORTED_PARAM;
}

// static
bool ChromeBrowserMainPartsWin::CheckMachineLevelInstall() {
  // TODO(tommi): Check if using the default distribution is always the right
  // thing to do.
  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
  scoped_ptr<Version> version(InstallUtil::GetChromeVersion(dist, true));
  if (version.get()) {
    FilePath exe_path;
    PathService::Get(base::DIR_EXE, &exe_path);
    std::wstring exe = exe_path.value();
    FilePath user_exe_path(installer::GetChromeInstallPath(false, dist));
    if (FilePath::CompareEqualIgnoreCase(exe, user_exe_path.value())) {
      const string16 text =
          l10n_util::GetStringUTF16(IDS_MACHINE_LEVEL_INSTALL_CONFLICT);
      const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
      const UINT flags = MB_OK | MB_ICONERROR | MB_TOPMOST;
      ui::MessageBox(NULL, text, caption, flags);
      CommandLine uninstall_cmd(
          InstallUtil::GetChromeUninstallCmd(false, dist->GetType()));
      if (!uninstall_cmd.GetProgram().empty()) {
        uninstall_cmd.AppendSwitch(installer::switches::kForceUninstall);
        uninstall_cmd.AppendSwitch(
            installer::switches::kDoNotRemoveSharedItems);
        base::LaunchProcess(uninstall_cmd, base::LaunchOptions(), NULL);
      }
      return true;
    }
  }
  return false;
}

string16 TranslationDelegate::GetLocalizedString(int installer_string_id) {
  int resource_id = 0;
  switch (installer_string_id) {
  // HANDLE_STRING is used by the DO_INSTALLER_STRING_MAPPING macro which is in
  // the generated header installer_util_strings.h.
#define HANDLE_STRING(base_id, chrome_id) \
  case base_id: \
    resource_id = chrome_id; \
    break;
  DO_INSTALLER_STRING_MAPPING
#undef HANDLE_STRING
  default:
    NOTREACHED();
  }
  if (resource_id)
    return l10n_util::GetStringUTF16(resource_id);
  return string16();
}

// static
void ChromeBrowserMainPartsWin::SetupInstallerUtilStrings() {
  CR_DEFINE_STATIC_LOCAL(TranslationDelegate, delegate, ());
  installer::SetTranslationDelegate(&delegate);
}
<|endoftext|>


<commit_before>/*
 * Retina1DPattern.cpp
 *
 *  Created on: Apr 25, 2009
 *      Author: gkenyon
 */

#include "Retina1D.hpp"
#include <stdlib.h>
#include <assert.h>

namespace PV {

//Retina1D::Retina1D() : Retina() {
//}

Retina1D::Retina1D(const char * name, HyPerCol * hc) :
	Retina(name, hc) {
	targ1D = (pvdata_t *) malloc(sizeof(clayer->numNeurons));
	createImage(clayer->V);
}

Retina1D::~Retina1D(){
	free(targ1D);
}

int Retina1D::createImage(pvdata_t * localBuf) {

	// local HyPerCube dimensions
	const int nx = clayer->loc.nx;
	const int ny = clayer->loc.ny;
	const int nf = clayer->numFeatures;

	// only one MPI node creates global image
	if (l->columnId == 0) {

		// global layer dimensions
		float nxGlobal = clayer->loc.nxGlobal;
		float nyGlobal = clayer->loc.nyGlobal;
		float kx0 = clayer->loc.kx0;
		float ky0 = clayer->loc.ky0;
		float xMidGlobal = nxGlobal / 2.0;
		float yMidGlobal = nyGlobal / 2.0;

		// target is built from a specified number of
		// spaced segments separated by gaps
		// keeping the average density == clutterProb
		int numTargs = 2;  // TODO: read from params file
		int lenTarg = 8;   // TODO: read from params file
		lenTarg = (lenTarg > 0) ? lenTarg : 1; //can't have lenTarg == 0
		float clutterProb = 0.5;     // TODO: read from params file
		float clutterProbMin = ((numTargs * lenTarg) > 0) ? (numTargs * lenTarg
				/ (float) nx) : clutterProb;
		clutterProb = (clutterProb < clutterProbMin) ? clutterProbMin : clutterProb;
		// default all pixels to clutterProb
		for (int k = 0; k < clayer->numNeurons; k++) {
			localBuf[k] = rand() < (int) ( clutterProb * RAND_MAX );
			targ1D[k] = 0;
		}

		// set lenGap so that average density equals clutterProb
		int lenGap = (clutterProb > 0) ? (lenTarg * (1.0 - clutterProb)
				/ clutterProb) : 0;
		int beginTarg = rand() % ( nx - numTargs * (lenGap + lenTarg) );

		for (int iSeg = 0; iSeg < numTargs; iSeg++) {
			int startSeg = iSeg * (lenTarg + lenGap) + beginTarg;
			int endSeg = startSeg + lenTarg - 1;
			for (int iTarg = startSeg; iTarg < endSeg; iTarg++) {
				localBuf[iTarg] = 1;
				targ1D[iTarg] = 1;
			}
			int startGap = endSeg + 1;
			int endGap = startGap + lenGap - 1;
			for (int iGap = startGap; iGap < endGap; iGap++) {
				localBuf[iGap] = 0;
			}
		}
		// f[0] are OFF, f[1] are ON cells
		assert(nf == 1 || nf == 2);
		if (nf == 2) {
			for (int k = 0; k < nx * ny; k++) {
				localBuf[2 * k] = localBuf[k];
				localBuf[2 * k + 1] = 0;
			}
		}
	}

	scatterReadBuf(l, globalBuf, localBuf, comm);

	return 0;
}

}
<commit_msg>fixed target to match global coordinates<commit_after>/*
 * Retina1DPattern.cpp
 *
 *  Created on: Apr 25, 2009
 *      Author: gkenyon
 */

#include "Retina1D.hpp"
#include <stdlib.h>
#include <assert.h>
#include "src/io/io.h"

namespace PV {

//Retina1D::Retina1D() : Retina() {
//}

Retina1D::Retina1D(const char * name, HyPerCol * hc) :
	Retina(name, hc) {
	targ1D = (pvdata_t *) malloc(sizeof(pvdata_t)*(clayer->numNeurons));
	createImage(clayer->V);
}

Retina1D::~Retina1D(){
	free(targ1D);
}

int Retina1D::createImage(pvdata_t * localBuf) {

	// local HyPerCube dimensions
	const int nx = clayer->loc.nx;
//	const int ny = clayer->loc.ny;
	const int nf = clayer->numFeatures;
	const int numNeurons = clayer->numNeurons;

	// global layer dimensions: every node processes whole image
	const int nxGlobal = clayer->loc.nxGlobal;
	const int nyGlobal = clayer->loc.nyGlobal;
	const int nfGlobal = nf; //clayer->numFeatures;
	const int numNeuronsGlobal = nxGlobal * nyGlobal * nfGlobal;
//	const int kx0 = clayer->loc.kx0; // assert(kx0 == 0);
//	const int ky0 = clayer->loc.ky0;
//	const int xMidGlobal = nxGlobal / 2.0;
	const int yMidGlobal = nyGlobal / 2.0;
	pvdata_t * globalBuf = (pvdata_t *) malloc(sizeof(pvdata_t) * numNeuronsGlobal);

	// only one MPI node creates global image
	if (clayer->columnId == 0) {

		// target is built from a specified number of
		// spaced segments separated by gaps
		// keeping the average density == clutterProb
		int numTargs = 2;  // TODO: read from params file
		int lenTarg = 8;   // TODO: read from params file
		float clutterProb = 0.5;     // TODO: read from params file
		lenTarg = (lenTarg > 0) ? lenTarg : 1; //can't have lenTarg == 0
		float clutterProbMin = ((numTargs * lenTarg) > 0) ? (numTargs * lenTarg
				/ (float) nxGlobal) : clutterProb;
		clutterProb = (clutterProb < clutterProbMin) ? clutterProbMin : clutterProb;

		// default all pixels to clutterProb
		for (long kg = 0; kg < numNeuronsGlobal; kg++) {
			globalBuf[kg] = rand() < (int) ( clutterProb * RAND_MAX );
		}

		// set lenGap so that average density equals clutterProb
		int lenGap = (clutterProb > 0) ? (lenTarg * (1.0 - clutterProb)
				/ clutterProb) : 0;

		// start 1D target at random location (in global coordinates)
		int beginTargX = rand() % ( nxGlobal - numTargs * (lenGap + lenTarg) );
		int beginTargY = yMidGlobal;
		int beginTargF = 1;

		// make each target segment + gap
		for (int iSeg = 0; iSeg < numTargs; iSeg++) {
			int startSegX = iSeg * (lenTarg + lenGap) + beginTargX;
			int endSegX = startSegX + lenTarg - 1;
			for (int iTargX = startSegX; iTargX < endSegX; iTargX++) {
				int iTargK = kIndex(iTargX, beginTargY, beginTargF, nxGlobal,
						nyGlobal, nfGlobal);
				globalBuf[iTargK] = 1;
			}
			int startGapX = endSegX + 1;
			int endGapX = startGapX + lenGap - 1;
			for (int iGapX = startGapX; iGapX < endGapX; iGapX++) {
				int iGapK = kIndex(iGapX, beginTargY, beginTargF, nxGlobal,
						nyGlobal, nfGlobal);
				globalBuf[iGapK] = 0;
			}
		}

		// if nf == 2 -> f[0] are OFF, f[1] are ON cells
		assert(nf == 1 || nf == 2);
		if (nf == 2) {
			for (int kg = 0; kg < nxGlobal * nyGlobal; kg++) {
				globalBuf[2 * kg] = globalBuf[kg];
				globalBuf[2 * kg + 1] = 0;
			}
		}
	}  // end if (l->columnId == 0)

	scatterReadBuf(this->clayer, globalBuf, localBuf, 0);
	for (int k = 0; k < numNeurons; k++) {
		targ1D[k] = localBuf[k];
	}
	free(globalBuf);

	return 0;
}

}
<|endoftext|>


<commit_before>#include "Resolver.h"

#include "Requirement.h"

#include <cassert>
#include <exception>
#include <map>
#include <set>
#include <stdexcept>

using namespace Arbiter;
using namespace Resolver;

namespace {

struct DependencyNode final
{
  public:
    const ArbiterProjectIdentifier _project;
    const ArbiterSelectedVersion _proposedVersion;

    std::unique_ptr<ArbiterRequirement> _requirement;
    std::set<DependencyNode> _dependencies;

    DependencyNode (ArbiterProjectIdentifier project, ArbiterSelectedVersion proposedVersion, const ArbiterRequirement &requirement)
      : _project(std::move(project))
      , _proposedVersion(std::move(proposedVersion))
      , _requirement(requirement.clone())
    {
      assert(_requirement->satisfiedBy(_proposedVersion._semanticVersion));
    }

    bool operator== (const DependencyNode &other) const
    {
      return _project == other._project && _proposedVersion == other._proposedVersion;
    }

    bool operator< (const DependencyNode &other) const
    {
      if (_project != other._project) {
        // There's no well-defined ordering between nodes for different
        // projects, and we don't want them to appear equal within a set.
        return true;
      }

      // Sort such that higher versions are tried first.
      return _proposedVersion > other._proposedVersion;
    }
};

class DependencyGraph final
{
  public:
    std::set<DependencyNode> _allNodes;
    std::map<DependencyNode, std::set<DependencyNode>> _edges;
    std::set<DependencyNode> _roots;

    bool operator== (const DependencyGraph &other) const
    {
      return _edges == other._edges && _roots == other._roots;
    }
};

} // namespace

ArbiterResolver *ArbiterCreateResolver (ArbiterResolverBehaviors behaviors, const ArbiterDependencyList *dependencyList, ArbiterUserValue context)
{
  return new ArbiterResolver(std::move(behaviors), *dependencyList, ArbiterResolver::Context(std::move(context)));
}

const void *ArbiterResolverContext (const ArbiterResolver *resolver)
{
  return resolver->_context.data();
}

bool ArbiterResolvedAllDependencies (const ArbiterResolver *resolver)
{
  return resolver->resolvedAll();
}

void ArbiterStartResolvingNextDependency (ArbiterResolver *resolver, ArbiterResolverCallbacks callbacks)
{
  resolver->resolveNext().add_callback([resolver, callbacks = std::move(callbacks)](const auto &result) {
    try {
      const ResolvedDependency &dependency = result.rightOrThrowLeft();
      callbacks.onSuccess(resolver, &dependency.projectIdentifier, &dependency.selectedVersion);
    } catch (const std::exception &ex) {
      callbacks.onError(resolver, ex.what());
    }
  });
}

void ArbiterFreeResolver (ArbiterResolver *resolver)
{
  delete resolver;
}

ResolvedDependency ResolvedDependency::takeOwnership (ArbiterDependencyListFetch fetch) noexcept
{
  std::unique_ptr<ArbiterProjectIdentifier> project(const_cast<ArbiterProjectIdentifier *>(fetch.project));
  std::unique_ptr<ArbiterSelectedVersion> selectedVersion(const_cast<ArbiterSelectedVersion *>(fetch.selectedVersion));

  return ResolvedDependency { std::move(*project), std::move(*selectedVersion) };
}

bool ResolvedDependency::operator== (const ResolvedDependency &other) const noexcept
{
  return projectIdentifier == other.projectIdentifier && selectedVersion == other.selectedVersion;
}

bool ArbiterResolver::resolvedAll () const noexcept
{
  return _remainingDependencies._dependencies.empty();
}

Arbiter::Future<ResolvedDependency> resolveNext ()
{
  Arbiter::Promise<ResolvedDependency> promise;

  // TODO: Actually resolve

  return promise.get_future();
}

Arbiter::Future<ArbiterDependencyList> ArbiterResolver::insertDependencyListFetch (ResolvedDependency dependency)
{
  std::lock_guard<std::mutex> guard(_fetchesMutex);

  return _dependencyListFetches[std::move(dependency)].get_future();
}

Arbiter::Promise<ArbiterDependencyList> ArbiterResolver::extractDependencyListFetch (const ResolvedDependency &dependency)
{
  std::lock_guard<std::mutex> guard(_fetchesMutex);

  Arbiter::Promise<ArbiterDependencyList> promise = std::move(_dependencyListFetches.at(dependency));
  _dependencyListFetches.erase(dependency);

  return promise;
}

Arbiter::Future<ArbiterDependencyList> ArbiterResolver::fetchDependencyList (ResolvedDependency dependency)
{
  // Eventually freed in the C callback function.
  auto project = std::make_unique<ArbiterProjectIdentifier>(dependency.projectIdentifier);
  auto version = std::make_unique<ArbiterSelectedVersion>(dependency.selectedVersion);

  auto future = insertDependencyListFetch(std::move(dependency));

  _behaviors.fetchDependencyList(
    ArbiterDependencyListFetch { this, project.release(), version.release() },
    &dependencyListFetchOnSuccess,
    &dependencyListFetchOnError
  );

  return future;
}

void ArbiterResolver::dependencyListFetchOnSuccess (ArbiterDependencyListFetch cFetch, const ArbiterDependencyList *fetchedList)
{
  auto &resolver = *const_cast<ArbiterResolver *>(cFetch.resolver);
  auto dependency = ResolvedDependency::takeOwnership(cFetch);

  resolver
    .extractDependencyListFetch(dependency)
    .set_value(*fetchedList);
}

void ArbiterResolver::dependencyListFetchOnError (ArbiterDependencyListFetch cFetch)
{
  auto &resolver = *const_cast<ArbiterResolver *>(cFetch.resolver);
  auto dependency = ResolvedDependency::takeOwnership(cFetch);

  resolver
    .extractDependencyListFetch(dependency)
    // TODO: Better error reporting
    .set_exception(std::make_exception_ptr(std::runtime_error("Dependency list fetch failed")));
}
<commit_msg>Add operator<< overloads for dependency graph types<commit_after>#include "Resolver.h"

#include "Requirement.h"

#include <cassert>
#include <exception>
#include <map>
#include <set>
#include <stdexcept>

using namespace Arbiter;
using namespace Resolver;

namespace {

struct DependencyNode final
{
  public:
    const ArbiterProjectIdentifier _project;
    const ArbiterSelectedVersion _proposedVersion;

    std::unique_ptr<ArbiterRequirement> _requirement;
    std::set<DependencyNode> _dependencies;

    DependencyNode (ArbiterProjectIdentifier project, ArbiterSelectedVersion proposedVersion, const ArbiterRequirement &requirement)
      : _project(std::move(project))
      , _proposedVersion(std::move(proposedVersion))
      , _requirement(requirement.clone())
    {
      assert(_requirement->satisfiedBy(_proposedVersion._semanticVersion));
    }

    bool operator== (const DependencyNode &other) const
    {
      return _project == other._project && _proposedVersion == other._proposedVersion;
    }

    bool operator< (const DependencyNode &other) const
    {
      if (_project != other._project) {
        // There's no well-defined ordering between nodes for different
        // projects, and we don't want them to appear equal within a set.
        return true;
      }

      // Sort such that higher versions are tried first.
      return _proposedVersion > other._proposedVersion;
    }
};

std::ostream &operator<< (std::ostream &os, const DependencyNode &node)
{
  return os
    << node._project << " @ " << node._proposedVersion
    << " (restricted to " << *node._requirement << ")";
}

class DependencyGraph final
{
  public:
    std::set<DependencyNode> _allNodes;
    std::map<DependencyNode, std::set<DependencyNode>> _edges;
    std::set<DependencyNode> _roots;

    bool operator== (const DependencyGraph &other) const
    {
      return _edges == other._edges && _roots == other._roots;
    }
};

std::ostream &operator<< (std::ostream &os, const DependencyGraph &graph)
{
  os << "Roots:";
  for (const DependencyNode &root : graph._roots) {
    os << "\n\t" << root;
  }

  os << "\n\nEdges";
  for (const auto &pair : graph._edges) {
    const DependencyNode &node = pair.first;
    os << "\n\t" << node._project << " ->";

    const auto &dependencies = pair.second;
    for (const DependencyNode &dep : dependencies) {
      os << "\n\t\t" << dep;
    }
  }

  return os;
}

} // namespace

ArbiterResolver *ArbiterCreateResolver (ArbiterResolverBehaviors behaviors, const ArbiterDependencyList *dependencyList, ArbiterUserValue context)
{
  return new ArbiterResolver(std::move(behaviors), *dependencyList, ArbiterResolver::Context(std::move(context)));
}

const void *ArbiterResolverContext (const ArbiterResolver *resolver)
{
  return resolver->_context.data();
}

bool ArbiterResolvedAllDependencies (const ArbiterResolver *resolver)
{
  return resolver->resolvedAll();
}

void ArbiterStartResolvingNextDependency (ArbiterResolver *resolver, ArbiterResolverCallbacks callbacks)
{
  resolver->resolveNext().add_callback([resolver, callbacks = std::move(callbacks)](const auto &result) {
    try {
      const ResolvedDependency &dependency = result.rightOrThrowLeft();
      callbacks.onSuccess(resolver, &dependency.projectIdentifier, &dependency.selectedVersion);
    } catch (const std::exception &ex) {
      callbacks.onError(resolver, ex.what());
    }
  });
}

void ArbiterFreeResolver (ArbiterResolver *resolver)
{
  delete resolver;
}

ResolvedDependency ResolvedDependency::takeOwnership (ArbiterDependencyListFetch fetch) noexcept
{
  std::unique_ptr<ArbiterProjectIdentifier> project(const_cast<ArbiterProjectIdentifier *>(fetch.project));
  std::unique_ptr<ArbiterSelectedVersion> selectedVersion(const_cast<ArbiterSelectedVersion *>(fetch.selectedVersion));

  return ResolvedDependency { std::move(*project), std::move(*selectedVersion) };
}

bool ResolvedDependency::operator== (const ResolvedDependency &other) const noexcept
{
  return projectIdentifier == other.projectIdentifier && selectedVersion == other.selectedVersion;
}

bool ArbiterResolver::resolvedAll () const noexcept
{
  return _remainingDependencies._dependencies.empty();
}

Arbiter::Future<ResolvedDependency> resolveNext ()
{
  Arbiter::Promise<ResolvedDependency> promise;

  // TODO: Actually resolve

  return promise.get_future();
}

Arbiter::Future<ArbiterDependencyList> ArbiterResolver::insertDependencyListFetch (ResolvedDependency dependency)
{
  std::lock_guard<std::mutex> guard(_fetchesMutex);

  return _dependencyListFetches[std::move(dependency)].get_future();
}

Arbiter::Promise<ArbiterDependencyList> ArbiterResolver::extractDependencyListFetch (const ResolvedDependency &dependency)
{
  std::lock_guard<std::mutex> guard(_fetchesMutex);

  Arbiter::Promise<ArbiterDependencyList> promise = std::move(_dependencyListFetches.at(dependency));
  _dependencyListFetches.erase(dependency);

  return promise;
}

Arbiter::Future<ArbiterDependencyList> ArbiterResolver::fetchDependencyList (ResolvedDependency dependency)
{
  // Eventually freed in the C callback function.
  auto project = std::make_unique<ArbiterProjectIdentifier>(dependency.projectIdentifier);
  auto version = std::make_unique<ArbiterSelectedVersion>(dependency.selectedVersion);

  auto future = insertDependencyListFetch(std::move(dependency));

  _behaviors.fetchDependencyList(
    ArbiterDependencyListFetch { this, project.release(), version.release() },
    &dependencyListFetchOnSuccess,
    &dependencyListFetchOnError
  );

  return future;
}

void ArbiterResolver::dependencyListFetchOnSuccess (ArbiterDependencyListFetch cFetch, const ArbiterDependencyList *fetchedList)
{
  auto &resolver = *const_cast<ArbiterResolver *>(cFetch.resolver);
  auto dependency = ResolvedDependency::takeOwnership(cFetch);

  resolver
    .extractDependencyListFetch(dependency)
    .set_value(*fetchedList);
}

void ArbiterResolver::dependencyListFetchOnError (ArbiterDependencyListFetch cFetch)
{
  auto &resolver = *const_cast<ArbiterResolver *>(cFetch.resolver);
  auto dependency = ResolvedDependency::takeOwnership(cFetch);

  resolver
    .extractDependencyListFetch(dependency)
    // TODO: Better error reporting
    .set_exception(std::make_exception_ptr(std::runtime_error("Dependency list fetch failed")));
}
<|endoftext|>


<commit_before>///
/// @file  RiemannR.cpp
/// @brief Logarithmic integral and Riemann R function.
///        Both the Logarithmic integral and the Riemann R function
///        are very accurate approximations of PrimePi(x). The inverse
///        Logarithmic integral and the inverse Riemann R function are
///        very accurate approximations of the nth prime.
///
///        Note that these implementations are only accurate up to
///        about 10^19 (if the long double type has 80 bits). We also
///        include implementations based on the non standard __float128
///        type and libquadmath that can be enabled using
///        'cmake -DWITH_FLOAT128=ON'. Currently __float128 support
///        is disabled by default because there are warnings during
///        compilation (using -Wpedantic) although the code
///        works perfectly fine.
///
/// Copyright (C) 2019 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount-internal.hpp>
#include <generate.hpp>
#include <int128_t.hpp>

#include <stdint.h>
#include <cmath>
#include <limits>

#if defined(HAVE_FLOAT128)
  #include <quadmath.h>
#endif

namespace {

using namespace std;
using namespace primecount;

/// Calculate the logarithmic integral using
/// Ramanujan's formula:
/// https://en.wikipedia.org/wiki/Logarithmic_integral_function#Series_representation
///
long double li(long double x)
{
  if (x <= 1)
    return 0;

  long double gamma = 0.577215664901532860606512090082402431L;
  long double sum = 0;
  long double inner_sum = 0;
  long double factorial = 1;
  long double p = -1;
  long double q = 0;
  long double power2 = 1;
  long double logx = log(x);
  int k = 0;

  for (int n = 1; true; n++)
  {
    p *= -logx;
    factorial *= n;
    q = factorial * power2;
    power2 *= 2;

    for (; k <= (n - 1) / 2; k++)
      inner_sum += 1.0L / (2 * k + 1);

    auto old_sum = sum;
    sum += (p / q) * inner_sum;

    // Not converging anymore
    if (abs(sum - old_sum) < numeric_limits<long double>::epsilon())
      break;
  }

  return gamma + log(logx) + sqrt(x) * sum;
}

/// Calculate the offset logarithmic integral which is a very
/// accurate approximation of the number of primes <= x.
/// Li(x) > pi(x) for 24 <= x <= ~ 10^316
///
long double Li(long double x)
{
  long double li2 = 1.045163780117492784844588889194613136L;

  if (x <= li2)
    return 0;
  else
    return li(x) - li2;
}

/// Calculate the inverse offset logarithmic integral which
/// is a very accurate approximation of the nth prime.
/// Li^-1(x) < nth_prime(x) for 7 <= x <= 10^316
///
/// This implementation computes Li^-1(x) as the zero of the
/// function f(z) = Li(z) - x using the Newton–Raphson method.
/// Note that Li'(z) = 1 / log(z).
/// https://math.stackexchange.com/a/853192
///
/// Newton–Raphson method:
/// zn+1 = zn - (f(zn) / f'(zn)).
/// zn+1 = zn - (Li(zn) - x) / (1 / log(zn))
/// zn+1 = zn - (Li(zn) - x) * log(zn)
///
long double Li_inverse(long double x)
{
  if (x < 2)
    return 0;

  long double t = x * log(x);
  long double old_term = numeric_limits<long double>::infinity();

  while (true)
  {
    long double term = (Li(t) - x) * log(t);

    // Not converging anymore
    if (abs(term) >= abs(old_term))
      break;

    t -= term;
    old_term = term;
  }

  return t;
}

/// Calculate the Riemann R function which is a very accurate
/// approximation of the number of primes below x.
/// RiemannR(x) = \sum_{n=1}^{∞} μ(n)/n * li(x^(1/n))
/// http://mathworld.wolfram.com/RiemannPrimeCountingFunction.html
///
long double Ri(long double x)
{
  if (x <= 1)
    return 0;

  auto terms = (int) (log2(x) + 10);
  auto mu = generate_moebius(terms);
  long double sum = 0;

  for (int n = 1; n < terms; n++)
  {
    if (mu[n])
    {
      long double root = pow(x, 1.0L / n);
      long double term = (li(root) * mu[n]) / n;
      long double old_sum = sum;
      sum += term;

      // Not converging anymore
      if (abs(sum - old_sum) < numeric_limits<long double>::epsilon())
        break;
    }
  }

  return sum;
}

/// Calculate the inverse Riemann R function which is a very
/// accurate approximation of the nth prime.
/// This implementation computes Ri^-1(x) as the zero of the
/// function f(z) = Ri(z) - x using the Newton–Raphson method.
/// Note that Ri'(z) = 1 / log(z).
/// https://math.stackexchange.com/a/853192
///
/// Newton–Raphson method:
/// zn+1 = zn - (f(zn) / f'(zn)).
/// zn+1 = zn - (Ri(zn) - x) / (1 / log(zn))
/// zn+1 = zn - (Ri(zn) - x) * log(zn)
///
long double Ri_inverse(long double x)
{
  if (x < 2)
    return 0;

  long double t = Li_inverse(x);
  long double old_term = numeric_limits<long double>::infinity();

  while (true)
  {
    long double term = (Ri(t) - x) * log(t);

    // Not converging anymore
    if (abs(term) >= abs(old_term))
      break;

    t -= term;
    old_term = term;
  }

  return t;
}

#if defined(HAVE_FLOAT128)

/// Calculate the logarithmic integral using
/// Ramanujan's formula:
/// https://en.wikipedia.org/wiki/Logarithmic_integral_function#Series_representation
///
__float128 li(__float128 x)
{
  if (x <= 1)
    return 0;

  __float128 gamma = 0.577215664901532860606512090082402431Q;
  __float128 sum = 0;
  __float128 inner_sum = 0;
  __float128 factorial = 1;
  __float128 p = -1;
  __float128 q = 0;
  __float128 power2 = 1;
  __float128 logx = logq(x);
  int k = 0;

  for (int n = 1; true; n++)
  {
    p *= -logx;
    factorial *= n;
    q = factorial * power2;
    power2 *= 2;

    for (; k <= (n - 1) / 2; k++)
      inner_sum += 1.0Q / (2 * k + 1);

    auto old_sum = sum;
    sum += (p / q) * inner_sum;

    // Not converging anymore
    if (fabsq(sum - old_sum) < FLT128_EPSILON)
      break;
  }

  return gamma + logq(logx) + sqrtq(x) * sum;
}

/// Calculate the offset logarithmic integral which is a very
/// accurate approximation of the number of primes <= x.
/// Li(x) > pi(x) for 24 <= x <= ~ 10^316
///
__float128 Li(__float128 x)
{
  __float128 li2 = 1.045163780117492784844588889194613136Q;

  if (x <= li2)
    return 0;
  else
    return li(x) - li2;
}

/// Calculate the inverse offset logarithmic integral which
/// is a very accurate approximation of the nth prime.
/// Li^-1(x) < nth_prime(x) for 7 <= x <= 10^316
///
/// This implementation computes Li^-1(x) as the zero of the
/// function f(z) = Li(z) - x using the Newton–Raphson method.
/// Note that Li'(z) = 1 / log(z).
/// https://math.stackexchange.com/a/853192
///
/// Newton–Raphson method:
/// zn+1 = zn - (f(zn) / f'(zn)).
/// zn+1 = zn - (Li(zn) - x) / (1 / log(zn))
/// zn+1 = zn - (Li(zn) - x) * log(zn)
///
__float128 Li_inverse(__float128 x)
{
  if (x < 2)
    return 0;

  __float128 t = x * logq(x);
  __float128 old_term = FLT128_MAX;

  while (true)
  {
    __float128 term = (Li(t) - x) * logq(t);

    // Not converging anymore
    if (fabsq(term) >= fabsq(old_term))
      break;

    t -= term;
    old_term = term;
  }

  return t;
}

/// Calculate the Riemann R function which is a very accurate
/// approximation of the number of primes below x.
/// RiemannR(x) = \sum_{n=1}^{∞} μ(n)/n * li(x^(1/n))
/// http://mathworld.wolfram.com/RiemannPrimeCountingFunction.html
///
__float128 Ri(__float128 x)
{
  if (x <= 1)
    return 0;

  auto terms = (int) (log2q(x) + 10);
  auto mu = generate_moebius(terms);
  __float128 sum = 0;

  for (int n = 1; n < terms; n++)
  {
    if (mu[n])
    {
      __float128 root = powq(x, 1.0Q / n);
      __float128 term = (li(root) * mu[n]) / n;
      __float128 old_sum = sum;
      sum += term;

      // Not converging anymore
      if (fabsq(sum - old_sum) < FLT128_EPSILON)
        break;
    }
  }

  return sum;
}

/// Calculate the inverse Riemann R function which is a very
/// accurate approximation of the nth prime.
/// This implementation computes Ri^-1(x) as the zero of the
/// function f(z) = Ri(z) - x using the Newton–Raphson method.
/// Note that Ri'(z) = 1 / log(z).
/// https://math.stackexchange.com/a/853192
///
/// Newton–Raphson method:
/// zn+1 = zn - (f(zn) / f'(zn)).
/// zn+1 = zn - (Ri(zn) - x) / (1 / log(zn))
/// zn+1 = zn - (Ri(zn) - x) * log(zn)
///
__float128 Ri_inverse(__float128 x)
{
  if (x < 2)
    return 0;

  __float128 t = Li_inverse(x);
  __float128 old_term = FLT128_MAX;

  while (true)
  {
    __float128 term = (Ri(t) - x) * logq(t);

    // Not converging anymore
    if (fabsq(term) >= fabsq(old_term))
      break;

    t -= term;
    old_term = term;
  }

  return t;
}

#endif

} // namespace

namespace primecount {

int64_t Li(int64_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int64_t) ::Li((__float128) x);
#endif

  return (int64_t) ::Li((long double) x);
}

int64_t Li_inverse(int64_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int64_t) ::Li_inverse((__float128) x);
#endif

  return (int64_t) ::Li_inverse((long double) x);
}

int64_t Ri(int64_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int64_t) ::Ri((__float128) x);
#endif

  return (int64_t) ::Ri((long double) x);
}

int64_t Ri_inverse(int64_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int64_t) ::Ri_inverse((__float128) x);
#endif

  return (int64_t) ::Ri_inverse((long double) x);
}

#ifdef HAVE_INT128_T

int128_t Li(int128_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int128_t) ::Li((__float128) x);
#endif

  return (int128_t) ::Li((long double) x);
}

int128_t Li_inverse(int128_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int128_t) ::Li_inverse((__float128) x);
#endif

  return (int128_t) ::Li_inverse((long double) x);
}

int128_t Ri(int128_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int128_t) ::Ri((__float128) x);
#endif

  return (int128_t) ::Ri((long double) x);
}

int128_t Ri_inverse(int128_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int128_t) ::Ri_inverse((__float128) x);
#endif

  return (int128_t) ::Ri_inverse((long double) x);
}

#endif

} // namespace
<commit_msg>Improve RiemannR accuracy<commit_after>///
/// @file  RiemannR.cpp
/// @brief Logarithmic integral and Riemann R function.
///        Both the Logarithmic integral and the Riemann R function
///        are very accurate approximations of PrimePi(x). The inverse
///        Logarithmic integral and the inverse Riemann R function are
///        very accurate approximations of the nth prime.
///
///        Note that these implementations are only accurate up to
///        about 10^19 (if the long double type has 80 bits). We also
///        include implementations based on the non standard __float128
///        type and libquadmath that can be enabled using
///        'cmake -DWITH_FLOAT128=ON'. Currently __float128 support
///        is disabled by default because there are warnings during
///        compilation (using -Wpedantic) although the code
///        works perfectly fine.
///
/// Copyright (C) 2019 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount-internal.hpp>
#include <generate.hpp>
#include <int128_t.hpp>

#include <stdint.h>
#include <cmath>
#include <limits>

#if defined(HAVE_FLOAT128)
  #include <quadmath.h>
#endif

namespace {

using namespace std;
using namespace primecount;

/// Calculate the logarithmic integral using
/// Ramanujan's formula:
/// https://en.wikipedia.org/wiki/Logarithmic_integral_function#Series_representation
///
long double li(long double x)
{
  if (x <= 1)
    return 0;

  long double gamma = 0.577215664901532860606512090082402431L;
  long double sum = 0;
  long double inner_sum = 0;
  long double factorial = 1;
  long double p = -1;
  long double q = 0;
  long double power2 = 1;
  long double logx = log(x);
  int k = 0;

  for (int n = 1; true; n++)
  {
    p *= -logx;
    factorial *= n;
    q = factorial * power2;
    power2 *= 2;

    for (; k <= (n - 1) / 2; k++)
      inner_sum += 1.0L / (2 * k + 1);

    auto old_sum = sum;
    sum += (p / q) * inner_sum;

    // Not converging anymore
    if (abs(sum - old_sum) < numeric_limits<long double>::epsilon())
      break;
  }

  return gamma + log(logx) + sqrt(x) * sum;
}

/// Calculate the offset logarithmic integral which is a very
/// accurate approximation of the number of primes <= x.
/// Li(x) > pi(x) for 24 <= x <= ~ 10^316
///
long double Li(long double x)
{
  long double li2 = 1.045163780117492784844588889194613136L;

  if (x <= li2)
    return 0;
  else
    return li(x) - li2;
}

/// Calculate the inverse offset logarithmic integral which
/// is a very accurate approximation of the nth prime.
/// Li^-1(x) < nth_prime(x) for 7 <= x <= 10^316
///
/// This implementation computes Li^-1(x) as the zero of the
/// function f(z) = Li(z) - x using the Newton–Raphson method.
/// Note that Li'(z) = 1 / log(z).
/// https://math.stackexchange.com/a/853192
///
/// Newton–Raphson method:
/// zn+1 = zn - (f(zn) / f'(zn)).
/// zn+1 = zn - (Li(zn) - x) / (1 / log(zn))
/// zn+1 = zn - (Li(zn) - x) * log(zn)
///
long double Li_inverse(long double x)
{
  if (x < 2)
    return 0;

  long double t = x * log(x);
  long double old_term = numeric_limits<long double>::infinity();

  while (true)
  {
    long double term = (Li(t) - x) * log(t);

    // Not converging anymore
    if (abs(term) >= abs(old_term))
      break;

    t -= term;
    old_term = term;
  }

  return t;
}

/// Calculate the Riemann R function which is a very accurate
/// approximation of the number of primes below x.
/// RiemannR(x) = \sum_{n=1}^{∞} μ(n)/n * li(x^(1/n))
/// http://mathworld.wolfram.com/RiemannPrimeCountingFunction.html
///
long double Ri(long double x)
{
  if (x <= 1)
    return 0;

  long double sum = 0;
  long double old_term = numeric_limits<long double>::infinity();
  auto terms = (int) (log2(x) * 2 + 10);
  auto mu = generate_moebius(terms);

  for (int n = 1; n < terms; n++)
  {
    if (mu[n])
    {
      long double root = pow(x, 1.0L / n);
      long double term = (li(root) * mu[n]) / n;

      // Not converging anymore
      if (abs(term) >= abs(old_term))
        break;

      sum += term;
      old_term = term;
    }
  }

  return sum;
}

/// Calculate the inverse Riemann R function which is a very
/// accurate approximation of the nth prime.
/// This implementation computes Ri^-1(x) as the zero of the
/// function f(z) = Ri(z) - x using the Newton–Raphson method.
/// Note that Ri'(z) = 1 / log(z).
/// https://math.stackexchange.com/a/853192
///
/// Newton–Raphson method:
/// zn+1 = zn - (f(zn) / f'(zn)).
/// zn+1 = zn - (Ri(zn) - x) / (1 / log(zn))
/// zn+1 = zn - (Ri(zn) - x) * log(zn)
///
long double Ri_inverse(long double x)
{
  if (x < 2)
    return 0;

  long double t = Li_inverse(x);
  long double old_term = numeric_limits<long double>::infinity();

  while (true)
  {
    long double term = (Ri(t) - x) * log(t);

    // Not converging anymore
    if (abs(term) >= abs(old_term))
      break;

    t -= term;
    old_term = term;
  }

  return t;
}

#if defined(HAVE_FLOAT128)

/// Calculate the logarithmic integral using
/// Ramanujan's formula:
/// https://en.wikipedia.org/wiki/Logarithmic_integral_function#Series_representation
///
__float128 li(__float128 x)
{
  if (x <= 1)
    return 0;

  __float128 gamma = 0.577215664901532860606512090082402431Q;
  __float128 sum = 0;
  __float128 inner_sum = 0;
  __float128 factorial = 1;
  __float128 p = -1;
  __float128 q = 0;
  __float128 power2 = 1;
  __float128 logx = logq(x);
  int k = 0;

  for (int n = 1; true; n++)
  {
    p *= -logx;
    factorial *= n;
    q = factorial * power2;
    power2 *= 2;

    for (; k <= (n - 1) / 2; k++)
      inner_sum += 1.0Q / (2 * k + 1);

    auto old_sum = sum;
    sum += (p / q) * inner_sum;

    // Not converging anymore
    if (fabsq(sum - old_sum) < FLT128_EPSILON)
      break;
  }

  return gamma + logq(logx) + sqrtq(x) * sum;
}

/// Calculate the offset logarithmic integral which is a very
/// accurate approximation of the number of primes <= x.
/// Li(x) > pi(x) for 24 <= x <= ~ 10^316
///
__float128 Li(__float128 x)
{
  __float128 li2 = 1.045163780117492784844588889194613136Q;

  if (x <= li2)
    return 0;
  else
    return li(x) - li2;
}

/// Calculate the inverse offset logarithmic integral which
/// is a very accurate approximation of the nth prime.
/// Li^-1(x) < nth_prime(x) for 7 <= x <= 10^316
///
/// This implementation computes Li^-1(x) as the zero of the
/// function f(z) = Li(z) - x using the Newton–Raphson method.
/// Note that Li'(z) = 1 / log(z).
/// https://math.stackexchange.com/a/853192
///
/// Newton–Raphson method:
/// zn+1 = zn - (f(zn) / f'(zn)).
/// zn+1 = zn - (Li(zn) - x) / (1 / log(zn))
/// zn+1 = zn - (Li(zn) - x) * log(zn)
///
__float128 Li_inverse(__float128 x)
{
  if (x < 2)
    return 0;

  __float128 t = x * logq(x);
  __float128 old_term = FLT128_MAX;

  while (true)
  {
    __float128 term = (Li(t) - x) * logq(t);

    // Not converging anymore
    if (fabsq(term) >= fabsq(old_term))
      break;

    t -= term;
    old_term = term;
  }

  return t;
}

/// Calculate the Riemann R function which is a very accurate
/// approximation of the number of primes below x.
/// RiemannR(x) = \sum_{n=1}^{∞} μ(n)/n * li(x^(1/n))
/// http://mathworld.wolfram.com/RiemannPrimeCountingFunction.html
///
__float128 Ri(__float128 x)
{
  if (x <= 1)
    return 0;

  __float128 sum = 0;
  __float128 old_term = FLT128_MAX;
  auto terms = (int) (log2q(x) * 2 + 10);
  auto mu = generate_moebius(terms);

  for (int n = 1; n < terms; n++)
  {
    if (mu[n])
    {
      __float128 root = powq(x, 1.0Q / n);
      __float128 term = (li(root) * mu[n]) / n;

      // Not converging anymore
      if (fabsq(term) >= fabsq(old_term))
        break;

      sum += term;
      old_term = term;
    }
  }

  return sum;
}

/// Calculate the inverse Riemann R function which is a very
/// accurate approximation of the nth prime.
/// This implementation computes Ri^-1(x) as the zero of the
/// function f(z) = Ri(z) - x using the Newton–Raphson method.
/// Note that Ri'(z) = 1 / log(z).
/// https://math.stackexchange.com/a/853192
///
/// Newton–Raphson method:
/// zn+1 = zn - (f(zn) / f'(zn)).
/// zn+1 = zn - (Ri(zn) - x) / (1 / log(zn))
/// zn+1 = zn - (Ri(zn) - x) * log(zn)
///
__float128 Ri_inverse(__float128 x)
{
  if (x < 2)
    return 0;

  __float128 t = Li_inverse(x);
  __float128 old_term = FLT128_MAX;

  while (true)
  {
    __float128 term = (Ri(t) - x) * logq(t);

    // Not converging anymore
    if (fabsq(term) >= fabsq(old_term))
      break;

    t -= term;
    old_term = term;
  }

  return t;
}

#endif

} // namespace

namespace primecount {

int64_t Li(int64_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int64_t) ::Li((__float128) x);
#endif

  return (int64_t) ::Li((long double) x);
}

int64_t Li_inverse(int64_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int64_t) ::Li_inverse((__float128) x);
#endif

  return (int64_t) ::Li_inverse((long double) x);
}

int64_t Ri(int64_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int64_t) ::Ri((__float128) x);
#endif

  return (int64_t) ::Ri((long double) x);
}

int64_t Ri_inverse(int64_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int64_t) ::Ri_inverse((__float128) x);
#endif

  return (int64_t) ::Ri_inverse((long double) x);
}

#ifdef HAVE_INT128_T

int128_t Li(int128_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int128_t) ::Li((__float128) x);
#endif

  return (int128_t) ::Li((long double) x);
}

int128_t Li_inverse(int128_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int128_t) ::Li_inverse((__float128) x);
#endif

  return (int128_t) ::Li_inverse((long double) x);
}

int128_t Ri(int128_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int128_t) ::Ri((__float128) x);
#endif

  return (int128_t) ::Ri((long double) x);
}

int128_t Ri_inverse(int128_t x)
{
#if defined(HAVE_FLOAT128)
  if (x > 1e14)
    return (int128_t) ::Ri_inverse((__float128) x);
#endif

  return (int128_t) ::Ri_inverse((long double) x);
}

#endif

} // namespace
<|endoftext|>