<commit_before>/*
libmimeapps, an implementation of
http://standards.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html

Copyright (c) 2015, Piotr Wójcik
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "Tools.h"

#include <dirent.h>
#include <sys/stat.h>

#include <algorithm>
#include <cstring>
#include <map>
#include <sstream>

namespace LibMimeApps
{

bool startsWith(const std::string &str, const std::string &prefix)
{
	if (str.size() < prefix.size())
	{
		return false;
	}

	return std::equal(prefix.begin(), prefix.end(), str.begin());
}

bool endsWith(std::string const &str, std::string const &suffix)
{
	if (str.size() < suffix.size())
	{
		return false;
	}

	return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
}

std::vector<std::string> split(const std::string &str, char delim)
{
	std::vector<std::string> chunks;
	std::stringstream stream(str);
	std::string item;

	while (std::getline(stream, item, delim))
	{
		chunks.push_back(item);
	}

	return chunks;
}

bool match(std::string const& text, std::string const& pattern)
{
	return std::search(text.begin(), text.end(), pattern.begin(), pattern.end()) != text.end();
}

std::vector<file> directoryEntries(const std::string &directory)
{
	std::vector<file> result;
	DIR *stream = opendir(directory.c_str());

	if (stream == NULL)
	{
		return result;
	}

	struct dirent *entry;
	struct stat info;
	std::string name;
	std::string path;

	while ((entry = readdir(stream)) != NULL)
	{
		name = entry->d_name;
		path = directory + name;

		stat(path.c_str(), &info);

		if (name.size() > 0 && name.at(0) != '.')
		{
			if (S_ISREG(info.st_mode))
			{
				result.push_back(file(name, FileType::File));
			}
			else if (S_ISDIR(info.st_mode))
			{
				result.push_back(file(name, FileType::Directory));
			}
		}
	}

	closedir(stream);

	return result;
}

std::vector<std::string> unfoldVariable(const std::string &string)
{
	std::vector<std::string> result;

	if (!match(string, "$"))
	{
		result.push_back(string);

		return result;
	}

	int begin = 0;

	while (string.at(begin) != '$')
	{
		++begin;
	}

	int end = begin+1;

	while (std::isalnum(string.at(end)) || string.at(end) == '_')
	{
		++end;
	}

	std::string name = string.substr(begin+1, end-(begin+1));

	std::vector<std::string> values = getVariableValues(name);

	for (std::vector<std::string>::iterator value = values.begin(); value != values.end(); ++value)
	{
		result.push_back(string.substr(0, begin) + (*value) + string.substr(end));
	}

	return result;
}

std::vector<std::string> getVariableValues(const std::string &name)
{
	std::string value;
	char *env = std::getenv(name.c_str());

	if (env && std::strlen(env) > 0)
	{
		value = std::string(env);
	}
	else
	{
		std::map<std::string, std::string> defaultVariableValues;
		defaultVariableValues["XDG_DATA_HOME"] = std::string("$HOME/.local/share");
		defaultVariableValues["XDG_CONFIG_HOME"] = std::string("$HOME/.config");
		defaultVariableValues["XDG_DATA_DIRS"] = std::string("/usr/local/share/:/usr/share/");
		defaultVariableValues["XDG_CONFIG_DIRS"] = std::string("/etc/xdg");

		if (defaultVariableValues.find(name) != defaultVariableValues.end())
		{
			value = defaultVariableValues.at(name);
		}
	}

	return split(value, ':');
}

std::string getLocaleValue(const ConfigReader &config, const std::string &group, const std::string &key, const std::string &language)
{
	lang wanted(language);
	std::vector<std::string> localeKeys;

	if (wanted.country.size() > 0 && wanted.modifier.size() > 0)
	{
		localeKeys.push_back(wanted.language + "_" + wanted.country + "@" + wanted.modifier);
	}

	if (wanted.country.size() > 0)
	{
		localeKeys.push_back(wanted.language + "_" + wanted.country);
	}

	if (wanted.modifier.size() > 0)
	{
		localeKeys.push_back(wanted.language + "@" + wanted.modifier);
	}

	localeKeys.push_back(wanted.language);

	for (std::vector<std::string>::size_type i = 0; i < localeKeys.size(); ++i)
	{
		std::string localeKey = key + "[" + localeKeys[i] + "]";

		if (config.hasKey(group, localeKey))
		{
			return config.value(group, localeKey);
		}
	}

	return config.value(group, key);
}

std::string alnums(const std::string &string, size_t begin)
{
	if (begin == std::string::npos || begin >= string.size())
	{
		return std::string();
	}

	size_t end = begin;

	while (end < string.size() && std::isalnum(string.at(end)))
	{
		++end;
	}

	return string.substr(begin, end-begin);
}

lang::lang(const std::string &string):
	language(alnums(string, 0))
{
	if (match(string, "_"))
	{
		country = alnums(string, string.find('_')+1);
	}

	if (match(string, "@"))
	{
		modifier = alnums(string, string.find('@')+1);
	}
}

}
<commit_msg>Process string more carefully, spotted by textbrowser<commit_after>/*
libmimeapps, an implementation of
http://standards.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html

Copyright (c) 2015, Piotr Wójcik
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "Tools.h"

#include <dirent.h>
#include <sys/stat.h>

#include <algorithm>
#include <cstring>
#include <map>
#include <sstream>

namespace LibMimeApps
{

bool startsWith(const std::string &str, const std::string &prefix)
{
	if (str.size() < prefix.size())
	{
		return false;
	}

	return std::equal(prefix.begin(), prefix.end(), str.begin());
}

bool endsWith(std::string const &str, std::string const &suffix)
{
	if (str.size() < suffix.size())
	{
		return false;
	}

	return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
}

std::vector<std::string> split(const std::string &str, char delim)
{
	std::vector<std::string> chunks;
	std::stringstream stream(str);
	std::string item;

	while (std::getline(stream, item, delim))
	{
		chunks.push_back(item);
	}

	return chunks;
}

bool match(std::string const& text, std::string const& pattern)
{
	return std::search(text.begin(), text.end(), pattern.begin(), pattern.end()) != text.end();
}

std::vector<file> directoryEntries(const std::string &directory)
{
	std::vector<file> result;
	DIR *stream = opendir(directory.c_str());

	if (stream == NULL)
	{
		return result;
	}

	struct dirent *entry;
	struct stat info;
	std::string name;
	std::string path;

	while ((entry = readdir(stream)) != NULL)
	{
		name = entry->d_name;
		path = directory + name;

		stat(path.c_str(), &info);

		if (name.size() > 0 && name.at(0) != '.')
		{
			if (S_ISREG(info.st_mode))
			{
				result.push_back(file(name, FileType::File));
			}
			else if (S_ISDIR(info.st_mode))
			{
				result.push_back(file(name, FileType::Directory));
			}
		}
	}

	closedir(stream);

	return result;
}

std::vector<std::string> unfoldVariable(const std::string &string)
{
	std::vector<std::string> result;
	size_t begin = string.find('$');

	if (begin == std::string::npos)
	{
		result.push_back(string);

		return result;
	}

	size_t end = begin+1;

	while (end < string.size() && (std::isalnum(string.at(end)) || string.at(end) == '_'))
	{
		++end;
	}

	std::string name = string.substr(begin+1, end-(begin+1));

	std::vector<std::string> values = getVariableValues(name);

	for (std::vector<std::string>::iterator value = values.begin(); value != values.end(); ++value)
	{
		result.push_back(string.substr(0, begin) + (*value) + string.substr(end));
	}

	return result;
}

std::vector<std::string> getVariableValues(const std::string &name)
{
	std::string value;
	char *env = std::getenv(name.c_str());

	if (env && std::strlen(env) > 0)
	{
		value = std::string(env);
	}
	else
	{
		std::map<std::string, std::string> defaultVariableValues;
		defaultVariableValues["XDG_DATA_HOME"] = std::string("$HOME/.local/share");
		defaultVariableValues["XDG_CONFIG_HOME"] = std::string("$HOME/.config");
		defaultVariableValues["XDG_DATA_DIRS"] = std::string("/usr/local/share/:/usr/share/");
		defaultVariableValues["XDG_CONFIG_DIRS"] = std::string("/etc/xdg");

		if (defaultVariableValues.find(name) != defaultVariableValues.end())
		{
			value = defaultVariableValues.at(name);
		}
	}

	return split(value, ':');
}

std::string getLocaleValue(const ConfigReader &config, const std::string &group, const std::string &key, const std::string &language)
{
	lang wanted(language);
	std::vector<std::string> localeKeys;

	if (wanted.country.size() > 0 && wanted.modifier.size() > 0)
	{
		localeKeys.push_back(wanted.language + "_" + wanted.country + "@" + wanted.modifier);
	}

	if (wanted.country.size() > 0)
	{
		localeKeys.push_back(wanted.language + "_" + wanted.country);
	}

	if (wanted.modifier.size() > 0)
	{
		localeKeys.push_back(wanted.language + "@" + wanted.modifier);
	}

	localeKeys.push_back(wanted.language);

	for (std::vector<std::string>::size_type i = 0; i < localeKeys.size(); ++i)
	{
		std::string localeKey = key + "[" + localeKeys[i] + "]";

		if (config.hasKey(group, localeKey))
		{
			return config.value(group, localeKey);
		}
	}

	return config.value(group, key);
}

std::string alnums(const std::string &string, size_t begin)
{
	if (begin == std::string::npos || begin >= string.size())
	{
		return std::string();
	}

	size_t end = begin;

	while (end < string.size() && std::isalnum(string.at(end)))
	{
		++end;
	}

	return string.substr(begin, end-begin);
}

lang::lang(const std::string &string):
	language(alnums(string, 0))
{
	if (match(string, "_"))
	{
		country = alnums(string, string.find('_')+1);
	}

	if (match(string, "@"))
	{
		modifier = alnums(string, string.find('@')+1);
	}
}

}
<|endoftext|>


<commit_before>#include "logger.hpp"
#include <iostream>

void CottonTTYLogger::error(int code, const std::string& error) {
    std::cerr << error_color << "Error " << code;
    std::cerr << reset_color << ": " << error << std::endl;
}
void CottonTTYLogger::warning(int code, const std::string& warning) {
    std::cerr << warning_color << "Error " << code;
    std::cerr << reset_color << ": " << warning << std::endl;
}
void CottonTTYLogger::result(bool res) {
    std::cout << (res?"true":"false") << std::endl;
}
void CottonTTYLogger::result(size_t res) {
    std::cout << res << std::endl;
}
void CottonTTYLogger::result(const std::string& res) {
    std::cout << res << std::endl;
}
void CottonTTYLogger::result(const std::vector<std::pair<std::string, std::string>>& res) {
    for (unsigned i=0; i<res.size(); i++)
        std::cout << res[i].first << ": " << res[i].second << std::endl;
}
void CottonTTYLogger::result(const std::vector<std::tuple<std::string, int, std::vector<std::string>>>& res) {
    for (unsigned i=0; i<res.size(); i++) {
        std::cout << boxname_color << std::get<0>(res[i]) << reset_color << std::endl;
        std::cout << "penality: " << std::get<1>(res[i]) << std::endl;
        std::cout << "features: ";
        for (auto feature: std::get<2>(res[i]))
            std::cout << feature << " ";
        std::cout << std::endl;
    }
}

void CottonJSONLogger::error(int code, const std::string& error) {
    errors.emplace_back(code, error);
}
void CottonJSONLogger::warning(int code, const std::string& warning) {
    warnings.emplace_back(code, warning);
}
void CottonJSONLogger::result(bool res) {
    result_ = to_json(res);
}
void CottonJSONLogger::result(size_t res) {
    result_ = to_json(res);
}
void CottonJSONLogger::result(const std::string& res) {
    result_ = to_json(res);
}
void CottonJSONLogger::result(const std::vector<std::pair<std::string, std::string>>& res) {
    result_ = to_json_obj(res);
}
void CottonJSONLogger::result(const std::vector<std::tuple<std::string, int, std::vector<std::string>>>& res) {
    result_ = to_json_arr(res, [](const std::tuple<std::string, int, std::vector<std::string>>& v) {
        return to_json_obj(
            "name", std::get<0>(v),
            "penality", std::get<1>(v),
            "features", std::get<2>(v)
        );
    });
}
void CottonJSONLogger::write() {
    auto ew_converter = [] (const std::pair<int, std::string>& msg) {
        return to_json_obj("code", msg.first, "message", msg.second);
    };
    std::cout << to_json_obj(
        "result", result_,
        "errors", to_json_arr(errors, ew_converter),
        "warnings", to_json_arr(warnings, ew_converter)
    ) << std::endl;
}
<commit_msg>Fix warning message in logger<commit_after>#include "logger.hpp"
#include <iostream>

void CottonTTYLogger::error(int code, const std::string& error) {
    std::cerr << error_color << "Error " << code;
    std::cerr << reset_color << ": " << error << std::endl;
}
void CottonTTYLogger::warning(int code, const std::string& warning) {
    std::cerr << warning_color << "Warning " << code;
    std::cerr << reset_color << ": " << warning << std::endl;
}
void CottonTTYLogger::result(bool res) {
    std::cout << (res?"true":"false") << std::endl;
}
void CottonTTYLogger::result(size_t res) {
    std::cout << res << std::endl;
}
void CottonTTYLogger::result(const std::string& res) {
    std::cout << res << std::endl;
}
void CottonTTYLogger::result(const std::vector<std::pair<std::string, std::string>>& res) {
    for (unsigned i=0; i<res.size(); i++)
        std::cout << res[i].first << ": " << res[i].second << std::endl;
}
void CottonTTYLogger::result(const std::vector<std::tuple<std::string, int, std::vector<std::string>>>& res) {
    for (unsigned i=0; i<res.size(); i++) {
        std::cout << boxname_color << std::get<0>(res[i]) << reset_color << std::endl;
        std::cout << "penality: " << std::get<1>(res[i]) << std::endl;
        std::cout << "features: ";
        for (auto feature: std::get<2>(res[i]))
            std::cout << feature << " ";
        std::cout << std::endl;
    }
}

void CottonJSONLogger::error(int code, const std::string& error) {
    errors.emplace_back(code, error);
}
void CottonJSONLogger::warning(int code, const std::string& warning) {
    warnings.emplace_back(code, warning);
}
void CottonJSONLogger::result(bool res) {
    result_ = to_json(res);
}
void CottonJSONLogger::result(size_t res) {
    result_ = to_json(res);
}
void CottonJSONLogger::result(const std::string& res) {
    result_ = to_json(res);
}
void CottonJSONLogger::result(const std::vector<std::pair<std::string, std::string>>& res) {
    result_ = to_json_obj(res);
}
void CottonJSONLogger::result(const std::vector<std::tuple<std::string, int, std::vector<std::string>>>& res) {
    result_ = to_json_arr(res, [](const std::tuple<std::string, int, std::vector<std::string>>& v) {
        return to_json_obj(
            "name", std::get<0>(v),
            "penality", std::get<1>(v),
            "features", std::get<2>(v)
        );
    });
}
void CottonJSONLogger::write() {
    auto ew_converter = [] (const std::pair<int, std::string>& msg) {
        return to_json_obj("code", msg.first, "message", msg.second);
    };
    std::cout << to_json_obj(
        "result", result_,
        "errors", to_json_arr(errors, ew_converter),
        "warnings", to_json_arr(warnings, ew_converter)
    ) << std::endl;
}
<|endoftext|>


<commit_before>/*
Copyright 2014, Jernej Kovacic

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * @file SampleStatGeneric.cpp
 *
 * Implementation of the class SampleStaGeneric that calculates sample's
 * mean, variance, standard deviation, sum, etc.
 *
 * As the class is templated, this file must not be compiled.
 * Instead it must be included after the class declaration in the .h file
 *
 * @author Jernej Kovacic
 */

// deliberately there is no #include "SampleStatGeneric.h" !
#include <cstddef>
#include <cmath>
#include <vector>

#include "omp_header.h"
#include "omp_settings.h"

#include "StatisticsException.h"
#include "NumericUtil.h"

/**
 * Constructor. Initializes all internal variables but does not
 * calculate anything yet.
 *
 * @param sample - a vector of samples
 *
 * @throw StatisticsException if 'sample' is an empty vector
 */
template <class T>
math::SampleStatGeneric<T>::SampleStatGeneric(const std::vector<T>& sample) throw(math::StatisticsException)
{
    this->m_processed = false;
    this->m_N = 0;
    this->m_sum = math::NumericUtil<T>::ZERO;
    this->m_mean = math::NumericUtil<T>::ZERO;
    this->m_sumSqDev = math::NumericUtil<T>::ZERO;
    this->m_pData = NULL;

    if ( 0 == sample.size() )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_EMPTY);
    }

    this->m_N = sample.size();
    this->m_pData = &sample;
}

/**
 * Calculates values of all necessary internal variables which become
 * available to be returned by getter methods.
 *
 * Nothing is done if process() has been called before on the same object.
 *
 * After this method is finished, the original vector of samples may be freely
 * modified as other methods do not need it anymore.
 */
template <class T>
void math::SampleStatGeneric<T>::process()
{
    // Check whether the sample has already been processed.
    if ( true == this->m_processed )
    {
        return;
    }

    /*
     * Coarse grained parallelism will be applied, i.e. each thread will be
     * assigned an (approximately) equally sized contiguous block of data
     * to be processed.
     */

    // Ideal number of threads
    // (if each one processes approx. OMP_CHUNKS_PER_THREAD items):
    const size_t ideal = this->m_N / OMP_CHUNKS_PER_THREAD +
                         ( 0 == this->m_N % OMP_CHUNKS_PER_THREAD ? 0 : 1 );

    /*
     * In the first step, each thread calculates the sum of its block
     */
    T tempSum = NumericUtil<T>::ZERO;
    #pragma omp parallel num_threads(ideal) \
                    if(this->m_N>OMP_CHUNKS_PER_THREAD) \
                    default(none) \
                    reduction(+ : tempSum)
    {
        // Depending on the number of available threads,
    	// determine the ideal nr.of samples per thread,
    	// and start and sample of a block that each thread will process.
        const size_t thrnr = omp_get_thread_num();
        const size_t nthreads = omp_get_num_threads();

        const size_t samples_per_thread = (this->m_N + nthreads -1) / nthreads;
        const size_t istart = samples_per_thread * thrnr;
        const size_t iend = istart + samples_per_thread;

        // Calculate the sum of the assigned block...
        T partsum = math::NumericUtil<T>::ZERO;
        for ( size_t i=istart; i<iend && i<this->m_N; ++i )
        {
            partsum += this->m_pData->at(i);
        }

        // ... and add it to the total sum in a thread safe manner.
        tempSum += partsum;
    }

    // When the sum is known, it is trivial to obtain the sample's mean:
    this->m_sum = tempSum;
    this->m_mean = this->m_sum / this->m_N;

    // Fork threads once more, this time calculate the sum of
    // squared deviations from the mean.
    // Apply exactly the same approach as above.
    tempSum = NumericUtil<T>::ZERO;
    #pragma omp parallel num_threads(ideal) \
                 if(this->m_N>OMP_CHUNKS_PER_THREAD) \
                 default(none) \
                 reduction(+ : tempSum)
    {
        const size_t thrnr = omp_get_thread_num();
        const size_t nthreads = omp_get_num_threads();

        const size_t samples_per_thread = (this->m_N + nthreads -1) / nthreads;
        const size_t istart = samples_per_thread * thrnr;
        const size_t iend = istart + samples_per_thread;

        T partsum = math::NumericUtil<T>::ZERO;
        for ( size_t i=istart; i<iend && i<this->m_N; ++i )
        {
            T diff = this->m_pData->at(i) - this->m_mean;
            partsum += diff * diff;
        }

        tempSum += partsum;

    }

    // The sum of squared deviations will be used by other functions to
    // calculate the sample's variance and standard deviation.
    this->m_sumSqDev = tempSum;

    // Flag the sample as processed
    this->m_processed = true;

    // In serial mode this variable is never used.
    (void) ideal;
}

/**
 * @return a logical value indicating whether the samples have already been processed
 */
template <class T>
bool math::SampleStatGeneric<T>::processed() const
{
    return this->m_processed;
}

/**
 * @return number of samples or 0 if process() has not been called yet
 */
template <class T>
size_t math::SampleStatGeneric<T>::sampleSize() const
{
    return this->m_N;
}

/**
 * @return sum of all sample values
 *
 * @throw StatisticsException if process() has not been called yet
 */
template <class T>
T math::SampleStatGeneric<T>::sum() const throw(math::StatisticsException)
{
    if ( false == this->m_processed )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_NOT_PROCESSED_YET);
    }

    return this->m_sum;
}

/**
 * Arithmetical mean (or average) of the sample.
 *
 * @return mean value of the sample
 *
 * @throw StatisticsException if process() has not been called yet
 */
template <class T>
T math::SampleStatGeneric<T>::mean() const throw(math::StatisticsException)
{
    /*
     * Arithmetical mean is calculated as:
     *
     *                   N
     *                 -----
     *             1   \
     * mean(X) = -----  >  X(i)
     *             N   /
     *                 -----
     *                  i=1
     *
     */

    if ( false == this->m_processed )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_NOT_PROCESSED_YET);
    }

    return this->m_mean;
}

/**
 * Variance of the sample.
 * The method allows the divisor (sample size) to be reduced by an arbitrary
 * positive integer number 'df_sub' as long as it is strictly smaller than
 * the sample size.
 *
 * @param df_sub - generalized Bessel's correction value (typically 1 or 0)
 *
 * @return variance of the sample, depending on the given 'df_sub'
 *
 * @throw StatisticsException if process() has not been called yet or if 'df_sub' exceeds sample's size
 */
template <class T>
T math::SampleStatGeneric<T>::var(size_t df_sub) const throw(math::StatisticsException)
{
    /*
     * Variance of the sample is calculated as:
     *
     *                              N
     *                            -----
     *                  1         \                 2
     *   var(X) = ------------     >   (X(i) - mean)
     *             N - df_sub     /
     *                            -----
     *                             i=1
     */

    if ( false == this->m_processed )
	{
        throw math::StatisticsException(math::StatisticsException::SAMPLE_NOT_PROCESSED_YET);
    }

    if ( df_sub >= this->m_N )
    {
        throw math::StatisticsException(math::StatisticsException::DF_SUBTRAHEND_TOO_LARGE);
    }

    return this->m_sumSqDev / static_cast<T>(this->m_N - df_sub);
}

/**
 * Variance of the sample.
 * Calculates either variance of a sample (sum of square deviations from
 * the mean is divided by N-1) or of a population (sum of squares divided by N).
 *
 * @param sample - if 'true', sum of squared deviations is divided by (N-1), otherwise by N
 *
 * @return variance of the sample depending on 'sample'
 *
 * @throw StatisticsException if process() has not been called yet or if the sample is too small
 */
template <class T>
T math::SampleStatGeneric<T>::var(bool sample) const throw(math::StatisticsException)
{
    /*
     * Variance of the sample, calculated as:
     *
     *                         N
     *                       -----
     *                1      \                 2
     *   var(X) = --------    >   (X(i) - mean)
     *             N - BC    /
     *                       -----
     *                        i=1
     *
     * where BC (Bessel's correction) equals 1 if 'sample' is 'true', otherwise it equals 0.
     */

    if ( false == this->m_processed )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_NOT_PROCESSED_YET);
    }

    if ( true==sample && 1==this->m_N )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_TOO_SMALL);
    }

    return this->var( static_cast<size_t>( (false==sample ? 0 : 1) ) );
}

/**
 * Standard deviation of the sample.
 * Calculates either standard deviation of a sample (sum of square deviations from
 * the mean is divided by N-1) or of a population (sum of squares divided by N).
 *
 * @param sample - if 'true', sum of squared deviations is divided by (N-1), otherwise by N
 *
 * @return standard deviation of the sample depending on 'sample'
 *
 * @throw StatisticsException if process() has not been called yet or if the sample is too small
 */
template <class T>
T math::SampleStatGeneric<T>::stdev(bool sample) const throw(math::StatisticsException)
{
    /*
     * Standard deviation is calculated as:
     *
     *                            ---------------------------------
     *                           /            N                   |
     *                          /           -----
     *              ---        /    1       \                 2
     *   stdev(X) =    \      /  --------    >   (X(i) - mean)
     *                  \    /    N - BC    /
     *                   \  /               -----
     *                    \/                 i=1
     *
     * where BC (Bessel's correction) equals 1 if 'sample' is 'true', otherwise it equals 0.
     */

    if ( true==sample && 1==this->m_N )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_TOO_SMALL);
    }

    return this->stdev( static_cast<size_t>( (false==sample ? 0 : 1) ) );
}

/**
 * Standard deviation of the sample.
 * The method allows the divisor (sample size) to be reduced by an arbitrary
 * positive integer number 'df_sub' as long as it is strictly smaller than
 * the sample size.
 *
 * @param df_sub - generalized Bessel's correction value (typically 1 or 0)
 *
 * @return standard deviation of the sample, depending on the given 'df_sub'
 *
 * @throw StatisticsException if process() has not been called yet or if 'df_sub' exceeds sample's size
 */
template <class T>
T math::SampleStatGeneric<T>::stdev(size_t df_sub) const throw(math::StatisticsException)
{
    /*
     * (Generalized) standard deviation is calculated as:
     *
     *                            -------------------------------------
     *                           /               N                    |
     *                          /               -----
     *              ---        /     1          \                 2
     *   stdev(X) =    \      / ------------     >   (X(i) - mean)
     *                  \    /   N - df_sub     /
     *                   \  /                   -----
     *                    \/                     i=1
     *
     */

    /*
     *  This operation is only supported for T=float, T=double or T=long double.
     *  Specialized implementation is provided below for these three types.
     *
     *  For any other type, the operation is (probably) not supported
     *  as sqrt may not be defined for the type. In such a case throw an
     *  exception immediately.
     */

    throw math::StatisticsException(math::StatisticsException::UNSUPPORTED_TYPE);

    // will never execute, but some compilers may produce a warning if nothing is returned
    return math::NumericUtil<T>::ONE;
}

/*
 * Specialization of stdev() for float, double and long double.
 * All three specializations are very similar and only differ in types of the
 * returned  value.
 * For easier maintainability, the specialization will be implemented
 * only once using a parameterized #define.
 */

#define _MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV(FD) \
template<> \
FD math::SampleStatGeneric<FD>::stdev(size_t df_sub) const throw (math::StatisticsException) \
{ \
    return std::sqrt( this->var(df_sub) ); \
}
// end of #define

// the actual specialization for float:
_MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV(float)

// for double:
_MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV(double)

// and for long double:
_MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV(long double)

// definition of _MATH_QUATERNIONGENERIC_SPECIALIZED_NORM not needed anymore, #undef it
#undef _MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV
<commit_msg>casted divisor in mean<commit_after>/*
Copyright 2014, Jernej Kovacic

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * @file SampleStatGeneric.cpp
 *
 * Implementation of the class SampleStaGeneric that calculates sample's
 * mean, variance, standard deviation, sum, etc.
 *
 * As the class is templated, this file must not be compiled.
 * Instead it must be included after the class declaration in the .h file
 *
 * @author Jernej Kovacic
 */

// deliberately there is no #include "SampleStatGeneric.h" !
#include <cstddef>
#include <cmath>
#include <vector>

#include "omp_header.h"
#include "omp_settings.h"

#include "StatisticsException.h"
#include "NumericUtil.h"

/**
 * Constructor. Initializes all internal variables but does not
 * calculate anything yet.
 *
 * @param sample - a vector of samples
 *
 * @throw StatisticsException if 'sample' is an empty vector
 */
template <class T>
math::SampleStatGeneric<T>::SampleStatGeneric(const std::vector<T>& sample) throw(math::StatisticsException)
{
    this->m_processed = false;
    this->m_N = 0;
    this->m_sum = math::NumericUtil<T>::ZERO;
    this->m_mean = math::NumericUtil<T>::ZERO;
    this->m_sumSqDev = math::NumericUtil<T>::ZERO;
    this->m_pData = NULL;

    if ( 0 == sample.size() )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_EMPTY);
    }

    this->m_N = sample.size();
    this->m_pData = &sample;
}

/**
 * Calculates values of all necessary internal variables which become
 * available to be returned by getter methods.
 *
 * Nothing is done if process() has been called before on the same object.
 *
 * After this method is finished, the original vector of samples may be freely
 * modified as other methods do not need it anymore.
 */
template <class T>
void math::SampleStatGeneric<T>::process()
{
    // Check whether the sample has already been processed.
    if ( true == this->m_processed )
    {
        return;
    }

    /*
     * Coarse grained parallelism will be applied, i.e. each thread will be
     * assigned an (approximately) equally sized contiguous block of data
     * to be processed.
     */

    // Ideal number of threads
    // (if each one processes approx. OMP_CHUNKS_PER_THREAD items):
    const size_t ideal = this->m_N / OMP_CHUNKS_PER_THREAD +
                         ( 0 == this->m_N % OMP_CHUNKS_PER_THREAD ? 0 : 1 );

    /*
     * In the first step, each thread calculates the sum of its block
     */
    T tempSum = NumericUtil<T>::ZERO;
    #pragma omp parallel num_threads(ideal) \
                    if(this->m_N>OMP_CHUNKS_PER_THREAD) \
                    default(none) \
                    reduction(+ : tempSum)
    {
        // Depending on the number of available threads,
    	// determine the ideal nr.of samples per thread,
    	// and start and sample of a block that each thread will process.
        const size_t thrnr = omp_get_thread_num();
        const size_t nthreads = omp_get_num_threads();

        const size_t samples_per_thread = (this->m_N + nthreads -1) / nthreads;
        const size_t istart = samples_per_thread * thrnr;
        const size_t iend = istart + samples_per_thread;

        // Calculate the sum of the assigned block...
        T partsum = math::NumericUtil<T>::ZERO;
        for ( size_t i=istart; i<iend && i<this->m_N; ++i )
        {
            partsum += this->m_pData->at(i);
        }

        // ... and add it to the total sum in a thread safe manner.
        tempSum += partsum;
    }

    // When the sum is known, it is trivial to obtain the sample's mean:
    this->m_sum = tempSum;
    this->m_mean = this->m_sum / static_cast<T>(this->m_N);

    // Fork threads once more, this time calculate the sum of
    // squared deviations from the mean.
    // Apply exactly the same approach as above.
    tempSum = NumericUtil<T>::ZERO;
    #pragma omp parallel num_threads(ideal) \
                 if(this->m_N>OMP_CHUNKS_PER_THREAD) \
                 default(none) \
                 reduction(+ : tempSum)
    {
        const size_t thrnr = omp_get_thread_num();
        const size_t nthreads = omp_get_num_threads();

        const size_t samples_per_thread = (this->m_N + nthreads -1) / nthreads;
        const size_t istart = samples_per_thread * thrnr;
        const size_t iend = istart + samples_per_thread;

        T partsum = math::NumericUtil<T>::ZERO;
        for ( size_t i=istart; i<iend && i<this->m_N; ++i )
        {
            T diff = this->m_pData->at(i) - this->m_mean;
            partsum += diff * diff;
        }

        tempSum += partsum;

    }

    // The sum of squared deviations will be used by other functions to
    // calculate the sample's variance and standard deviation.
    this->m_sumSqDev = tempSum;

    // Flag the sample as processed
    this->m_processed = true;

    // In serial mode this variable is never used.
    (void) ideal;
}

/**
 * @return a logical value indicating whether the samples have already been processed
 */
template <class T>
bool math::SampleStatGeneric<T>::processed() const
{
    return this->m_processed;
}

/**
 * @return number of samples or 0 if process() has not been called yet
 */
template <class T>
size_t math::SampleStatGeneric<T>::sampleSize() const
{
    return this->m_N;
}

/**
 * @return sum of all sample values
 *
 * @throw StatisticsException if process() has not been called yet
 */
template <class T>
T math::SampleStatGeneric<T>::sum() const throw(math::StatisticsException)
{
    if ( false == this->m_processed )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_NOT_PROCESSED_YET);
    }

    return this->m_sum;
}

/**
 * Arithmetical mean (or average) of the sample.
 *
 * @return mean value of the sample
 *
 * @throw StatisticsException if process() has not been called yet
 */
template <class T>
T math::SampleStatGeneric<T>::mean() const throw(math::StatisticsException)
{
    /*
     * Arithmetical mean is calculated as:
     *
     *                   N
     *                 -----
     *             1   \
     * mean(X) = -----  >  X(i)
     *             N   /
     *                 -----
     *                  i=1
     *
     */

    if ( false == this->m_processed )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_NOT_PROCESSED_YET);
    }

    return this->m_mean;
}

/**
 * Variance of the sample.
 * The method allows the divisor (sample size) to be reduced by an arbitrary
 * positive integer number 'df_sub' as long as it is strictly smaller than
 * the sample size.
 *
 * @param df_sub - generalized Bessel's correction value (typically 1 or 0)
 *
 * @return variance of the sample, depending on the given 'df_sub'
 *
 * @throw StatisticsException if process() has not been called yet or if 'df_sub' exceeds sample's size
 */
template <class T>
T math::SampleStatGeneric<T>::var(size_t df_sub) const throw(math::StatisticsException)
{
    /*
     * Variance of the sample is calculated as:
     *
     *                              N
     *                            -----
     *                  1         \                 2
     *   var(X) = ------------     >   (X(i) - mean)
     *             N - df_sub     /
     *                            -----
     *                             i=1
     */

    if ( false == this->m_processed )
	{
        throw math::StatisticsException(math::StatisticsException::SAMPLE_NOT_PROCESSED_YET);
    }

    if ( df_sub >= this->m_N )
    {
        throw math::StatisticsException(math::StatisticsException::DF_SUBTRAHEND_TOO_LARGE);
    }

    return this->m_sumSqDev / static_cast<T>(this->m_N - df_sub);
}

/**
 * Variance of the sample.
 * Calculates either variance of a sample (sum of square deviations from
 * the mean is divided by N-1) or of a population (sum of squares divided by N).
 *
 * @param sample - if 'true', sum of squared deviations is divided by (N-1), otherwise by N
 *
 * @return variance of the sample depending on 'sample'
 *
 * @throw StatisticsException if process() has not been called yet or if the sample is too small
 */
template <class T>
T math::SampleStatGeneric<T>::var(bool sample) const throw(math::StatisticsException)
{
    /*
     * Variance of the sample, calculated as:
     *
     *                         N
     *                       -----
     *                1      \                 2
     *   var(X) = --------    >   (X(i) - mean)
     *             N - BC    /
     *                       -----
     *                        i=1
     *
     * where BC (Bessel's correction) equals 1 if 'sample' is 'true', otherwise it equals 0.
     */

    if ( false == this->m_processed )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_NOT_PROCESSED_YET);
    }

    if ( true==sample && 1==this->m_N )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_TOO_SMALL);
    }

    return this->var( static_cast<size_t>( (false==sample ? 0 : 1) ) );
}

/**
 * Standard deviation of the sample.
 * Calculates either standard deviation of a sample (sum of square deviations from
 * the mean is divided by N-1) or of a population (sum of squares divided by N).
 *
 * @param sample - if 'true', sum of squared deviations is divided by (N-1), otherwise by N
 *
 * @return standard deviation of the sample depending on 'sample'
 *
 * @throw StatisticsException if process() has not been called yet or if the sample is too small
 */
template <class T>
T math::SampleStatGeneric<T>::stdev(bool sample) const throw(math::StatisticsException)
{
    /*
     * Standard deviation is calculated as:
     *
     *                            ---------------------------------
     *                           /            N                   |
     *                          /           -----
     *              ---        /    1       \                 2
     *   stdev(X) =    \      /  --------    >   (X(i) - mean)
     *                  \    /    N - BC    /
     *                   \  /               -----
     *                    \/                 i=1
     *
     * where BC (Bessel's correction) equals 1 if 'sample' is 'true', otherwise it equals 0.
     */

    if ( true==sample && 1==this->m_N )
    {
        throw math::StatisticsException(math::StatisticsException::SAMPLE_TOO_SMALL);
    }

    return this->stdev( static_cast<size_t>( (false==sample ? 0 : 1) ) );
}

/**
 * Standard deviation of the sample.
 * The method allows the divisor (sample size) to be reduced by an arbitrary
 * positive integer number 'df_sub' as long as it is strictly smaller than
 * the sample size.
 *
 * @param df_sub - generalized Bessel's correction value (typically 1 or 0)
 *
 * @return standard deviation of the sample, depending on the given 'df_sub'
 *
 * @throw StatisticsException if process() has not been called yet or if 'df_sub' exceeds sample's size
 */
template <class T>
T math::SampleStatGeneric<T>::stdev(size_t df_sub) const throw(math::StatisticsException)
{
    /*
     * (Generalized) standard deviation is calculated as:
     *
     *                            -------------------------------------
     *                           /               N                    |
     *                          /               -----
     *              ---        /     1          \                 2
     *   stdev(X) =    \      / ------------     >   (X(i) - mean)
     *                  \    /   N - df_sub     /
     *                   \  /                   -----
     *                    \/                     i=1
     *
     */

    /*
     *  This operation is only supported for T=float, T=double or T=long double.
     *  Specialized implementation is provided below for these three types.
     *
     *  For any other type, the operation is (probably) not supported
     *  as sqrt may not be defined for the type. In such a case throw an
     *  exception immediately.
     */

    throw math::StatisticsException(math::StatisticsException::UNSUPPORTED_TYPE);

    // will never execute, but some compilers may produce a warning if nothing is returned
    return math::NumericUtil<T>::ONE;
}

/*
 * Specialization of stdev() for float, double and long double.
 * All three specializations are very similar and only differ in types of the
 * returned  value.
 * For easier maintainability, the specialization will be implemented
 * only once using a parameterized #define.
 */

#define _MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV(FD) \
template<> \
FD math::SampleStatGeneric<FD>::stdev(size_t df_sub) const throw (math::StatisticsException) \
{ \
    return std::sqrt( this->var(df_sub) ); \
}
// end of #define

// the actual specialization for float:
_MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV(float)

// for double:
_MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV(double)

// and for long double:
_MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV(long double)

// definition of _MATH_QUATERNIONGENERIC_SPECIALIZED_NORM not needed anymore, #undef it
#undef _MATH_SAMPLESTATGENERIC_SPECIALIZED_STDEV
<|endoftext|>


<commit_before>#include "common.h"

#include <algorithm>

namespace remu {

/**
 * Initialises the memory module
 * @param emu      Reference to the emulator structure
 * @param mem_size Size of dram in bytes
 */
Memory::Memory(Emulator *emu, size_t mem_size)
  : emu(emu)
  , mem_size(mem_size)
  , data(new uint8_t[mem_size])
{
  std::fill(data, data + mem_size, 0);
}

/**
 * Clean up Memory
 */
Memory::~Memory()
{
  delete data;
}

/**
 * Prints out the non-zero bytes from memory
 */
void Memory::dump()
{
  size_t i = 0;
  printf("Non-zero memory:\n");

  for (i = 0; i < mem_size && i < 65535; i += 4)
  {
    uint32_t data = readDwordLe(i);
    if (data != 0)
    {
      printf("0x%08zx: 0x%08x\n", i, data);
    }
  }
}

/**
 * Frees the memory
 * @param memory Reference to the memory structure
 */
void
memory_destroy(Memory* m)
{
  if (!m)
  {
    return;
  }
}

/**
 * Reads a byte from memory
 * @param addr Memory location
 */
uint8_t Memory::readByte(uint32_t addr)
{
  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr < mem_size, 1))
  {
    return data[addr];
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
  return 0;
}

/**
 * Reads a word from memory (little endian)
 * @param memory Reference to the memory structure
 */
uint16_t Memory::readWordLe(uint32_t addr)
{
  uint32_t base;
  uint8_t off;

  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr + 1 < mem_size, 1))
  {
    base = addr & ~0x01;
    off = addr & 0x01;

    return (data[base + ((off + 0) & 0x01)] <<  0) |
           (data[base + ((off + 1) & 0x01)] <<  8);
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
  return 0;
}

/**
 * Reads a double word from memory (little endian)
 * @param address Memory location
 */
uint32_t Memory::readDwordLe(uint32_t addr)
{
  uint32_t base;
  uint8_t off;

  /* Apparently, SDRAM and IO peripherials are mapped to 4 different address
   * ranges by the VideoCore MMU. We can replicate that behaviour by ignoring
   * the two most significant bits of the address. We can do this thanks to
   * the fact that we ignore cacheing
   */
  addr = addr & 0x3FFFFFFF;

  /* SDRAM Read */
  if (__builtin_expect(addr + 3 < mem_size, 1))
  {
    base = addr & ~0x03;
    off = addr & 0x03;

    return (data[base + ((off + 0) & 0x03)] <<  0) |
           (data[base + ((off + 1) & 0x03)] <<  8) |
           (data[base + ((off + 2) & 0x03)] << 16) |
           (data[base + ((off + 3) & 0x03)] << 24);
  }

  /* System Timer */
  if (addr == 0x20003004)
  {
    uint64_t timer_value = emu->getSystemTimer();
    return (uint32_t)(timer_value & 0xffffffff);
  }
  else if (addr == 0x20003008)
  {
    uint64_t timer_value = emu->getSystemTimer();
    return (uint32_t)((timer_value >> 32) & 0xffffffff);
  }

  /* Grab relevant IoRegion and call it if registered */
  IoRegion *ioregion = iomap.getRegionForAddr(addr);
  if (ioregion) {
    return ioregion->readIo(addr - ioregion->base, sizeof(uint32_t));
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
  return 0;
}

/**
 * Writes a single byte to memory
 * @param addr  Memory location
 * @param value Data to be written
 */
void Memory::writeByte(uint32_t addr, uint8_t value)
{
  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr < mem_size, 1))
  {
    data[addr] = value;
    return;
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
}

/**
 * Writes a word to memory
 * @param addr Memory location
 * @param data Data to be written
 */
void Memory::writeWordLe(uint32_t addr, uint16_t value)
{
  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr + 1 < mem_size, 1))
  {
    data[addr + 0] = (value >> 0) & 0xFF;
    data[addr + 1] = (value >> 8) & 0xFF;
    return;
  }

  /* Grab relevant IoRegion and call it if registered */
  IoRegion *ioregion = iomap.getRegionForAddr(addr);
  if (ioregion) {
    ioregion->writeIo(addr, value, sizeof(uint16_t));
    return;
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
}

/**
 * Writes a double word to memory
 * @param addr  Memory location
 * @param value Data to be written
 */
void Memory::writeDwordLe(uint32_t addr, uint32_t value)
{
  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr + 3 < mem_size, 1))
  {
    data[addr + 0] = (value >>  0) & 0xFF;
    data[addr + 1] = (value >>  8) & 0xFF;
    data[addr + 2] = (value >> 16) & 0xFF;
    data[addr + 3] = (value >> 24) & 0xFF;
    return;
  }

  /* Grab relevant IoRegion and call it if registered */
  IoRegion *ioregion = iomap.getRegionForAddr(addr);
  if (ioregion) {
    ioregion->writeIo(addr - ioregion->base, value, sizeof(uint32_t));
    return;
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
}

} /*namespace remu*/

<commit_msg>Remove unused memory_destory<commit_after>#include "common.h"

#include <algorithm>

namespace remu {

/**
 * Initialises the memory module
 * @param emu      Reference to the emulator structure
 * @param mem_size Size of dram in bytes
 */
Memory::Memory(Emulator *emu, size_t mem_size)
  : emu(emu)
  , mem_size(mem_size)
  , data(new uint8_t[mem_size])
{
  std::fill(data, data + mem_size, 0);
}

/**
 * Clean up Memory
 */
Memory::~Memory()
{
  delete data;
}

/**
 * Prints out the non-zero bytes from memory
 */
void Memory::dump()
{
  size_t i = 0;
  printf("Non-zero memory:\n");

  for (i = 0; i < mem_size && i < 65535; i += 4)
  {
    uint32_t data = readDwordLe(i);
    if (data != 0)
    {
      printf("0x%08zx: 0x%08x\n", i, data);
    }
  }
}

/**
 * Reads a byte from memory
 * @param addr Memory location
 */
uint8_t Memory::readByte(uint32_t addr)
{
  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr < mem_size, 1))
  {
    return data[addr];
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
  return 0;
}

/**
 * Reads a word from memory (little endian)
 * @param memory Reference to the memory structure
 */
uint16_t Memory::readWordLe(uint32_t addr)
{
  uint32_t base;
  uint8_t off;

  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr + 1 < mem_size, 1))
  {
    base = addr & ~0x01;
    off = addr & 0x01;

    return (data[base + ((off + 0) & 0x01)] <<  0) |
           (data[base + ((off + 1) & 0x01)] <<  8);
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
  return 0;
}

/**
 * Reads a double word from memory (little endian)
 * @param address Memory location
 */
uint32_t Memory::readDwordLe(uint32_t addr)
{
  uint32_t base;
  uint8_t off;

  /* Apparently, SDRAM and IO peripherials are mapped to 4 different address
   * ranges by the VideoCore MMU. We can replicate that behaviour by ignoring
   * the two most significant bits of the address. We can do this thanks to
   * the fact that we ignore cacheing
   */
  addr = addr & 0x3FFFFFFF;

  /* SDRAM Read */
  if (__builtin_expect(addr + 3 < mem_size, 1))
  {
    base = addr & ~0x03;
    off = addr & 0x03;

    return (data[base + ((off + 0) & 0x03)] <<  0) |
           (data[base + ((off + 1) & 0x03)] <<  8) |
           (data[base + ((off + 2) & 0x03)] << 16) |
           (data[base + ((off + 3) & 0x03)] << 24);
  }

  /* System Timer */
  if (addr == 0x20003004)
  {
    uint64_t timer_value = emu->getSystemTimer();
    return (uint32_t)(timer_value & 0xffffffff);
  }
  else if (addr == 0x20003008)
  {
    uint64_t timer_value = emu->getSystemTimer();
    return (uint32_t)((timer_value >> 32) & 0xffffffff);
  }

  /* Grab relevant IoRegion and call it if registered */
  IoRegion *ioregion = iomap.getRegionForAddr(addr);
  if (ioregion) {
    return ioregion->readIo(addr - ioregion->base, sizeof(uint32_t));
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
  return 0;
}

/**
 * Writes a single byte to memory
 * @param addr  Memory location
 * @param value Data to be written
 */
void Memory::writeByte(uint32_t addr, uint8_t value)
{
  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr < mem_size, 1))
  {
    data[addr] = value;
    return;
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
}

/**
 * Writes a word to memory
 * @param addr Memory location
 * @param data Data to be written
 */
void Memory::writeWordLe(uint32_t addr, uint16_t value)
{
  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr + 1 < mem_size, 1))
  {
    data[addr + 0] = (value >> 0) & 0xFF;
    data[addr + 1] = (value >> 8) & 0xFF;
    return;
  }

  /* Grab relevant IoRegion and call it if registered */
  IoRegion *ioregion = iomap.getRegionForAddr(addr);
  if (ioregion) {
    ioregion->writeIo(addr, value, sizeof(uint16_t));
    return;
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
}

/**
 * Writes a double word to memory
 * @param addr  Memory location
 * @param value Data to be written
 */
void Memory::writeDwordLe(uint32_t addr, uint32_t value)
{
  addr = addr & 0x3FFFFFFF;

  /* SDRAM */
  if (__builtin_expect(addr + 3 < mem_size, 1))
  {
    data[addr + 0] = (value >>  0) & 0xFF;
    data[addr + 1] = (value >>  8) & 0xFF;
    data[addr + 2] = (value >> 16) & 0xFF;
    data[addr + 3] = (value >> 24) & 0xFF;
    return;
  }

  /* Grab relevant IoRegion and call it if registered */
  IoRegion *ioregion = iomap.getRegionForAddr(addr);
  if (ioregion) {
    ioregion->writeIo(addr - ioregion->base, value, sizeof(uint32_t));
    return;
  }

  emu->error("Out of bounds memory access at address 0x%08x", addr);
}

} /*namespace remu*/

<|endoftext|>


<commit_before>/*************************************************************************************
*                           Generates .lua Parameter Files                            *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
**************************************************************************************/
#include "Sweep.h"

using namespace std;

int main (int argc, char* argv[])
{
    if(argc < 2)
    {
        cout << "Proper Usage <Input file> <Path to Separation>" << endl;
        return -1;
    }

    try
    {
        clock_t timer;
        sweep * Sweep1;
        Sweep1 = new sweep(argv[1]);

        pid_t parentPid = getpid();
        cout << "Parent PID: " << parentPid << endl;
        time_t time1, time2;
        time(&time1);
        if(Sweep1->run(argv[2], "list.txt"))
        {
            return -1;
        }

        time(&time2);
        cout << "Time to run: " << difftime(time2, time1) << endl;
        Sweep1->cleanup();
        delete Sweep1;
    }
    catch(string error)
    {
        cerr << error << endl;
        return -1;
    }
    return 0;
}
<commit_msg>Removed missed debugging output.<commit_after>/*************************************************************************************
*                           Generates .lua Parameter Files                            *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
*                                                                                *
**************************************************************************************/
#include "Sweep.h"

using namespace std;

int main (int argc, char* argv[])
{
    if(argc < 2)
    {
        cout << "Proper Usage <Input file> <Path to Separation>" << endl;
        return -1;
    }

    try
    {
        clock_t timer;
        sweep * Sweep1;
        Sweep1 = new sweep(argv[1]);

        time_t time1, time2;
        time(&time1);
        if(Sweep1->run(argv[2], "list.txt"))
        {
            return -1;
        }

        time(&time2);
        cout << "Time to run: " << difftime(time2, time1) << endl;
        Sweep1->cleanup();
        delete Sweep1;
    }
    catch(string error)
    {
        cerr << error << endl;
        return -1;
    }
    return 0;
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// class T0 walk correction      Alla Maevskaya alla@inr.ru 20.11.2007        //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliT0CalibWalk.h"
#include "AliLog.h"

#include <TObjArray.h>
#include <TGraph.h>
#include <TFile.h>
#include <TH2F.h>
#include <TMath.h>
#include <TSystem.h>
#include <Riostream.h>
#include <TSpectrum.h>
#include <TProfile.h>
#include <TF1.h>

ClassImp(AliT0CalibWalk)

//________________________________________________________________
  AliT0CalibWalk::AliT0CalibWalk():   TNamed(),
				      fWalk(0),
				      fAmpLEDRec(0),
				      fQTC(0),
				      fAmpLED(0)
{
  //
}

//________________________________________________________________
AliT0CalibWalk::AliT0CalibWalk(const char* name):TNamed(),
				      fWalk(0),
				      fAmpLEDRec(0),				  				      fQTC(0),
				      fAmpLED(0)

{
  TString namst = "Calib_";
  namst += name;
  SetName(namst.Data());
  SetTitle(namst.Data());

}

//________________________________________________________________
AliT0CalibWalk::AliT0CalibWalk(const AliT0CalibWalk& calibda) :
  TNamed(calibda),
  fWalk(0),
  fAmpLEDRec(0),
  fQTC(0),
  fAmpLED(0)

{
// copy constructor
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

}

//________________________________________________________________
AliT0CalibWalk &AliT0CalibWalk::operator =(const AliT0CalibWalk& calibda)
{
// assignment operator
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

  return *this;
}

//________________________________________________________________
AliT0CalibWalk::~AliT0CalibWalk()
{
  //
}
//________________________________________________________________

Bool_t AliT0CalibWalk::MakeWalkCorrGraph(const char *laserFile)
{
  //make walk corerction for preprocessor
  Int_t npeaks = 20;
  Int_t sigma=3.;
  Bool_t down=false;
  Int_t index[20];
  Bool_t ok=true;
  Float_t   mips[20];
  Int_t nfound=0;

  gFile = TFile::Open(laserFile);
  if(!gFile) {
    AliError("No input laser data found ");
  }
  else
    {
      //      gFile->ls();
      TH1F* hAmp = (TH1F*) gFile->Get("hAmpLaser");
      Int_t nmips=0;
      for (Int_t ibin=0; ibin<2000; ibin++) {
	Float_t bincont = hAmp->GetBinContent(ibin);
	if(bincont>0){
	  mips[nmips] = hAmp->GetXaxis()->GetBinCenter(ibin);
	  cout<<ibin<<" bincont "<<bincont<<" amp "<< mips[nmips]<<endl;
	  nmips++;
	}
      }

      if (nmips<15) ok=false;

      Float_t x1[50], y1[50];
      Float_t x2[50], xx2[50],y2[50];
      Float_t xx1[50],yy1[50], xx[50];

      Float_t cfd0[24];
      Int_t startim = 0;

      for (Int_t ii=0; ii<nmips; ii++)
	x1[ii] = y1[ii] = x2[ii] = y2[ii] = 0;

      for (Int_t i=0; i<24; i++)
	{
	  for (Int_t im=startim; im<nmips; im++)
	    {
	      TString cfd = Form("hCFD%i_%i",i+1,im+1);
	      TString qtc = Form("hQTC%i_%i",i+1,im+1);
	      TString led = Form("hLED%i_%i",i+1,im+1);

	      TH1F *hCFD = (TH1F*) gFile->Get(cfd.Data()) ;
	      TH1F *hLED = (TH1F*) gFile->Get(led.Data());
	      TH1F *hQTC = (TH1F*) gFile->Get(qtc.Data()) ;
	      hCFD->SetDirectory(0);
	      hQTC->SetDirectory(0);
	      hLED->SetDirectory(0);
	      if(!hCFD )
 	      	AliWarning(Form(" no CFD data in LASER DA for channel %i for amplitude %f MIPs",i,mips[im]));
	      if(!hQTC )
 	      	AliWarning(Form(" no QTC correction data in LASER DA for channel %i for amplitude %f MIPs",i,mips[im]));
	      if(!hLED)
	      	AliWarning(Form(" no LED correction data in LASER DA for channel %i for amplitude %f MIPs",i,mips[im]));

	      if(hCFD )	{
		TSpectrum *s = new TSpectrum(2*npeaks,1);
		nfound = s->Search(hCFD,sigma," ",0.1);
		if(nfound!=0){
		  Float_t *xpeak = s->GetPositionX();
		  TMath::Sort(nfound, xpeak, index,down);
		  Float_t xp = xpeak[index[0]];
		  Double_t hmax = xp+3*sigma;
		  Double_t hmin = xp-3*sigma;
		  hCFD->GetXaxis()->SetRangeUser(hmin-10,hmax+10);
		}
		else
		  {
		    hCFD->Rebin(2);
		    TSpectrum *s1 = new TSpectrum(2*npeaks,1);
		    nfound = s1->Search(hCFD,sigma," ",0.1);
		    if(nfound!=0){
		      Float_t *xpeak = s1->GetPositionX();
		      TMath::Sort(nfound, xpeak, index,down);
		      Float_t xp = xpeak[index[0]];
		      Double_t hmax = xp+3*sigma;
		      Double_t hmin = xp-3*sigma;
		      hCFD->GetXaxis()->SetRangeUser(hmin-10,hmax+10);
		    }
		    else
		      ok=false;
		  }

		if (im == 0) cfd0[i] = hCFD->GetMean();
		y1[im] =  hCFD->GetMean() - cfd0[i];
	      }
	      if( hQTC) x1[im] = hQTC->GetMean();

	      if( hLED){
		TSpectrum *s = new TSpectrum(2*npeaks,1);
		nfound = s->Search(hLED,sigma," ",0.1);
		if(nfound!=0){
		  Float_t *xpeak = s->GetPositionX();
		  TMath::Sort(nfound, xpeak, index,down);
		  Float_t xp = xpeak[index[0]];
		  Double_t hmax = xp+10*sigma;
		  Double_t hmin = xp-10*sigma;
		  hLED->GetXaxis()->SetRangeUser(hmin-10,hmax+10);
		}
		else
		  ok=false;
		x2[im] = hLED->GetMean();
		xx2[im] = x2[nmips-im-1];
	      }
	      xx[im]=mips[im];

	      if (hQTC) delete  hQTC;
	      if (hCFD) delete  hCFD;
	      if (hLED) delete  hLED;
	    }

	  for (Int_t imi=0; imi<nmips; imi++)
	    {
	      yy1[imi] = Float_t (mips[nmips-imi-1]);
	      xx1[imi] = x2[nmips-imi-1];
	      //	      cout<<" LED rev "<<i<<" "<<imi<<" "<<xx1[imi]<<" "<< yy1[imi]<<"nmips-imi-1 = "<< nmips-imi-1<<endl;
	    }

	  if(i==0) cout<<"Making graphs..."<<endl;

	  /*

	  Float_t x1[50], y1[50];
	  Float_t x2[50], xx2[50],y2[50];
	  Float_t xx1[50],yy1[50], xx[50];

	  Int_t nmips=20;
	  for (Int_t i=0; i<24; i++)
	  {

	  for (Int_t im=0; im<nmips; im++)
	  {
	  x1[im]=xx[im]=500+im*200;
	  y1[im]=0;
	  x2[im]=xx1[im]=yy1[im]=260+20*im;
	  }
	  */
       TGraph *grwalkqtc = new TGraph (nmips,x1,y1);
      grwalkqtc->SetTitle(Form("PMT%i",i));
      TGraph *grwalkled = new TGraph (nmips,x2,y1);
      grwalkled->SetTitle(Form("PMT%i",i));
      fWalk.AddAtAndExpand(grwalkqtc,i);
      fAmpLEDRec.AddAtAndExpand(grwalkled,i);
      //	  cout<<" add walk "<<i<<endl;

      //fit amplitude graphs to make comparison wth new one
      TGraph *grampled = new TGraph (nmips,xx1,yy1);
      TGraph *grqtc = new TGraph (nmips,x1,xx);
      fQTC.AddAtAndExpand(grqtc,i);
      fAmpLED.AddAtAndExpand(grampled,i);
      //	  cout<<" add amp "<<i<<endl;

      if(i==23)
	cout<<"Graphs created..."<<endl;
	}
    } //if gFile exits
  ok=true;
  return ok;
}

<commit_msg>fixed: now preprocessor will not crash for 1st 17 amplitude calibration runs<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// class T0 walk correction      Alla Maevskaya alla@inr.ru 20.11.2007        //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliT0CalibWalk.h"
#include "AliLog.h"

#include <TObjArray.h>
#include <TGraph.h>
#include <TFile.h>
#include <TH2F.h>
#include <TMath.h>
#include <TSystem.h>
#include <Riostream.h>
#include <TSpectrum.h>
#include <TProfile.h>
#include <TF1.h>

ClassImp(AliT0CalibWalk)

//________________________________________________________________
  AliT0CalibWalk::AliT0CalibWalk():   TNamed(),
				      fWalk(0),
				      fAmpLEDRec(0),
				      fQTC(0),
				      fAmpLED(0)
{
  //
}

//________________________________________________________________
AliT0CalibWalk::AliT0CalibWalk(const char* name):TNamed(),
				      fWalk(0),
				      fAmpLEDRec(0),				  				      fQTC(0),
				      fAmpLED(0)

{
  TString namst = "Calib_";
  namst += name;
  SetName(namst.Data());
  SetTitle(namst.Data());

}

//________________________________________________________________
AliT0CalibWalk::AliT0CalibWalk(const AliT0CalibWalk& calibda) :
  TNamed(calibda),
  fWalk(0),
  fAmpLEDRec(0),
  fQTC(0),
  fAmpLED(0)

{
// copy constructor
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

}

//________________________________________________________________
AliT0CalibWalk &AliT0CalibWalk::operator =(const AliT0CalibWalk& calibda)
{
// assignment operator
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

  return *this;
}

//________________________________________________________________
AliT0CalibWalk::~AliT0CalibWalk()
{
  //
}
//________________________________________________________________

Bool_t AliT0CalibWalk::MakeWalkCorrGraph(const char *laserFile)
{
  //make walk corerction for preprocessor
  Int_t npeaks = 20;
  Int_t sigma=3;
  Bool_t down=false;
  Int_t index[20];
  Bool_t ok=true;
  Float_t   mips[20];
  Int_t nfound=0;

  gFile = TFile::Open(laserFile);
  if(!gFile) {
    AliError("No input laser data found ");
  }
  else
    {
      //      gFile->ls();
      TH1F* hAmp = (TH1F*) gFile->Get("hAmpLaser");
      Int_t nmips=0;
      for (Int_t ibin=0; ibin<2000; ibin++) {
	Float_t bincont = hAmp->GetBinContent(ibin);
	if(bincont>0){
	  mips[nmips] = hAmp->GetXaxis()->GetBinCenter(ibin);
	  cout<<ibin<<" bincont "<<bincont<<" amp "<< mips[nmips]<<endl;
	  nmips++;
	}
      }

      if (nmips<17) {
	ok=false;
	return ok;
      }

      Float_t x1[50], y1[50];
      Float_t x2[50], xx2[50],y2[50];
      Float_t xx1[50],yy1[50], xx[50];

      Float_t cfd0[24];
      Int_t startim = 0;

      for (Int_t ii=0; ii<nmips; ii++)
	x1[ii] = y1[ii] = x2[ii] = y2[ii] = 0;

      for (Int_t i=0; i<24; i++)
	{
	  for (Int_t im=startim; im<nmips; im++)
	    {
	      TString cfd = Form("hCFD%i_%i",i+1,im+1);
	      TString qtc = Form("hQTC%i_%i",i+1,im+1);
	      TString led = Form("hLED%i_%i",i+1,im+1);

	      TH1F *hCFD = (TH1F*) gFile->Get(cfd.Data()) ;
	      TH1F *hLED = (TH1F*) gFile->Get(led.Data());
	      TH1F *hQTC = (TH1F*) gFile->Get(qtc.Data()) ;
	      hCFD->SetDirectory(0);
	      hQTC->SetDirectory(0);
	      hLED->SetDirectory(0);
	      if(!hCFD )
 	      	AliWarning(Form(" no CFD data in LASER DA for channel %i for amplitude %f MIPs",i,mips[im]));
	      if(!hQTC )
 	      	AliWarning(Form(" no QTC correction data in LASER DA for channel %i for amplitude %f MIPs",i,mips[im]));
	      if(!hLED)
	      	AliWarning(Form(" no LED correction data in LASER DA for channel %i for amplitude %f MIPs",i,mips[im]));

	      if(hCFD )	{
		TSpectrum *s = new TSpectrum(2*npeaks,1);
		nfound = s->Search(hCFD,sigma," ",0.1);
		if(nfound!=0){
		  Float_t *xpeak = s->GetPositionX();
		  TMath::Sort(nfound, xpeak, index,down);
		  Float_t xp = xpeak[index[0]];
		  Double_t hmax = xp+3*sigma;
		  Double_t hmin = xp-3*sigma;
		  hCFD->GetXaxis()->SetRangeUser(hmin-10,hmax+10);
		}
		else
		  {
		    hCFD->Rebin(2);
		    TSpectrum *s1 = new TSpectrum(2*npeaks,1);
		    nfound = s1->Search(hCFD,sigma," ",0.1);
		    if(nfound!=0){
		      Float_t *xpeak = s1->GetPositionX();
		      TMath::Sort(nfound, xpeak, index,down);
		      Float_t xp = xpeak[index[0]];
		      Double_t hmax = xp+3*sigma;
		      Double_t hmin = xp-3*sigma;
		      hCFD->GetXaxis()->SetRangeUser(hmin-10,hmax+10);
		    }
		    else
		      {
			ok=false;
			printf("no peak in CFD spectrum for PMT %i amplitude %i\n",i,im);
			return ok;
		      }

		  }

		if (im == 0) cfd0[i] = hCFD->GetMean();
		y1[im] =  hCFD->GetMean() - cfd0[i];
	      }
	      if( hQTC) {
		x1[im] = hQTC->GetMean();
		if( x1[im] == 0) {
		  ok=false;
		  printf("no peak in QTC signal for PMT %i amplitude %i\n",i,im);
		  return ok;
		  }
	      }

	      if( hLED){
		TSpectrum *s = new TSpectrum(2*npeaks,1);
		nfound = s->Search(hLED,sigma," ",0.1);
		if(nfound!=0){
		  Float_t *xpeak = s->GetPositionX();
		  TMath::Sort(nfound, xpeak, index,down);
		  Float_t xp = xpeak[index[0]];
		  Double_t hmax = xp+10*sigma;
		  Double_t hmin = xp-10*sigma;
		  hLED->GetXaxis()->SetRangeUser(hmin-10,hmax+10);
		}
		else
		  {
		    ok=false;
		    printf("no peak in LED spectrum for PMT %i amplitude %i\n",i,im);
		    return ok;
		  }
		x2[im] = hLED->GetMean();
		xx2[im] = x2[nmips-im-1];
	      }
	      xx[im]=mips[im];

	      if (hQTC) delete  hQTC;
	      if (hCFD) delete  hCFD;
	      if (hLED) delete  hLED;
	    }

	  for (Int_t imi=0; imi<nmips; imi++)
	    {
	      yy1[imi] = Float_t (mips[nmips-imi-1]);
	      xx1[imi] = x2[nmips-imi-1];
	      //	      cout<<" LED rev "<<i<<" "<<imi<<" "<<xx1[imi]<<" "<< yy1[imi]<<"nmips-imi-1 = "<< nmips-imi-1<<endl;
	    }

	  if(i==0) cout<<"Making graphs..."<<endl;

	  /*

	  Float_t x1[50], y1[50];
	  Float_t x2[50], xx2[50],y2[50];
	  Float_t xx1[50],yy1[50], xx[50];

	  Int_t nmips=20;
	  for (Int_t i=0; i<24; i++)
	  {

	  for (Int_t im=0; im<nmips; im++)
	  {
	  x1[im]=xx[im]=500+im*200;
	  y1[im]=0;
	  x2[im]=xx1[im]=yy1[im]=260+20*im;
	  }
	  */
       TGraph *grwalkqtc = new TGraph (nmips,x1,y1);
      grwalkqtc->SetTitle(Form("PMT%i",i));
      TGraph *grwalkled = new TGraph (nmips,x2,y1);
      grwalkled->SetTitle(Form("PMT%i",i));
      fWalk.AddAtAndExpand(grwalkqtc,i);
      fAmpLEDRec.AddAtAndExpand(grwalkled,i);
      //	  cout<<" add walk "<<i<<endl;

      //fit amplitude graphs to make comparison wth new one
      TGraph *grampled = new TGraph (nmips,xx1,yy1);
      TGraph *grqtc = new TGraph (nmips,x1,xx);
      fQTC.AddAtAndExpand(grqtc,i);
      fAmpLED.AddAtAndExpand(grampled,i);
      //	  cout<<" add amp "<<i<<endl;

      if(i==23)
	cout<<"Graphs created..."<<endl;
	}
    } //if gFile exits

  return ok;
}

<|endoftext|>


<commit_before>#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <complex>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <utility>

using namespace std;

typedef long l;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned long ul;
typedef long double ld;
typedef pair<int, int > Pii;

const double pi = acos(-1.0);

const int INF = INT_MAX;
const int MAX_N = 50005;
const int MAX_V = MAX_N;
const int MAX_E = 100010;

template <typename T>
inline T sqr(T a) { return a * a;};

struct edge {
    int u, v;
    int dis;
};
vector<edge> g[MAX_V];
vector<edge> es;
bool vis[MAX_N];
int d[MAX_N], V, E, pre[MAX_V];
int cost[MAX_V][MAX_V];

class Point {
public:
    double x, y;
    friend double dis(Point A, Point B) {
        return sqrt(sqr(A.x - B.x) + sqr(A.y - B.y));
    }
    void print() {
        printf("(%.2f, %.2f)\n", x, y);
    }
};

void dijkstra(int s) {
    //
    // fill(d, d + V, INF);
    // fill(vis, vis + V, false);
    // d[s] = 0;
    // while (true) {
    //     int v = -1;
    //     for (int u = 0; u < V; ++u)
    //         if (!vis[u] && (v == -1 || d[u] < d[v])) v = u;
    //     if (v == -1) break;
    //     vis[v] = true;
    //     for (int u = 0; u < V; ++u) {
    //         d[u] = min(d[v] + cost[v][u], d[u]);
    //     }
    // }
    //
    priority_queue<Pii, vector<Pii>, greater<Pii> > que;// fisrt 是最短距离，second 是顶点编号
    fill(d, d + V, INF);
    d[s] = 0;
    que.push(Pii(0, s));
    while (!que.empty()) {
        Pii p = que.top();que.pop();
        int u = p.second;
        if (d[u] < p.first) continue;
        for (int i = 0; i < g[u].size(); i++) {
            edge e = g[u][i];
            if (d[e.v] > d[u] + e.dis) {
                d[e.v] = d[u] + e.dis;
                que.push(Pii(d[e.v], e.v));
            }
        }
    }
}
void bellman_ford(int s) {
    fill(d, d + V, INF);
    d[s] = 0;
    //
    // for (int i = 0; i < V; ++i
    //     for (int j = 0; j < E; ++j) {
    //         int u, v;
    //         u = es[j].u;
    //         v = es[j].v;
    //         if (d[u] != INF)
    //             d[v] = min(d[u] + es[j].dis, d[v]);
    //         if (d[v] != INF)
    //             d[u] = min(d[v] + es[j].dis, d[u]);
    //     }
    //
    while (true) {
        bool update = false;
        for (int i = 0; i < E; ++i) {
            edge e = es[i];
            if (d[e.u] != INF && d[e.u] + e.dis < d[e.v]) {
                update = true;
                d[e.v] = d[e.u] + e.dis;
            }
        }
        if (!update) break;
    }
}
void spfa(int s) {
    queue<int> que;
    fill(d, d + V, INF);
    fill(vis, vis + V, false);
    d[s] = 0;
    que.push(s);
    vis[s] = true;
    while (!que.empty()) {
        int u = que.front();
        que.pop();
        vis[u] = false;
        for (int i = 0; i < g[u].size(); ++i) {
            int v = g[u][i].v;
            if (d[v] > d[u] + g[u][i].dis) {
                d[v] = d[u] + g[u][i].dis;
                if (!vis[v]) {
                    que.push(v);
                    vis[v] = true;
                }
            }
        }
    }
}
int prim() {
    fill(d, d + V, INF);
    fill(vis, vis + V, false);
    d[0] = 0;
    int res = 0;
    while (true) {
        int v = -1;
        for (int u = 0; u < V; ++u) {
            if(!vis[u] && (v == -1 || d[u] < d[v])) v = u;
        }
        if (v == -1) break;
        vis[v] = true;
        res += d[v];
        for (int u = 0; u < V; u++)
            d[u] = min(d[u], cost[v][u]);
    }
    return res;
}
bool cmp(edge &e1, edge &e2) {
    return e1.dis < e2.dis;
}
// int kruskal() {
//     sort(es, es + E, cmp);
//     init(V);
//     int res = 0;
//     for (int i = 0; i < E; ++i) {
//         edge e = es[i];
//         if (!same(e.u, e.v)) {
//             unite(e.u, e.v);
//             res += e.dis;
//         }
//     }
//     return res;
// }
bool isPrime(int n) {
    for (int i = 2; i * i <= n; ++i)
        if (n % i == 0) return false;
    return n != 1;
}
vector<int> divisor(int n) {
    vector<int> res;
    for (int i = 1; i * i <= n; ++i) {
        if (n % i == 0) {
            res.push_back(i);
            if (i != n / i) res.push_back(n / i);
        }
    }
    return res;
}
map<int, int> primeFactor(int n) {
    map<int, int> res;
    for (int i = 2; i * i <= n; ++i) {
        while (n % i == 0) {
            ++res[i];
            n /= i;
        }
    }
    if (n != 1) res[n] = 1;
    return res;
}
int prime[MAX_N];
bool is_prime[MAX_N + 1];
int seive(int n) {
    int p = 0;
    fill(is_prime, is_prime + n + 1, true);
    is_prime[0] = is_prime[1] = false;
    for (int i = 2; i <= n; ++i)
        if (is_prime[i]) {
            prime[p++] = i;
            for (int j = 2 * i; j <= n; j += i) is_prime[j] = false;
        }
    return p;
}
const int MAX_L = 1e5, MAX_SQRT_R = 1e3;
bool seg_prime_small[MAX_L];
bool seg_prime[MAX_SQRT_R];
// the number of prime in [L, r)
// 对区间 [l, r）内的整数执行筛法，prime[i - l] = true <=> i 是素数
void segmentSieve(ll l, ll r) {
    for (int i = 0; (ll)i * i < r; ++i) seg_prime_small[i] = true;
    for (int i = 0; i < r - l; ++i) seg_prime[i] = true;
    for (int i = 2; (ll)i * i < r; ++i) {
        if (seg_prime_small[i]) {
            for (int j = 2 * i; (ll)j * j <= r; j += i) seg_prime_small[j] = false;
            for (ll j = max(2LL, (l + i - 1) / i) * i; j < r; j += i) seg_prime[j - l] = false;
        }
    }
}
int getMaxString(const string &str) {
    int len = (int)str.length();
    int i = 0, j = 1, k = 0;
    while (i < len && j < len && k < len) {
        int t = str[(i + k) % len] - str[(j + k) % len];
        if (t == 0) ++k;
        else {
            if (t > 0) j += k + 1;
            else i += k + 1;
            if (i == j) ++j;
            k = 0;
        }
    }
    return min(i, j);
}
int nxt[MAX_N];
void getNext(const string &str) {
    int j = 0, k, len = str.length();
    nxt[0] = k = -1;
    while (j < len) {
        if (k == -1 || str[j] == str[k])
            nxt[++j] = ++k;
        else k = nxt[k];
    }
}
int kmp(const string &tar, const string &pat) {
    getNext(pat);
    int j, k, res;
    int lenT = tar.length(), lenP = pat.length();
    res = j = k = 0;
    while (j < lenT) {
        if (k == -1 || tar[j] == pat[k])
            ++j, ++k;
        else k = nxt[k];
        if (k == lenP) {
            res = max(res, j - lenP + 1);
            k = nxt[k];
        }
    }
    return res;
}

// int extNext[MAX_N];
// void getExtNext(const string &str) {
//     int j = 0, k, len = str.length();
//     k = exNext[0] = -1;
//     while (j < len) {
//         while (k != -1 && str[j] != str[k])
//             k = exNext[k];
//         ++j, ++k;
//         if (str[j] == str[k])
//             exNext[j] = exNext[k];
//         else exNext[j] = k;
//     }
// }
// int extKmp(const string &tar, const string &pat) {
//     getExtNext(pat);
//     int l, r, j, k;
//     int lenT = tar.length(), lenP = pat.length();
//     while (j < lenT) {

//     }
// }

// void Cal_next (const char *pattern,int len)  //改进写法,next[]有多个-1
// {
//     int i=0,j=-1;
//     next[0]=-1;
//     while (i<len)
//     {
//         while (j>=0 && pattern[i]!=pattern[j])
//             j=next[j];
//         j++,i++;
//         if (pattern[j]==pattern[i])
//             next[i]=next[j];
//         else
//             next[i]=j;
//     }
// }
// void exKMP (char s[],char t[]) //s为主串，t为模板串
// {
//     int i,j=0,p,L;
//     int lens=strlen(s);
//     int lent=strlen(t);
//     next[0]=lent;

//     while (j+1<lent && t[j]==t[j+1])
//         j++;
//     next[1]=j;

//     int a=1;
//     for (i=2;i<lent;i++)
//     {
//         p=next[a]+a-1;
//         L=next[i-a];
//         if (i+L<p+1) next[i]=L;
//         else
//         {
//             j=max(0,p-i+1);
//             while (i+j<lent && t[i+j]==t[j])
//                 j++;
//             next[i]=j;
//             a=i;
//         }
//     }

//     j=0;
//     while (j<lens && j<lent && s[j]==t[j])
//         j++;
//     extend[0]=j;
//     a=0;
//     for (i=1;i<lens;i++)
//     {
//         p=extend[a]+a-1;
//         L=next[i-a];
//         if (L+i<p+1) extend[i]=L;
//         else
//         {
//             j=max(0,p-i+1);
//             while (i+j<lens && j<lent && s[i+j]==t[j])
//                 j++;
//             extend[i]=j;
//             a=i;
//         }
//     }
// }
// void GetExtand(const EleType str[], int strLen, int extand[], const EleType mode[], int modeLen, int next[])
// {
//     int i, a, p, j(-1);

//     for (i = 0; i < strLen; ++i, --j)
//     {
//         if (j < 0 || i + next[i - a] >= p)
//         {
//             if (j < 0) j = 0, p = i;
//             while (p < strLen && j < modeLen && str[p] == mode[j])
//                 ++p, ++j;
//             extand[i] = j, a = i;
//         }
//         else extand[i] = next[i - a];
//     }
// }

int lis[MAX_N], a[MAX_N];
void solve(int n) {
    int dp[MAX_N];
    fill(dp, dp + n, INF);
    for (int i = 0; i < n; ++i)
        *lower_bound(dp, dp + n, a[i]) = a[i];// lds: -a[i]
    printf("%ld\n", lower_bound(dp, dp + n, INF) - dp);
}

int mu[MAX_N];
void moebius() {
    int cnt = 0; mu[1] = 1;
    memset(vis, 0, sizeof vis);
    for (int i = 2; i < MAX_N; ++i) {
        if (!vis[i]) {
            prime[cnt++] = i;
            mu[i] = -1;
        }
        for (int j = 0; j < cnt && i * prime[j] < MAX_N; ++j) {
            vis[i * prime[j]] = true;
            if (i % prime[j])
                mu[i * prime[j]] = -mu[i];
            else
                mu[i * prime[j]] = 0, break;
        }
    }
}

int main(void) {

    return 0;
}
<commit_msg>Modified template.cpp<commit_after>#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <complex>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <utility>

using namespace std;

typedef long l;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned long ul;
typedef long double ld;
typedef pair<int, int > Pii;

const double pi = acos(-1.0);

const int INF = INT_MAX;
const int MAX_N = 50005;
const int MAX_V = MAX_N;
const int MAX_E = 100010;

template <typename T>
inline T sqr(T a) { return a * a;};

struct edge {
    int u, v;
    int dis;
};
vector<edge> g[MAX_V];
vector<edge> es;
bool vis[MAX_N];
int d[MAX_N], V, E, pre[MAX_V];
int cost[MAX_V][MAX_V];

class Point {
public:
    double x, y;
    friend double dis(Point A, Point B) {
        return sqrt(sqr(A.x - B.x) + sqr(A.y - B.y));
    }
    void print() {
        printf("(%.2f, %.2f)\n", x, y);
    }
};

void dijkstra(int s) {
    //
    // fill(d, d + V, INF);
    // fill(vis, vis + V, false);
    // d[s] = 0;
    // while (true) {
    //     int v = -1;
    //     for (int u = 0; u < V; ++u)
    //         if (!vis[u] && (v == -1 || d[u] < d[v])) v = u;
    //     if (v == -1) break;
    //     vis[v] = true;
    //     for (int u = 0; u < V; ++u) {
    //         d[u] = min(d[v] + cost[v][u], d[u]);
    //     }
    // }
    //
    priority_queue<Pii, vector<Pii>, greater<Pii> > que;// fisrt 是最短距离，second 是顶点编号
    fill(d, d + V, INF);
    d[s] = 0;
    que.push(Pii(0, s));
    while (!que.empty()) {
        Pii p = que.top();que.pop();
        int u = p.second;
        if (d[u] < p.first) continue;
        for (int i = 0; i < g[u].size(); i++) {
            edge e = g[u][i];
            if (d[e.v] > d[u] + e.dis) {
                d[e.v] = d[u] + e.dis;
                que.push(Pii(d[e.v], e.v));
            }
        }
    }
}
void bellman_ford(int s) {
    fill(d, d + V, INF);
    d[s] = 0;
    //
    // for (int i = 0; i < V; ++i
    //     for (int j = 0; j < E; ++j) {
    //         int u, v;
    //         u = es[j].u;
    //         v = es[j].v;
    //         if (d[u] != INF)
    //             d[v] = min(d[u] + es[j].dis, d[v]);
    //         if (d[v] != INF)
    //             d[u] = min(d[v] + es[j].dis, d[u]);
    //     }
    //
    while (true) {
        bool update = false;
        for (int i = 0; i < E; ++i) {
            edge e = es[i];
            if (d[e.u] != INF && d[e.u] + e.dis < d[e.v]) {
                update = true;
                d[e.v] = d[e.u] + e.dis;
            }
        }
        if (!update) break;
    }
}
void spfa(int s) {
    queue<int> que;
    fill(d, d + V, INF);
    fill(vis, vis + V, false);
    d[s] = 0;
    que.push(s);
    vis[s] = true;
    while (!que.empty()) {
        int u = que.front();
        que.pop();
        vis[u] = false;
        for (int i = 0; i < g[u].size(); ++i) {
            int v = g[u][i].v;
            if (d[v] > d[u] + g[u][i].dis) {
                d[v] = d[u] + g[u][i].dis;
                if (!vis[v]) {
                    que.push(v);
                    vis[v] = true;
                }
            }
        }
    }
}
int prim() {
    fill(d, d + V, INF);
    fill(vis, vis + V, false);
    d[0] = 0;
    int res = 0;
    while (true) {
        int v = -1;
        for (int u = 0; u < V; ++u) {
            if(!vis[u] && (v == -1 || d[u] < d[v])) v = u;
        }
        if (v == -1) break;
        vis[v] = true;
        res += d[v];
        for (int u = 0; u < V; u++)
            d[u] = min(d[u], cost[v][u]);
    }
    return res;
}
bool cmp(edge &e1, edge &e2) {
    return e1.dis < e2.dis;
}
// int kruskal() {
//     sort(es, es + E, cmp);
//     init(V);
//     int res = 0;
//     for (int i = 0; i < E; ++i) {
//         edge e = es[i];
//         if (!same(e.u, e.v)) {
//             unite(e.u, e.v);
//             res += e.dis;
//         }
//     }
//     return res;
// }
bool isPrime(int n) {
    for (int i = 2; i * i <= n; ++i)
        if (n % i == 0) return false;
    return n != 1;
}
vector<int> divisor(int n) {
    vector<int> res;
    for (int i = 1; i * i <= n; ++i) {
        if (n % i == 0) {
            res.push_back(i);
            if (i != n / i) res.push_back(n / i);
        }
    }
    return res;
}
map<int, int> primeFactor(int n) {
    map<int, int> res;
    for (int i = 2; i * i <= n; ++i) {
        while (n % i == 0) {
            ++res[i];
            n /= i;
        }
    }
    if (n != 1) res[n] = 1;
    return res;
}
int prime[MAX_N];
bool is_prime[MAX_N + 1];
int seive(int n) {
    int p = 0;
    fill(is_prime, is_prime + n + 1, true);
    is_prime[0] = is_prime[1] = false;
    for (int i = 2; i <= n; ++i)
        if (is_prime[i]) {
            prime[p++] = i;
            for (int j = 2 * i; j <= n; j += i) is_prime[j] = false;
        }
    return p;
}
const int MAX_L = 1e5, MAX_SQRT_R = 1e3;
bool seg_prime_small[MAX_L];
bool seg_prime[MAX_SQRT_R];
// the number of prime in [L, r)
// 对区间 [l, r）内的整数执行筛法，prime[i - l] = true <=> i 是素数
void segmentSieve(ll l, ll r) {
    for (int i = 0; (ll)i * i < r; ++i) seg_prime_small[i] = true;
    for (int i = 0; i < r - l; ++i) seg_prime[i] = true;
    for (int i = 2; (ll)i * i < r; ++i) {
        if (seg_prime_small[i]) {
            for (int j = 2 * i; (ll)j * j <= r; j += i) seg_prime_small[j] = false;
            for (ll j = max(2LL, (l + i - 1) / i) * i; j < r; j += i) seg_prime[j - l] = false;
        }
    }
}
int getMaxString(const string &str) {
    int len = (int)str.length();
    int i = 0, j = 1, k = 0;
    while (i < len && j < len && k < len) {
        int t = str[(i + k) % len] - str[(j + k) % len];
        if (t == 0) ++k;
        else {
            if (t > 0) j += k + 1;
            else i += k + 1;
            if (i == j) ++j;
            k = 0;
        }
    }
    return min(i, j);
}
int nxt[MAX_N];
void getNext(const string &str) {
    int j = 0, k, len = str.length();
    nxt[0] = k = -1;
    while (j < len) {
        if (k == -1 || str[j] == str[k])
            nxt[++j] = ++k;
        else k = nxt[k];
    }
}
int kmp(const string &tar, const string &pat) {
    getNext(pat);
    int j, k, res;
    int lenT = tar.length(), lenP = pat.length();
    res = j = k = 0;
    while (j < lenT) {
        if (k == -1 || tar[j] == pat[k])
            ++j, ++k;
        else k = nxt[k];
        if (k == lenP) {
            res = max(res, j - lenP + 1);
            k = nxt[k];
        }
    }
    return res;
}

// int extNext[MAX_N];
// void getExtNext(const string &str) {
//     int j = 0, k, len = str.length();
//     k = exNext[0] = -1;
//     while (j < len) {
//         while (k != -1 && str[j] != str[k])
//             k = exNext[k];
//         ++j, ++k;
//         if (str[j] == str[k])
//             exNext[j] = exNext[k];
//         else exNext[j] = k;
//     }
// }
// int extKmp(const string &tar, const string &pat) {
//     getExtNext(pat);
//     int l, r, j, k;
//     int lenT = tar.length(), lenP = pat.length();
//     while (j < lenT) {

//     }
// }

// void Cal_next (const char *pattern,int len)  //改进写法,next[]有多个-1
// {
//     int i=0,j=-1;
//     next[0]=-1;
//     while (i<len)
//     {
//         while (j>=0 && pattern[i]!=pattern[j])
//             j=next[j];
//         j++,i++;
//         if (pattern[j]==pattern[i])
//             next[i]=next[j];
//         else
//             next[i]=j;
//     }
// }
// void exKMP (char s[],char t[]) //s为主串，t为模板串
// {
//     int i,j=0,p,L;
//     int lens=strlen(s);
//     int lent=strlen(t);
//     next[0]=lent;

//     while (j+1<lent && t[j]==t[j+1])
//         j++;
//     next[1]=j;

//     int a=1;
//     for (i=2;i<lent;i++)
//     {
//         p=next[a]+a-1;
//         L=next[i-a];
//         if (i+L<p+1) next[i]=L;
//         else
//         {
//             j=max(0,p-i+1);
//             while (i+j<lent && t[i+j]==t[j])
//                 j++;
//             next[i]=j;
//             a=i;
//         }
//     }

//     j=0;
//     while (j<lens && j<lent && s[j]==t[j])
//         j++;
//     extend[0]=j;
//     a=0;
//     for (i=1;i<lens;i++)
//     {
//         p=extend[a]+a-1;
//         L=next[i-a];
//         if (L+i<p+1) extend[i]=L;
//         else
//         {
//             j=max(0,p-i+1);
//             while (i+j<lens && j<lent && s[i+j]==t[j])
//                 j++;
//             extend[i]=j;
//             a=i;
//         }
//     }
// }
// void GetExtand(const EleType str[], int strLen, int extand[], const EleType mode[], int modeLen, int next[])
// {
//     int i, a, p, j(-1);

//     for (i = 0; i < strLen; ++i, --j)
//     {
//         if (j < 0 || i + next[i - a] >= p)
//         {
//             if (j < 0) j = 0, p = i;
//             while (p < strLen && j < modeLen && str[p] == mode[j])
//                 ++p, ++j;
//             extand[i] = j, a = i;
//         }
//         else extand[i] = next[i - a];
//     }
// }

int lis[MAX_N], a[MAX_N];
void solve(int n) {
    int dp[MAX_N];
    fill(dp, dp + n, INF);
    for (int i = 0; i < n; ++i)
        *lower_bound(dp, dp + n, a[i]) = a[i];// lds: -a[i]; lni: upper_bound
    printf("%ld\n", lower_bound(dp, dp + n, INF) - dp);
}

int mu[MAX_N];
void moebius() {
    int cnt = 0; mu[1] = 1;
    memset(vis, 0, sizeof vis);
    for (int i = 2; i < MAX_N; ++i) {
        if (!vis[i]) {
            prime[cnt++] = i;
            mu[i] = -1;
        }
        for (int j = 0; j < cnt && i * prime[j] < MAX_N; ++j) {
            vis[i * prime[j]] = true;
            if (i % prime[j])
                mu[i * prime[j]] = -mu[i];
            else {
                mu[i * prime[j]] = 0;break;
            }
        }
    }
}

int main(void) {
    cout << seive(1000000000) << endl;
    return 0;
}
<|endoftext|>