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

/* Author: Ioan Sucan */

#include "ompl/base/manifolds/RealVectorStateManifold.h"
#include "ompl/base/manifolds/RealVectorStateProjections.h"
#include "ompl/util/Exception.h"
#include <algorithm>
#include <cstring>
#include <limits>
#include <cmath>

void ompl::base::RealVectorStateSampler::sampleUniform(State *state)
{
    const unsigned int dim = manifold_->getDimension();
    const RealVectorBounds &bounds = static_cast<const RealVectorStateManifold*>(manifold_)->getBounds();

    RealVectorStateManifold::StateType *rstate = static_cast<RealVectorStateManifold::StateType*>(state);
    for (unsigned int i = 0 ; i < dim ; ++i)
        rstate->values[i] = rng_.uniformReal(bounds.low[i], bounds.high[i]);
}

void ompl::base::RealVectorStateSampler::sampleUniformNear(State *state, const State *near, const double distance)
{
    const unsigned int dim = manifold_->getDimension();
    const RealVectorBounds &bounds = static_cast<const RealVectorStateManifold*>(manifold_)->getBounds();

    RealVectorStateManifold::StateType *rstate = static_cast<RealVectorStateManifold::StateType*>(state);
    const RealVectorStateManifold::StateType *rnear = static_cast<const RealVectorStateManifold::StateType*>(near);
    for (unsigned int i = 0 ; i < dim ; ++i)
        rstate->values[i] =
            rng_.uniformReal(std::max(bounds.low[i], rnear->values[i] - distance),
                             std::min(bounds.high[i], rnear->values[i] + distance));
}

void ompl::base::RealVectorStateSampler::sampleGaussian(State *state, const State *mean, const double stdDev)
{
    const unsigned int dim = manifold_->getDimension();
    const RealVectorBounds &bounds = static_cast<const RealVectorStateManifold*>(manifold_)->getBounds();

    RealVectorStateManifold::StateType *rstate = static_cast<RealVectorStateManifold::StateType*>(state);
    const RealVectorStateManifold::StateType *rmean = static_cast<const RealVectorStateManifold::StateType*>(mean);
    for (unsigned int i = 0 ; i < dim ; ++i)
    {
        double v = rng_.gaussian(rmean->values[i], stdDev);
        if (v < bounds.low[i])
            v = bounds.low[i];
        else
            if (v > bounds.high[i])
                v = bounds.high[i];
        rstate->values[i] = v;
    }
}

void ompl::base::RealVectorStateManifold::registerProjections(void)
{
    // compute a default random projection
    if (dimension_ > 0)
    {
        if (dimension_ > 2)
        {
            int p = std::max(2, (int)ceil(log((double)dimension_)));
            registerDefaultProjection(ProjectionEvaluatorPtr(new RealVectorRandomLinearProjectionEvaluator(this, p)));
        }
        else
            registerDefaultProjection(ProjectionEvaluatorPtr(new RealVectorIdentityProjectionEvaluator(this)));
    }
}

void ompl::base::RealVectorStateManifold::setup(void)
{
    bounds_.check();
    StateManifold::setup();
}

void ompl::base::RealVectorStateManifold::addDimension(const std::string &name, double minBound, double maxBound)
{
    addDimension(minBound, maxBound);
    setDimensionName(dimension_ - 1, name);
}

void ompl::base::RealVectorStateManifold::addDimension(double minBound, double maxBound)
{
    dimension_++;
    stateBytes_ = dimension_ * sizeof(double);
    bounds_.low.push_back(minBound);
    bounds_.high.push_back(maxBound);
    dimensionNames_.resize(dimension_, "");
}

void ompl::base::RealVectorStateManifold::setBounds(const RealVectorBounds &bounds)
{
    bounds.check();
    if (bounds.low.size() != dimension_)
        throw Exception("Bounds do not match dimension of manifold");
    bounds_ = bounds;
}

void ompl::base::RealVectorStateManifold::setBounds(double low, double high)
{
    RealVectorBounds bounds(dimension_);
    bounds.setLow(low);
    bounds.setHigh(high);
    setBounds(bounds);
}

unsigned int ompl::base::RealVectorStateManifold::getDimension(void) const
{
    return dimension_;
}

const std::string& ompl::base::RealVectorStateManifold::getDimensionName(unsigned int index) const
{
    if (index < dimensionNames_.size())
        return dimensionNames_[index];
    throw Exception("Index out of bounds");
}

int ompl::base::RealVectorStateManifold::getDimensionIndex(const std::string &name) const
{
    std::map<std::string, unsigned int>::const_iterator it = dimensionIndex_.find(name);
    return it != dimensionIndex_.end() ? it->second : -1;
}

void ompl::base::RealVectorStateManifold::setDimensionName(unsigned int index, const std::string &name)
{
    if (index < dimensionNames_.size())
    {
        dimensionNames_[index] = name;
        dimensionIndex_[name] = index;
    }
    else
        throw Exception("Cannot set dimension name. Index out of bounds");
}

double ompl::base::RealVectorStateManifold::getMaximumExtent(void) const
{
    double e = 0.0;
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
    {
        double d = bounds_.high[i] - bounds_.low[i];
        e += d*d;
    }
    return sqrt(e);
}

void ompl::base::RealVectorStateManifold::enforceBounds(State *state) const
{
    StateType *rstate = static_cast<StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
    {
        if (rstate->values[i] > bounds_.high[i])
            rstate->values[i] = bounds_.high[i];
        else
            if (rstate->values[i] < bounds_.low[i])
                rstate->values[i] = bounds_.low[i];
    }
}

bool ompl::base::RealVectorStateManifold::satisfiesBounds(const State *state) const
{
    const StateType *rstate = static_cast<const StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        if (rstate->values[i] - std::numeric_limits<double>::epsilon() > bounds_.high[i] ||
            rstate->values[i] + std::numeric_limits<double>::epsilon() < bounds_.low[i])
            return false;
    return true;
}

void ompl::base::RealVectorStateManifold::copyState(State *destination, const State *source) const
{
    memcpy(static_cast<StateType*>(destination)->values,
           static_cast<const StateType*>(source)->values, stateBytes_);
}

double ompl::base::RealVectorStateManifold::distance(const State *state1, const State *state2) const
{
    double dist = 0.0;
    const double *s1 = static_cast<const StateType*>(state1)->values;
    const double *s2 = static_cast<const StateType*>(state2)->values;

    for (unsigned int i = 0 ; i < dimension_ ; ++i)
    {
        double diff = (*s1++) - (*s2++);
        dist += diff * diff;
    }
    return sqrt(dist);
}

bool ompl::base::RealVectorStateManifold::equalStates(const State *state1, const State *state2) const
{
    const double *s1 = static_cast<const StateType*>(state1)->values;
    const double *s2 = static_cast<const StateType*>(state2)->values;
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
    {
        double diff = (*s1++) - (*s2++);
        if (fabs(diff) > std::numeric_limits<double>::epsilon() * 2.0)
            return false;
    }
    return true;
}

void ompl::base::RealVectorStateManifold::interpolate(const State *from, const State *to, const double t, State *state) const
{
    const StateType *rfrom = static_cast<const StateType*>(from);
    const StateType *rto = static_cast<const StateType*>(to);
    const StateType *rstate = static_cast<StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        rstate->values[i] = rfrom->values[i] + (rto->values[i] - rfrom->values[i]) * t;
}

ompl::base::ManifoldStateSamplerPtr ompl::base::RealVectorStateManifold::allocStateSampler(void) const
{
    return ManifoldStateSamplerPtr(new RealVectorStateSampler(this));
}

ompl::base::State* ompl::base::RealVectorStateManifold::allocState(void) const
{
    StateType *rstate = new StateType();
    rstate->values = new double[dimension_];
    return rstate;
}

void ompl::base::RealVectorStateManifold::freeState(State *state) const
{
    StateType *rstate = static_cast<StateType*>(state);
    delete[] rstate->values;
    delete rstate;
}

void ompl::base::RealVectorStateManifold::copyToReals(const State *state, std::vector<double> &reals) const
{
    reals.reserve(reals.size() + dimension_);
    const StateType *rstate = static_cast<const StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        reals.push_back(rstate->values[i]);
}

unsigned int ompl::base::RealVectorStateManifold::copyFromReals(State *state, const std::vector<double> &reals) const
{
    StateType *rstate = static_cast<StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        rstate->values[i] = reals[i];
    return dimension_;
}

void ompl::base::RealVectorStateManifold::printState(const State *state, std::ostream &out) const
{
    out << "RealVectorState [";
    if (state)
    {
        const StateType *rstate = static_cast<const StateType*>(state);
        for (unsigned int i = 0 ; i < dimension_ ; ++i)
        {
            out << rstate->values[i];
            if (i + 1 < dimension_)
                out << ' ';
        }
    }
    else
        out << "NULL" << std::endl;
    out << ']' << std::endl;
}

void ompl::base::RealVectorStateManifold::printSettings(std::ostream &out) const
{
    out << "Real vector state manifold '" << name_ << "' of dimension " << dimension_ << " with bounds: " << std::endl;
    out << "  - min: ";
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        out << bounds_.low[i] << " ";
    out << std::endl;
    out << "  - max: ";
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        out << bounds_.high[i] << " ";
    out << std::endl;
}
<commit_msg>print dimension names for real vector manifolds<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2010, Rice University
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Rice University nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Ioan Sucan */

#include "ompl/base/manifolds/RealVectorStateManifold.h"
#include "ompl/base/manifolds/RealVectorStateProjections.h"
#include "ompl/util/Exception.h"
#include <algorithm>
#include <cstring>
#include <limits>
#include <cmath>

void ompl::base::RealVectorStateSampler::sampleUniform(State *state)
{
    const unsigned int dim = manifold_->getDimension();
    const RealVectorBounds &bounds = static_cast<const RealVectorStateManifold*>(manifold_)->getBounds();

    RealVectorStateManifold::StateType *rstate = static_cast<RealVectorStateManifold::StateType*>(state);
    for (unsigned int i = 0 ; i < dim ; ++i)
        rstate->values[i] = rng_.uniformReal(bounds.low[i], bounds.high[i]);
}

void ompl::base::RealVectorStateSampler::sampleUniformNear(State *state, const State *near, const double distance)
{
    const unsigned int dim = manifold_->getDimension();
    const RealVectorBounds &bounds = static_cast<const RealVectorStateManifold*>(manifold_)->getBounds();

    RealVectorStateManifold::StateType *rstate = static_cast<RealVectorStateManifold::StateType*>(state);
    const RealVectorStateManifold::StateType *rnear = static_cast<const RealVectorStateManifold::StateType*>(near);
    for (unsigned int i = 0 ; i < dim ; ++i)
        rstate->values[i] =
            rng_.uniformReal(std::max(bounds.low[i], rnear->values[i] - distance),
                             std::min(bounds.high[i], rnear->values[i] + distance));
}

void ompl::base::RealVectorStateSampler::sampleGaussian(State *state, const State *mean, const double stdDev)
{
    const unsigned int dim = manifold_->getDimension();
    const RealVectorBounds &bounds = static_cast<const RealVectorStateManifold*>(manifold_)->getBounds();

    RealVectorStateManifold::StateType *rstate = static_cast<RealVectorStateManifold::StateType*>(state);
    const RealVectorStateManifold::StateType *rmean = static_cast<const RealVectorStateManifold::StateType*>(mean);
    for (unsigned int i = 0 ; i < dim ; ++i)
    {
        double v = rng_.gaussian(rmean->values[i], stdDev);
        if (v < bounds.low[i])
            v = bounds.low[i];
        else
            if (v > bounds.high[i])
                v = bounds.high[i];
        rstate->values[i] = v;
    }
}

void ompl::base::RealVectorStateManifold::registerProjections(void)
{
    // compute a default random projection
    if (dimension_ > 0)
    {
        if (dimension_ > 2)
        {
            int p = std::max(2, (int)ceil(log((double)dimension_)));
            registerDefaultProjection(ProjectionEvaluatorPtr(new RealVectorRandomLinearProjectionEvaluator(this, p)));
        }
        else
            registerDefaultProjection(ProjectionEvaluatorPtr(new RealVectorIdentityProjectionEvaluator(this)));
    }
}

void ompl::base::RealVectorStateManifold::setup(void)
{
    bounds_.check();
    StateManifold::setup();
}

void ompl::base::RealVectorStateManifold::addDimension(const std::string &name, double minBound, double maxBound)
{
    addDimension(minBound, maxBound);
    setDimensionName(dimension_ - 1, name);
}

void ompl::base::RealVectorStateManifold::addDimension(double minBound, double maxBound)
{
    dimension_++;
    stateBytes_ = dimension_ * sizeof(double);
    bounds_.low.push_back(minBound);
    bounds_.high.push_back(maxBound);
    dimensionNames_.resize(dimension_, "");
}

void ompl::base::RealVectorStateManifold::setBounds(const RealVectorBounds &bounds)
{
    bounds.check();
    if (bounds.low.size() != dimension_)
        throw Exception("Bounds do not match dimension of manifold");
    bounds_ = bounds;
}

void ompl::base::RealVectorStateManifold::setBounds(double low, double high)
{
    RealVectorBounds bounds(dimension_);
    bounds.setLow(low);
    bounds.setHigh(high);
    setBounds(bounds);
}

unsigned int ompl::base::RealVectorStateManifold::getDimension(void) const
{
    return dimension_;
}

const std::string& ompl::base::RealVectorStateManifold::getDimensionName(unsigned int index) const
{
    if (index < dimensionNames_.size())
        return dimensionNames_[index];
    throw Exception("Index out of bounds");
}

int ompl::base::RealVectorStateManifold::getDimensionIndex(const std::string &name) const
{
    std::map<std::string, unsigned int>::const_iterator it = dimensionIndex_.find(name);
    return it != dimensionIndex_.end() ? it->second : -1;
}

void ompl::base::RealVectorStateManifold::setDimensionName(unsigned int index, const std::string &name)
{
    if (index < dimensionNames_.size())
    {
        dimensionNames_[index] = name;
        dimensionIndex_[name] = index;
    }
    else
        throw Exception("Cannot set dimension name. Index out of bounds");
}

double ompl::base::RealVectorStateManifold::getMaximumExtent(void) const
{
    double e = 0.0;
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
    {
        double d = bounds_.high[i] - bounds_.low[i];
        e += d*d;
    }
    return sqrt(e);
}

void ompl::base::RealVectorStateManifold::enforceBounds(State *state) const
{
    StateType *rstate = static_cast<StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
    {
        if (rstate->values[i] > bounds_.high[i])
            rstate->values[i] = bounds_.high[i];
        else
            if (rstate->values[i] < bounds_.low[i])
                rstate->values[i] = bounds_.low[i];
    }
}

bool ompl::base::RealVectorStateManifold::satisfiesBounds(const State *state) const
{
    const StateType *rstate = static_cast<const StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        if (rstate->values[i] - std::numeric_limits<double>::epsilon() > bounds_.high[i] ||
            rstate->values[i] + std::numeric_limits<double>::epsilon() < bounds_.low[i])
            return false;
    return true;
}

void ompl::base::RealVectorStateManifold::copyState(State *destination, const State *source) const
{
    memcpy(static_cast<StateType*>(destination)->values,
           static_cast<const StateType*>(source)->values, stateBytes_);
}

double ompl::base::RealVectorStateManifold::distance(const State *state1, const State *state2) const
{
    double dist = 0.0;
    const double *s1 = static_cast<const StateType*>(state1)->values;
    const double *s2 = static_cast<const StateType*>(state2)->values;

    for (unsigned int i = 0 ; i < dimension_ ; ++i)
    {
        double diff = (*s1++) - (*s2++);
        dist += diff * diff;
    }
    return sqrt(dist);
}

bool ompl::base::RealVectorStateManifold::equalStates(const State *state1, const State *state2) const
{
    const double *s1 = static_cast<const StateType*>(state1)->values;
    const double *s2 = static_cast<const StateType*>(state2)->values;
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
    {
        double diff = (*s1++) - (*s2++);
        if (fabs(diff) > std::numeric_limits<double>::epsilon() * 2.0)
            return false;
    }
    return true;
}

void ompl::base::RealVectorStateManifold::interpolate(const State *from, const State *to, const double t, State *state) const
{
    const StateType *rfrom = static_cast<const StateType*>(from);
    const StateType *rto = static_cast<const StateType*>(to);
    const StateType *rstate = static_cast<StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        rstate->values[i] = rfrom->values[i] + (rto->values[i] - rfrom->values[i]) * t;
}

ompl::base::ManifoldStateSamplerPtr ompl::base::RealVectorStateManifold::allocStateSampler(void) const
{
    return ManifoldStateSamplerPtr(new RealVectorStateSampler(this));
}

ompl::base::State* ompl::base::RealVectorStateManifold::allocState(void) const
{
    StateType *rstate = new StateType();
    rstate->values = new double[dimension_];
    return rstate;
}

void ompl::base::RealVectorStateManifold::freeState(State *state) const
{
    StateType *rstate = static_cast<StateType*>(state);
    delete[] rstate->values;
    delete rstate;
}

void ompl::base::RealVectorStateManifold::copyToReals(const State *state, std::vector<double> &reals) const
{
    reals.reserve(reals.size() + dimension_);
    const StateType *rstate = static_cast<const StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        reals.push_back(rstate->values[i]);
}

unsigned int ompl::base::RealVectorStateManifold::copyFromReals(State *state, const std::vector<double> &reals) const
{
    StateType *rstate = static_cast<StateType*>(state);
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        rstate->values[i] = reals[i];
    return dimension_;
}

void ompl::base::RealVectorStateManifold::printState(const State *state, std::ostream &out) const
{
    out << "RealVectorState [";
    if (state)
    {
        const StateType *rstate = static_cast<const StateType*>(state);
        for (unsigned int i = 0 ; i < dimension_ ; ++i)
        {
            out << rstate->values[i];
            if (i + 1 < dimension_)
                out << ' ';
        }
    }
    else
        out << "NULL" << std::endl;
    out << ']' << std::endl;
}

void ompl::base::RealVectorStateManifold::printSettings(std::ostream &out) const
{
    out << "Real vector state manifold '" << name_ << "' of dimension " << dimension_ << " with bounds: " << std::endl;
    out << "  - min: ";
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        out << bounds_.low[i] << " ";
    out << std::endl;
    out << "  - max: ";
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
        out << bounds_.high[i] << " ";
    out << std::endl;

    bool printNames = false;
    for (unsigned int i = 0 ; i < dimension_ ; ++i)
	if (!dimensionNames_[i].empty())
	    printNames = true;
    if (printNames)
    {
	out << "  and dimension names: ";
	for (unsigned int i = 0 ; i < dimension_ ; ++i)
	    out << "'" << dimensionNames_[i] << "' ";
	out << std::endl;
    }
}
<|endoftext|>


<commit_before>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  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 reduce.inl
 *  \brief Inline file for reduce.h
 */

#pragma once

// do not attempt to compile this file with any other compiler
#ifdef __CUDACC__

#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/device_malloc.h>
#include <thrust/device_free.h>
#include <thrust/reduce.h>  // for second level reduction

#include <thrust/detail/device/cuda/block/reduce.h>

namespace thrust
{

namespace detail
{

namespace device
{

namespace cuda
{

/*
 * Reduction using a single thread.  Only used for small vectors.
 *
 */
template<typename InputFunctor,
         typename OutputType,
         typename BinaryFunction>
  __global__ void
  __thrust__serial_reduce_kernel(InputFunctor input,
                                  const size_t n,
                                  OutputType * block_results,
                                  BinaryFunction binary_op)
{
    if( threadIdx.x == 0 )
    {
        OutputType accum = input[0];
        for(unsigned int i = 1; i < n; i++){
            accum = binary_op(accum, input[i]);
        }
        block_results[0] = accum;
    }

} // end __thrust__serial_reduce_kernel()

/*
 * Reduce a vector of n elements using binary_op(op())
 *
 * The order of reduction is not defined, so binary_op() should
 * be a commutative (and associative) operator such as
 * (integer) addition.  Since floating point operations
 * do not completely satisfy these criteria, the result is
 * generally not the same as a consecutive reduction of
 * the elements.
 *
 * Uses the same pattern as reduce6() in the CUDA SDK
 *
 */
template<typename InputFunctor,
         typename OutputType,
         typename BinaryFunction,
         unsigned int BLOCK_SIZE>
  __global__ void
  __thrust__unordered_reduce_kernel(InputFunctor input,
                                     const unsigned int n,
                                     OutputType * block_results,
                                     BinaryFunction binary_op)
{
    __shared__ unsigned char sdata_workaround[BLOCK_SIZE * sizeof(OutputType)];
    OutputType *sdata = reinterpret_cast<OutputType*>(sdata_workaround);

    // perform first level of reduction,
    // write per-block results to global memory for second level reduction

    const unsigned int grid_size = BLOCK_SIZE * gridDim.x;
    unsigned int i = blockIdx.x * BLOCK_SIZE + threadIdx.x;

    // accumulate local result
    OutputType accum = input[i];
    i += grid_size;

    while (i < n)
    {
        accum = binary_op(accum, input[i]);
        i += grid_size;
    }

    // copy local result to shared mem and perform reduction
    sdata[threadIdx.x] = accum;

    __syncthreads(); // wait for all writes to finish

    if (BLOCK_SIZE >= 512) { if (threadIdx.x < 256) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x + 256]); } __syncthreads(); }
    if (BLOCK_SIZE >= 256) { if (threadIdx.x < 128) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x + 128]); } __syncthreads(); }
    if (BLOCK_SIZE >= 128) { if (threadIdx.x <  64) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +  64]); } __syncthreads(); }
    if (BLOCK_SIZE >=  64) { if (threadIdx.x <  32) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +  32]); } __syncthreads(); }
    if (BLOCK_SIZE >=  32) { if (threadIdx.x <  16) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +  16]); } __syncthreads(); }

    if (BLOCK_SIZE >=  16) { if (threadIdx.x <   8) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +   8]); } __syncthreads(); }
    if (BLOCK_SIZE >=   8) { if (threadIdx.x <   4) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +   4]); } __syncthreads(); }
    if (BLOCK_SIZE >=   4) { if (threadIdx.x <   2) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +   2]); } __syncthreads(); }
    if (BLOCK_SIZE >=   2) { if (threadIdx.x <   1) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +   1]); } __syncthreads(); }

    // XXX causes the following problem on CUDA 2.2 (Komrade issue #6)
    //     Advisory: Cannot tell what pointer points to, assuming global memory space
    //accum = thrust::detail::block::reduce<OutputType,BinaryFunction,BLOCK_SIZE>
    //    (sdata, threadIdx.x, binary_op);

    // write result for this block to global mem
    if (threadIdx.x == 0)
        block_results[blockIdx.x] = sdata[threadIdx.x];

} // end __thrust__unordered_reduce_kernel()

template<typename InputFunctor,
         typename OutputType,
         typename BinaryFunction>
  OutputType reduce(InputFunctor input,
                    const size_t n,
                    const OutputType init,
                    BinaryFunction binary_op)
{
    const size_t BLOCK_SIZE = 256;  // BLOCK_SIZE must be a power of 2
    const size_t MAX_BLOCKS = 3 * experimental::arch::max_active_threads() / BLOCK_SIZE;

    unsigned int GRID_SIZE;

    // handle zero length array case first
    if( n == 0 )
        return init;

    // TODO if n < UINT_MAX use unsigned int instead of size_t indices in kernel

    // kernels below assume n > 0
    if( n < BLOCK_SIZE )
    {
        GRID_SIZE = 1;
    }
    else
    {
        GRID_SIZE = std::min( (n / BLOCK_SIZE), MAX_BLOCKS);
    }

    // allocate storage for per-block results
    thrust::device_ptr<OutputType> block_results = thrust::device_malloc<OutputType>(GRID_SIZE);

    // do the gpu part
    if( n < BLOCK_SIZE )
    {
        __thrust__serial_reduce_kernel<InputFunctor, OutputType, BinaryFunction>
            <<<GRID_SIZE, 1>>>(input, n, block_results.get(), binary_op);
    }
    else
    {
        __thrust__unordered_reduce_kernel<InputFunctor, OutputType, BinaryFunction, BLOCK_SIZE>
            <<<GRID_SIZE, BLOCK_SIZE>>>(input, n, block_results.get(), binary_op);
    }

    // copy work array to host
    thrust::host_vector<OutputType> host_work(block_results, block_results + GRID_SIZE);

    // free device work array
    thrust::device_free(block_results);

    // reduce on the host
    return thrust::reduce(host_work.begin(), host_work.end(), init, binary_op);
} // end reduce()

} // end namespace cuda

} // end namespace device

} // end namespace detail

} // end namespace thrust

#endif // __CUDACC__

<commit_msg>Use raw_buffer in reduce.<commit_after>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  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 reduce.inl
 *  \brief Inline file for reduce.h
 */

#pragma once

// do not attempt to compile this file with any other compiler
#ifdef __CUDACC__

#include <thrust/iterator/iterator_traits.h>
#include <thrust/detail/raw_buffer.h>
#include <thrust/reduce.h>  // for second level reduction

#include <thrust/detail/device/cuda/block/reduce.h>

namespace thrust
{

namespace detail
{

namespace device
{

namespace cuda
{

/*
 * Reduction using a single thread.  Only used for small vectors.
 *
 */
template<typename InputFunctor,
         typename OutputType,
         typename BinaryFunction>
  __global__ void
  __thrust__serial_reduce_kernel(InputFunctor input,
                                  const size_t n,
                                  OutputType * block_results,
                                  BinaryFunction binary_op)
{
    if( threadIdx.x == 0 )
    {
        OutputType accum = input[0];
        for(unsigned int i = 1; i < n; i++){
            accum = binary_op(accum, input[i]);
        }
        block_results[0] = accum;
    }

} // end __thrust__serial_reduce_kernel()

/*
 * Reduce a vector of n elements using binary_op(op())
 *
 * The order of reduction is not defined, so binary_op() should
 * be a commutative (and associative) operator such as
 * (integer) addition.  Since floating point operations
 * do not completely satisfy these criteria, the result is
 * generally not the same as a consecutive reduction of
 * the elements.
 *
 * Uses the same pattern as reduce6() in the CUDA SDK
 *
 */
template<typename InputFunctor,
         typename OutputType,
         typename BinaryFunction,
         unsigned int BLOCK_SIZE>
  __global__ void
  __thrust__unordered_reduce_kernel(InputFunctor input,
                                     const unsigned int n,
                                     OutputType * block_results,
                                     BinaryFunction binary_op)
{
    __shared__ unsigned char sdata_workaround[BLOCK_SIZE * sizeof(OutputType)];
    OutputType *sdata = reinterpret_cast<OutputType*>(sdata_workaround);

    // perform first level of reduction,
    // write per-block results to global memory for second level reduction

    const unsigned int grid_size = BLOCK_SIZE * gridDim.x;
    unsigned int i = blockIdx.x * BLOCK_SIZE + threadIdx.x;

    // accumulate local result
    OutputType accum = input[i];
    i += grid_size;

    while (i < n)
    {
        accum = binary_op(accum, input[i]);
        i += grid_size;
    }

    // copy local result to shared mem and perform reduction
    sdata[threadIdx.x] = accum;

    __syncthreads(); // wait for all writes to finish

    if (BLOCK_SIZE >= 512) { if (threadIdx.x < 256) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x + 256]); } __syncthreads(); }
    if (BLOCK_SIZE >= 256) { if (threadIdx.x < 128) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x + 128]); } __syncthreads(); }
    if (BLOCK_SIZE >= 128) { if (threadIdx.x <  64) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +  64]); } __syncthreads(); }
    if (BLOCK_SIZE >=  64) { if (threadIdx.x <  32) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +  32]); } __syncthreads(); }
    if (BLOCK_SIZE >=  32) { if (threadIdx.x <  16) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +  16]); } __syncthreads(); }

    if (BLOCK_SIZE >=  16) { if (threadIdx.x <   8) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +   8]); } __syncthreads(); }
    if (BLOCK_SIZE >=   8) { if (threadIdx.x <   4) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +   4]); } __syncthreads(); }
    if (BLOCK_SIZE >=   4) { if (threadIdx.x <   2) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +   2]); } __syncthreads(); }
    if (BLOCK_SIZE >=   2) { if (threadIdx.x <   1) { sdata[threadIdx.x] = binary_op(sdata[threadIdx.x], sdata[threadIdx.x +   1]); } __syncthreads(); }

    // XXX causes the following problem on CUDA 2.2 (Komrade issue #6)
    //     Advisory: Cannot tell what pointer points to, assuming global memory space
    //accum = thrust::detail::block::reduce<OutputType,BinaryFunction,BLOCK_SIZE>
    //    (sdata, threadIdx.x, binary_op);

    // write result for this block to global mem
    if (threadIdx.x == 0)
        block_results[blockIdx.x] = sdata[threadIdx.x];

} // end __thrust__unordered_reduce_kernel()

template<typename InputFunctor,
         typename OutputType,
         typename BinaryFunction>
  OutputType reduce(InputFunctor input,
                    const size_t n,
                    const OutputType init,
                    BinaryFunction binary_op)
{
    const size_t BLOCK_SIZE = 256;  // BLOCK_SIZE must be a power of 2
    const size_t MAX_BLOCKS = 3 * experimental::arch::max_active_threads() / BLOCK_SIZE;

    unsigned int GRID_SIZE;

    // handle zero length array case first
    if( n == 0 )
        return init;

    // TODO if n < UINT_MAX use unsigned int instead of size_t indices in kernel

    // kernels below assume n > 0
    if( n < BLOCK_SIZE )
    {
        GRID_SIZE = 1;
    }
    else
    {
        GRID_SIZE = std::min( (n / BLOCK_SIZE), MAX_BLOCKS);
    }

    // allocate storage for per-block results
    raw_buffer<OutputType, experimental::space::device> block_results(GRID_SIZE);

    // do the gpu part
    if( n < BLOCK_SIZE )
    {
        __thrust__serial_reduce_kernel<InputFunctor, OutputType, BinaryFunction>
            <<<GRID_SIZE, 1>>>(input, n, raw_pointer_cast(&block_results[0]), binary_op);
    }
    else
    {
        __thrust__unordered_reduce_kernel<InputFunctor, OutputType, BinaryFunction, BLOCK_SIZE>
            <<<GRID_SIZE, BLOCK_SIZE>>>(input, n, raw_pointer_cast(&block_results[0]), binary_op);
    }

    // copy work array to host
    raw_buffer<OutputType, experimental::space::host> host_work(block_results.begin(), block_results.end());

    // reduce on the host
    return thrust::reduce(host_work.begin(), host_work.end(), init, binary_op);
} // end reduce()

} // end namespace cuda

} // end namespace device

} // end namespace detail

} // end namespace thrust

#endif // __CUDACC__

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <ZipPackageEntry.hxx>
#include <com/sun/star/packages/zip/ZipConstants.hpp>
#include <osl/diagnose.h>

#include <ZipPackageFolder.hxx>
#include <ZipPackageStream.hxx>
#include <ContentInfo.hxx>

#include <comphelper/storagehelper.hxx>

using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::packages::zip;
using namespace com::sun::star::packages::zip::ZipConstants;

#if OSL_DEBUG_LEVEL > 0
#define THROW_WHERE SAL_WHERE
#else
#define THROW_WHERE ""
#endif

ZipPackageEntry::ZipPackageEntry()
: mbIsFolder( false )
, mpParent ( NULL )
{
}

ZipPackageEntry::~ZipPackageEntry()
{
    // When the entry is destroyed it must be already disconnected from the parent
    OSL_ENSURE( !mpParent, "The parent must be disconnected already! Memory corruption is possible!\n" );
}

// XChild
OUString SAL_CALL ZipPackageEntry::getName(  )
    throw(RuntimeException, std::exception)
{
    return msName;
}
void SAL_CALL ZipPackageEntry::setName( const OUString& aName )
    throw(RuntimeException, std::exception)
{
    if ( mpParent && !msName.isEmpty() && mpParent->hasByName ( msName ) )
        mpParent->removeByName ( msName );

    // unfortunately no other exception than RuntimeException can be thrown here
    // usually the package is used through storage implementation, the problem should be detected there
    if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, true ) )
        throw RuntimeException(THROW_WHERE "Unexpected character is used in file name." );

    msName = aName;

    if ( mpParent )
        mpParent->doInsertByName ( this, false );
}
uno::Reference< XInterface > SAL_CALL ZipPackageEntry::getParent(  )
        throw(RuntimeException, std::exception)
{
    // return uno::Reference< XInterface >( xParent, UNO_QUERY );
    return uno::Reference< XInterface >( static_cast< ::cppu::OWeakObject* >( mpParent ), UNO_QUERY );
}

void ZipPackageEntry::doSetParent ( ZipPackageFolder * pNewParent, bool bInsert )
{
    // xParent = mpParent = pNewParent;
    mpParent = pNewParent;
    if ( bInsert && !msName.isEmpty() && !pNewParent->hasByName ( msName ) )
        pNewParent->doInsertByName ( this, false );
}

void SAL_CALL ZipPackageEntry::setParent( const uno::Reference< XInterface >& xNewParent )
        throw(NoSupportException, RuntimeException, std::exception)
{
    sal_Int64 nTest(0);
    uno::Reference < XUnoTunnel > xTunnel ( xNewParent, UNO_QUERY );
    if ( !xNewParent.is() || ( nTest = xTunnel->getSomething ( ZipPackageFolder::static_getImplementationId () ) ) == 0 )
        throw NoSupportException(THROW_WHERE );

    ZipPackageFolder *pNewParent = reinterpret_cast < ZipPackageFolder * > ( nTest );

    if ( pNewParent != mpParent )
    {
        if ( mpParent && !msName.isEmpty() && mpParent->hasByName ( msName ) && mbAllowRemoveOnInsert )
            mpParent->removeByName( msName );
        doSetParent ( pNewParent, true );
    }
}
    //XPropertySet
uno::Reference< beans::XPropertySetInfo > SAL_CALL ZipPackageEntry::getPropertySetInfo(  )
        throw(RuntimeException, std::exception)
{
    return uno::Reference < beans::XPropertySetInfo > ();
}
void SAL_CALL ZipPackageEntry::addPropertyChangeListener( const OUString& /*aPropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
        throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
{
}
void SAL_CALL ZipPackageEntry::removePropertyChangeListener( const OUString& /*aPropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
        throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
{
}
void SAL_CALL ZipPackageEntry::addVetoableChangeListener( const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
        throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
{
}
void SAL_CALL ZipPackageEntry::removeVetoableChangeListener( const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
        throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
{
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>cid#1249676 Uninitialized scalar field<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <ZipPackageEntry.hxx>
#include <com/sun/star/packages/zip/ZipConstants.hpp>
#include <osl/diagnose.h>

#include <ZipPackageFolder.hxx>
#include <ZipPackageStream.hxx>
#include <ContentInfo.hxx>

#include <comphelper/storagehelper.hxx>

using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::packages::zip;
using namespace com::sun::star::packages::zip::ZipConstants;

#if OSL_DEBUG_LEVEL > 0
#define THROW_WHERE SAL_WHERE
#else
#define THROW_WHERE ""
#endif

ZipPackageEntry::ZipPackageEntry()
: mbIsFolder( false )
, mbAllowRemoveOnInsert(false)
, mpParent ( NULL )
, m_nFormat(0)
{
}

ZipPackageEntry::~ZipPackageEntry()
{
    // When the entry is destroyed it must be already disconnected from the parent
    OSL_ENSURE( !mpParent, "The parent must be disconnected already! Memory corruption is possible!\n" );
}

// XChild
OUString SAL_CALL ZipPackageEntry::getName(  )
    throw(RuntimeException, std::exception)
{
    return msName;
}
void SAL_CALL ZipPackageEntry::setName( const OUString& aName )
    throw(RuntimeException, std::exception)
{
    if ( mpParent && !msName.isEmpty() && mpParent->hasByName ( msName ) )
        mpParent->removeByName ( msName );

    // unfortunately no other exception than RuntimeException can be thrown here
    // usually the package is used through storage implementation, the problem should be detected there
    if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, true ) )
        throw RuntimeException(THROW_WHERE "Unexpected character is used in file name." );

    msName = aName;

    if ( mpParent )
        mpParent->doInsertByName ( this, false );
}
uno::Reference< XInterface > SAL_CALL ZipPackageEntry::getParent(  )
        throw(RuntimeException, std::exception)
{
    // return uno::Reference< XInterface >( xParent, UNO_QUERY );
    return uno::Reference< XInterface >( static_cast< ::cppu::OWeakObject* >( mpParent ), UNO_QUERY );
}

void ZipPackageEntry::doSetParent ( ZipPackageFolder * pNewParent, bool bInsert )
{
    // xParent = mpParent = pNewParent;
    mpParent = pNewParent;
    if ( bInsert && !msName.isEmpty() && !pNewParent->hasByName ( msName ) )
        pNewParent->doInsertByName ( this, false );
}

void SAL_CALL ZipPackageEntry::setParent( const uno::Reference< XInterface >& xNewParent )
        throw(NoSupportException, RuntimeException, std::exception)
{
    sal_Int64 nTest(0);
    uno::Reference < XUnoTunnel > xTunnel ( xNewParent, UNO_QUERY );
    if ( !xNewParent.is() || ( nTest = xTunnel->getSomething ( ZipPackageFolder::static_getImplementationId () ) ) == 0 )
        throw NoSupportException(THROW_WHERE );

    ZipPackageFolder *pNewParent = reinterpret_cast < ZipPackageFolder * > ( nTest );

    if ( pNewParent != mpParent )
    {
        if ( mpParent && !msName.isEmpty() && mpParent->hasByName ( msName ) && mbAllowRemoveOnInsert )
            mpParent->removeByName( msName );
        doSetParent ( pNewParent, true );
    }
}
    //XPropertySet
uno::Reference< beans::XPropertySetInfo > SAL_CALL ZipPackageEntry::getPropertySetInfo(  )
        throw(RuntimeException, std::exception)
{
    return uno::Reference < beans::XPropertySetInfo > ();
}
void SAL_CALL ZipPackageEntry::addPropertyChangeListener( const OUString& /*aPropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
        throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
{
}
void SAL_CALL ZipPackageEntry::removePropertyChangeListener( const OUString& /*aPropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
        throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
{
}
void SAL_CALL ZipPackageEntry::addVetoableChangeListener( const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
        throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
{
}
void SAL_CALL ZipPackageEntry::removeVetoableChangeListener( const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
        throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
{
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include "multi_dimension_array.h"
#include <vector>
using std::vector;

#include <stdio.h>
#include <sys/time.h>

int main()
{
    size_t size = 2;
    const size_t rowlen = 5000;
    vector<size_t> dims;
    dims.resize(size, rowlen);

    vector<size_t> position;
    position.resize(size, 0);

    double **raw_array = new double*[rowlen];
    double *flat_array = new double[rowlen * rowlen];
    for (size_t i = 0; i < rowlen; ++i) {
        raw_array[i] = new double[rowlen];
        for (size_t j = 0; j < rowlen; ++j) {
            raw_array[i][j] = 42.0;

            flat_array[i * rowlen + j] = 42.0;
        }
    }
    MultiDimensionArray<double> array(dims, 42.0);

    // ===== RAW ARRAY ===== //

    struct timeval begin, end, diff;
    gettimeofday(&begin, NULL);
    double sum = 0.0;
    for (size_t i = 0; i < rowlen; ++i) {
        for (size_t j = 0; j < rowlen; ++j) {
            sum += raw_array[i][j];
        }
    }
    gettimeofday(&end, NULL);
    diff.tv_sec = end.tv_sec - begin.tv_sec;
    if (end.tv_usec < begin.tv_usec) {
        --diff.tv_sec;
        end.tv_usec += 1000000;
    }
    diff.tv_usec = end.tv_usec - begin.tv_usec;
    double seconds = diff.tv_sec + (diff.tv_usec / 1000000.0);

    fprintf(stderr, "raw array took %f seconds; sum=%f\n", seconds, sum);

    // ===== FLAT ARRAY ===== //

    gettimeofday(&begin, NULL);
    sum = 0.0;
    for (size_t i = 0; i < rowlen; ++i) {
        for (size_t j = 0; j < rowlen; ++j) {
            sum += flat_array[i * rowlen + j];
        }
    }
    gettimeofday(&end, NULL);
    diff.tv_sec = end.tv_sec - begin.tv_sec;
    if (end.tv_usec < begin.tv_usec) {
        --diff.tv_sec;
        end.tv_usec += 1000000;
    }
    diff.tv_usec = end.tv_usec - begin.tv_usec;
    seconds = diff.tv_sec + (diff.tv_usec / 1000000.0);

    fprintf(stderr, "flat array took %f seconds; sum=%f\n", seconds, sum);

    // ===== MultiDimensionArray ===== //

    gettimeofday(&begin, NULL);
    sum = 0.0;
    for (size_t i = 0; i < rowlen; ++i) {
        position[0] = i;
        for (size_t j = 0; j < rowlen; ++j) {
            position[1] = j;
            sum += array.at(position);
        }
    }
    gettimeofday(&end, NULL);
    diff.tv_sec = end.tv_sec - begin.tv_sec;
    if (end.tv_usec < begin.tv_usec) {
        --diff.tv_sec;
        end.tv_usec += 1000000;
    }
    diff.tv_usec = end.tv_usec - begin.tv_usec;
    seconds = diff.tv_sec + (diff.tv_usec / 1000000.0);

    fprintf(stderr, "MultiDimensionArray took %f seconds; sum=%f\n", seconds, sum);
    return 0;
}
<commit_msg>Added boost array test.<commit_after>#include "multi_dimension_array.h"
#include <vector>
using std::vector;

#include <stdio.h>
#include <sys/time.h>

#include <boost/multi_array.hpp>

int main()
{
    size_t size = 2;
    const size_t rowlen = 5000;
    vector<size_t> dims;
    dims.resize(size, rowlen);

    vector<size_t> position;
    position.resize(size, 0);

    double **raw_array = new double*[rowlen];
    double *flat_array = new double[rowlen * rowlen];
    boost::multi_array<double, 2> boost_array(boost::extents[rowlen][rowlen]);
    for (size_t i = 0; i < rowlen; ++i) {
        raw_array[i] = new double[rowlen];
        for (size_t j = 0; j < rowlen; ++j) {
            raw_array[i][j] = 42.0;
            flat_array[i * rowlen + j] = 42.0;
            boost_array[i][j] = 42.0;
        }
    }
    MultiDimensionArray<double> array(dims, 42.0);

    // ===== RAW ARRAY ===== //

    struct timeval begin, end, diff;
    gettimeofday(&begin, NULL);
    double sum = 0.0;
    for (size_t i = 0; i < rowlen; ++i) {
        for (size_t j = 0; j < rowlen; ++j) {
            sum += raw_array[i][j];
        }
    }
    gettimeofday(&end, NULL);
    diff.tv_sec = end.tv_sec - begin.tv_sec;
    if (end.tv_usec < begin.tv_usec) {
        --diff.tv_sec;
        end.tv_usec += 1000000;
    }
    diff.tv_usec = end.tv_usec - begin.tv_usec;
    double seconds = diff.tv_sec + (diff.tv_usec / 1000000.0);

    fprintf(stderr, "raw array took %f seconds; sum=%f\n", seconds, sum);

    // ===== FLAT ARRAY ===== //

    gettimeofday(&begin, NULL);
    sum = 0.0;
    for (size_t i = 0; i < rowlen; ++i) {
        for (size_t j = 0; j < rowlen; ++j) {
            sum += flat_array[i * rowlen + j];
        }
    }
    gettimeofday(&end, NULL);
    diff.tv_sec = end.tv_sec - begin.tv_sec;
    if (end.tv_usec < begin.tv_usec) {
        --diff.tv_sec;
        end.tv_usec += 1000000;
    }
    diff.tv_usec = end.tv_usec - begin.tv_usec;
    seconds = diff.tv_sec + (diff.tv_usec / 1000000.0);

    fprintf(stderr, "flat array took %f seconds; sum=%f\n", seconds, sum);

    // ===== MultiDimensionArray ===== //

    gettimeofday(&begin, NULL);
    sum = 0.0;
    for (size_t i = 0; i < rowlen; ++i) {
        position[0] = i;
        for (size_t j = 0; j < rowlen; ++j) {
            position[1] = j;
            sum += array.at(position);
        }
    }
    gettimeofday(&end, NULL);
    diff.tv_sec = end.tv_sec - begin.tv_sec;
    if (end.tv_usec < begin.tv_usec) {
        --diff.tv_sec;
        end.tv_usec += 1000000;
    }
    diff.tv_usec = end.tv_usec - begin.tv_usec;
    seconds = diff.tv_sec + (diff.tv_usec / 1000000.0);

    fprintf(stderr, "MultiDimensionArray took %f seconds; sum=%f\n", seconds, sum);

    // ===== boost::multi_array ===== //

    gettimeofday(&begin, NULL);
    sum = 0.0;
    for (size_t i = 0; i < rowlen; ++i) {
        for (size_t j = 0; j < rowlen; ++j) {
            sum += boost_array[i][j];
        }
    }
    gettimeofday(&end, NULL);
    diff.tv_sec = end.tv_sec - begin.tv_sec;
    if (end.tv_usec < begin.tv_usec) {
        --diff.tv_sec;
        end.tv_usec += 1000000;
    }
    diff.tv_usec = end.tv_usec - begin.tv_usec;
    seconds = diff.tv_sec + (diff.tv_usec / 1000000.0);

    fprintf(stderr, "boost::multi_array took %f seconds; sum=%f\n", seconds, sum);

    return 0;
}
<|endoftext|>


<commit_before>// MouseSensitivityTweak.cpp : Defines the entry point for the console application.
//

#include <Windows.h>
#include <tchar.h>

#define MIN_SPEED        1
#define MAX_SPEED        20
#define DEF_SPEED        10

BOOL IsSpeedValid(int nSpeed) {
    return ((nSpeed >= MIN_SPEED) && (nSpeed <= MAX_SPEED)) ? TRUE : FALSE;
}

int GetMouseSpeed() {
    int nSpeed = 0;
    BOOL fResult = SystemParametersInfo(SPI_GETMOUSESPEED,  // Get mouse information
                                        0,                  // Not used
										&nSpeed,            // Holds mouse speed
										0);

    if (!fResult || !IsSpeedValid(nSpeed)) {
        return -1;
    }
    return nSpeed;
}

BOOL SetMouseSpeed(int nSpeed) {
    if (!IsSpeedValid(nSpeed)) {
        return FALSE;
    }

    int nOldSpeed = GetMouseSpeed();
    if (nOldSpeed == nSpeed) {
        return TRUE;
    }

    BOOL fResult = SystemParametersInfo(SPI_SETMOUSESPEED,  // Get mouse information
                                        0,                  // Not used
										PVOID(nSpeed),      // Holds mouse speed
										SPIF_SENDCHANGE);   // Broadcasts the WM_SETTINGCHANGE message

    return fResult;
}

// Usage MouseSensitivityTweak <speed>
// Ex:
// MouseSensitivityTweak 16
int _tmain(int argc, _TCHAR* argv[])
{
    int nSpeed = DEF_SPEED;

    if (argc != 2) {
        return 0;
    }

    nSpeed = _wtoi(argv[1]);
    return SetMouseSpeed(nSpeed);
}<commit_msg>Remove tabs<commit_after>// MouseSensitivityTweak.cpp : Defines the entry point for the console application.
//

#include <Windows.h>
#include <tchar.h>

#define MIN_SPEED        1
#define MAX_SPEED        20
#define DEF_SPEED        10

BOOL IsSpeedValid(int nSpeed) {
    return ((nSpeed >= MIN_SPEED) && (nSpeed <= MAX_SPEED)) ? TRUE : FALSE;
}

int GetMouseSpeed() {
    int nSpeed = 0;
    BOOL fResult = SystemParametersInfo(SPI_GETMOUSESPEED,  // Get mouse information
                                        0,                  // Not used
                                        &nSpeed,            // Holds mouse speed
                                        0);

    if (!fResult || !IsSpeedValid(nSpeed)) {
        return -1;
    }
    return nSpeed;
}

BOOL SetMouseSpeed(int nSpeed) {
    if (!IsSpeedValid(nSpeed)) {
        return FALSE;
    }

    int nOldSpeed = GetMouseSpeed();
    if (nOldSpeed == nSpeed) {
        return TRUE;
    }

    BOOL fResult = SystemParametersInfo(SPI_SETMOUSESPEED,  // Get mouse information
                                        0,                  // Not used
                                        PVOID(nSpeed),      // Holds mouse speed
                                        SPIF_SENDCHANGE);   // Broadcasts the WM_SETTINGCHANGE message

    return fResult;
}

// Usage MouseSensitivityTweak <speed>
// Ex:
// MouseSensitivityTweak 16
int _tmain(int argc, _TCHAR* argv[])
{
    int nSpeed = DEF_SPEED;

    if (argc != 2) {
        return 0;
    }

    nSpeed = _wtoi(argv[1]);
    return SetMouseSpeed(nSpeed);
}<|endoftext|>


<commit_before>/***************************************************************************
 * Copyright 1998-2013 by authors (see AUTHORS.txt)                        *
 *                                                                         *
 *   This file is part of LuxRender.                                       *
 *                                                                         *
 * Licensed under the Apache License, Version 2.0 (the "License");         *
 * you may not use this file except in compliance with the License.        *
 * You may obtain a copy of the License at                                 *
 *                                                                         *
 *     http://www.apache.org/licenses/LICENSE-2.0                          *
 *                                                                         *
 * Unless required by applicable law or agreed to in writing, software     *
 * distributed under the License is distributed on an "AS IS" BASIS,       *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*
 * See the License for the specific language governing permissions and     *
 * limitations under the License.                                          *
 ***************************************************************************/

#include "boost/format.hpp"

#include "slg/engines/bidirvmcpu/bidirvmcpu.h"

using namespace std;
using namespace luxrays;
using namespace slg;

void HashGrid::Build(vector<vector<PathVertexVM> > &pathsVertices, const float radius) {
	// Reset statistic counters
	//mergeHitsV2V = 0;
	//mergeHitsV2S = 0;
	//mergeHitsS2S = 0;

	radius2 = radius * radius;

	// Build the vertices bounding box
	vertexCount = 0;
	vertexBBox = BBox();
	for (u_int i = 0; i < pathsVertices.size(); ++i) {
		vertexCount += pathsVertices[i].size();

		for (u_int j = 0; j < pathsVertices[i].size(); ++j)
			vertexBBox = Union(vertexBBox, pathsVertices[i][j].bsdf.hitPoint.p);
	}

	if (vertexCount <= 0)
		return;

	vertexBBox.Expand(radius + DEFAULT_EPSILON_STATIC);

	// Calculate the size of the grid cell
	const float cellSize = radius * 2.f;
	invCellSize = 1.f / cellSize;

	gridSize = vertexCount;
	cellEnds.resize(gridSize);
	fill(cellEnds.begin(), cellEnds.end(), 0);
	lightVertices.resize(gridSize, NULL);

	for (u_int i = 0, k = 0; i < pathsVertices.size(); ++i) {
		for (u_int j = 0; j < pathsVertices[i].size(); ++j, ++k) {
			const PathVertexVM *vertex = &pathsVertices[i][j];

			cellEnds[Hash(vertex->bsdf.hitPoint.p)]++;
		}
	}

	int sum = 0;
	for (u_int i = 0; i < cellEnds.size(); ++i) {
		int temp = cellEnds[i];
		cellEnds[i] = sum;
		sum += temp;
	}

	for (u_int i = 0; i < pathsVertices.size(); ++i) {
		for (u_int j = 0; j < pathsVertices[i].size(); ++j) {
			const PathVertexVM *vertex = &pathsVertices[i][j];

			const int targetIdx = cellEnds[Hash(vertex->bsdf.hitPoint.p)]++;
            lightVertices[targetIdx] = vertex;
		}
	}
}

void HashGrid::Process(const BiDirVMCPURenderThread *thread,
		const PathVertexVM &eyeVertex, Spectrum *radiance) const {
	if ((vertexCount <= 0) ||
			!vertexBBox.Inside(eyeVertex.bsdf.hitPoint.p))
		return;

	const Vector distMin = eyeVertex.bsdf.hitPoint.p - vertexBBox.pMin;
	const Vector cellPoint = invCellSize * distMin;
	const Vector coordFloor(floorf(cellPoint.x), floorf(cellPoint.y), floorf(cellPoint.z));

	const int px = int(coordFloor.x);
	const int py = int(coordFloor.y);
	const int pz = int(coordFloor.z);

	const Vector fractCoord = cellPoint - coordFloor;

	const int pxo = px + ((fractCoord.x < .5f) ? -1 : +1);
	const int pyo = py + ((fractCoord.y < .5f) ? -1 : +1);
	const int pzo = pz + ((fractCoord.z < .5f) ? -1 : +1);

	int i0, i1;
	HashRange(Hash(px, py, pz), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(px, py, pzo), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(px, pyo, pz), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(px, pyo, pzo), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(pxo, py, pz), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(pxo, py, pzo), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(pxo, pyo, pz), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(pxo, pyo, pzo), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
}

void HashGrid::Process(const BiDirVMCPURenderThread *thread,
		const PathVertexVM &eyeVertex, const int i0, const int i1,
		Spectrum *radiance) const {
	for (int i = i0; i < i1; ++i) {
		const PathVertexVM *lightVertex = lightVertices[i];
		Process(thread, eyeVertex, lightVertex, radiance);
	}
}

void HashGrid::Process(const BiDirVMCPURenderThread *thread,
		const PathVertexVM &eyeVertex, const PathVertexVM *lightVertex,
		Spectrum *radiance) const {
	const float distance2 = (lightVertex->bsdf.hitPoint.p - eyeVertex.bsdf.hitPoint.p).LengthSquared();

	if (distance2 <= radius2) {
		float eyeBsdfPdfW, eyeBsdfRevPdfW;
		BSDFEvent eyeEvent;
		// I need to remove the dotN term from the result (see below)
		Spectrum eyeBsdfEval = eyeVertex.bsdf.Evaluate(lightVertex->bsdf.hitPoint.fixedDir,
				&eyeEvent, &eyeBsdfPdfW, &eyeBsdfRevPdfW);
		if(eyeBsdfEval.Black())
			return;

		// Volume BSDF doesn't multiply BSDF::Evaluate() by dotN so I need
		// to remove the term only if it isn't a Volume
		if (!eyeVertex.bsdf.IsVolume())
			eyeBsdfEval /= AbsDot(lightVertex->bsdf.hitPoint.fixedDir, eyeVertex.bsdf.hitPoint.geometryN);

		BiDirVMCPURenderEngine *engine = (BiDirVMCPURenderEngine *)thread->renderEngine;
		if (eyeVertex.depth >= engine->rrDepth) {
			// Russian Roulette
			const float prob = RenderEngine::RussianRouletteProb(eyeBsdfEval, engine->rrImportanceCap);
			eyeBsdfPdfW *= prob;
			eyeBsdfRevPdfW *= prob; // Note: SmallVCM uses light prob here
		}

		// MIS weights
		const float weightLight = lightVertex->dVCM * thread->misVcWeightFactor +
			lightVertex->dVM * BiDirVMCPURenderThread::MIS(eyeBsdfPdfW);
		const float weightCamera = eyeVertex.dVCM * thread->misVcWeightFactor +
			eyeVertex.dVM * BiDirVMCPURenderThread::MIS(eyeBsdfRevPdfW);
		const float misWeight = 1.f / (weightLight + 1.f + weightCamera);

		*radiance += (thread->vmNormalization * misWeight) *
				eyeVertex.throughput * eyeBsdfEval * lightVertex->throughput;

		// Statistics
		/*if (eyeVertex.bsdf.IsVolume()) {
			if (lightVertex->bsdf.IsVolume())
				++mergeHitsV2V;
			else
				++mergeHitsV2S;
		} else {
			if (lightVertex->bsdf.IsVolume())
				++mergeHitsV2S;
			else
				++mergeHitsS2S;
		}*/
	}
}

/*void HashGrid::PrintStatistics() const {
	const double mergeTotal = mergeHitsV2V + mergeHitsV2S + mergeHitsS2S;

	if (mergeTotal == 0.f)
		cout << "Volume2Volume = 0  Volume2Surface = 0  Volume2Volume = 0\n";
	else
		cout << boost::format("Volume2Volume = %d (%.2f%%)  Volume2Surface = %d (%.2f%%)  Surface2Surface = %d (%.2f%%)") %
				mergeHitsV2V % (100.0 * mergeHitsV2V / mergeTotal) %
				mergeHitsV2S % (100.0 * mergeHitsV2S / mergeTotal) %
				mergeHitsS2S % (100.0 * mergeHitsS2S / mergeTotal) << "\n";
}*/
<commit_msg>Use correct boost/format.hpp include<commit_after>/***************************************************************************
 * Copyright 1998-2013 by authors (see AUTHORS.txt)                        *
 *                                                                         *
 *   This file is part of LuxRender.                                       *
 *                                                                         *
 * Licensed under the Apache License, Version 2.0 (the "License");         *
 * you may not use this file except in compliance with the License.        *
 * You may obtain a copy of the License at                                 *
 *                                                                         *
 *     http://www.apache.org/licenses/LICENSE-2.0                          *
 *                                                                         *
 * Unless required by applicable law or agreed to in writing, software     *
 * distributed under the License is distributed on an "AS IS" BASIS,       *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*
 * See the License for the specific language governing permissions and     *
 * limitations under the License.                                          *
 ***************************************************************************/

#include <boost/format.hpp>

#include "slg/engines/bidirvmcpu/bidirvmcpu.h"

using namespace std;
using namespace luxrays;
using namespace slg;

void HashGrid::Build(vector<vector<PathVertexVM> > &pathsVertices, const float radius) {
	// Reset statistic counters
	//mergeHitsV2V = 0;
	//mergeHitsV2S = 0;
	//mergeHitsS2S = 0;

	radius2 = radius * radius;

	// Build the vertices bounding box
	vertexCount = 0;
	vertexBBox = BBox();
	for (u_int i = 0; i < pathsVertices.size(); ++i) {
		vertexCount += pathsVertices[i].size();

		for (u_int j = 0; j < pathsVertices[i].size(); ++j)
			vertexBBox = Union(vertexBBox, pathsVertices[i][j].bsdf.hitPoint.p);
	}

	if (vertexCount <= 0)
		return;

	vertexBBox.Expand(radius + DEFAULT_EPSILON_STATIC);

	// Calculate the size of the grid cell
	const float cellSize = radius * 2.f;
	invCellSize = 1.f / cellSize;

	gridSize = vertexCount;
	cellEnds.resize(gridSize);
	fill(cellEnds.begin(), cellEnds.end(), 0);
	lightVertices.resize(gridSize, NULL);

	for (u_int i = 0, k = 0; i < pathsVertices.size(); ++i) {
		for (u_int j = 0; j < pathsVertices[i].size(); ++j, ++k) {
			const PathVertexVM *vertex = &pathsVertices[i][j];

			cellEnds[Hash(vertex->bsdf.hitPoint.p)]++;
		}
	}

	int sum = 0;
	for (u_int i = 0; i < cellEnds.size(); ++i) {
		int temp = cellEnds[i];
		cellEnds[i] = sum;
		sum += temp;
	}

	for (u_int i = 0; i < pathsVertices.size(); ++i) {
		for (u_int j = 0; j < pathsVertices[i].size(); ++j) {
			const PathVertexVM *vertex = &pathsVertices[i][j];

			const int targetIdx = cellEnds[Hash(vertex->bsdf.hitPoint.p)]++;
            lightVertices[targetIdx] = vertex;
		}
	}
}

void HashGrid::Process(const BiDirVMCPURenderThread *thread,
		const PathVertexVM &eyeVertex, Spectrum *radiance) const {
	if ((vertexCount <= 0) ||
			!vertexBBox.Inside(eyeVertex.bsdf.hitPoint.p))
		return;

	const Vector distMin = eyeVertex.bsdf.hitPoint.p - vertexBBox.pMin;
	const Vector cellPoint = invCellSize * distMin;
	const Vector coordFloor(floorf(cellPoint.x), floorf(cellPoint.y), floorf(cellPoint.z));

	const int px = int(coordFloor.x);
	const int py = int(coordFloor.y);
	const int pz = int(coordFloor.z);

	const Vector fractCoord = cellPoint - coordFloor;

	const int pxo = px + ((fractCoord.x < .5f) ? -1 : +1);
	const int pyo = py + ((fractCoord.y < .5f) ? -1 : +1);
	const int pzo = pz + ((fractCoord.z < .5f) ? -1 : +1);

	int i0, i1;
	HashRange(Hash(px, py, pz), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(px, py, pzo), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(px, pyo, pz), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(px, pyo, pzo), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(pxo, py, pz), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(pxo, py, pzo), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(pxo, pyo, pz), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
	HashRange(Hash(pxo, pyo, pzo), &i0, &i1);
	Process(thread, eyeVertex, i0, i1, radiance);
}

void HashGrid::Process(const BiDirVMCPURenderThread *thread,
		const PathVertexVM &eyeVertex, const int i0, const int i1,
		Spectrum *radiance) const {
	for (int i = i0; i < i1; ++i) {
		const PathVertexVM *lightVertex = lightVertices[i];
		Process(thread, eyeVertex, lightVertex, radiance);
	}
}

void HashGrid::Process(const BiDirVMCPURenderThread *thread,
		const PathVertexVM &eyeVertex, const PathVertexVM *lightVertex,
		Spectrum *radiance) const {
	const float distance2 = (lightVertex->bsdf.hitPoint.p - eyeVertex.bsdf.hitPoint.p).LengthSquared();

	if (distance2 <= radius2) {
		float eyeBsdfPdfW, eyeBsdfRevPdfW;
		BSDFEvent eyeEvent;
		// I need to remove the dotN term from the result (see below)
		Spectrum eyeBsdfEval = eyeVertex.bsdf.Evaluate(lightVertex->bsdf.hitPoint.fixedDir,
				&eyeEvent, &eyeBsdfPdfW, &eyeBsdfRevPdfW);
		if(eyeBsdfEval.Black())
			return;

		// Volume BSDF doesn't multiply BSDF::Evaluate() by dotN so I need
		// to remove the term only if it isn't a Volume
		if (!eyeVertex.bsdf.IsVolume())
			eyeBsdfEval /= AbsDot(lightVertex->bsdf.hitPoint.fixedDir, eyeVertex.bsdf.hitPoint.geometryN);

		BiDirVMCPURenderEngine *engine = (BiDirVMCPURenderEngine *)thread->renderEngine;
		if (eyeVertex.depth >= engine->rrDepth) {
			// Russian Roulette
			const float prob = RenderEngine::RussianRouletteProb(eyeBsdfEval, engine->rrImportanceCap);
			eyeBsdfPdfW *= prob;
			eyeBsdfRevPdfW *= prob; // Note: SmallVCM uses light prob here
		}

		// MIS weights
		const float weightLight = lightVertex->dVCM * thread->misVcWeightFactor +
			lightVertex->dVM * BiDirVMCPURenderThread::MIS(eyeBsdfPdfW);
		const float weightCamera = eyeVertex.dVCM * thread->misVcWeightFactor +
			eyeVertex.dVM * BiDirVMCPURenderThread::MIS(eyeBsdfRevPdfW);
		const float misWeight = 1.f / (weightLight + 1.f + weightCamera);

		*radiance += (thread->vmNormalization * misWeight) *
				eyeVertex.throughput * eyeBsdfEval * lightVertex->throughput;

		// Statistics
		/*if (eyeVertex.bsdf.IsVolume()) {
			if (lightVertex->bsdf.IsVolume())
				++mergeHitsV2V;
			else
				++mergeHitsV2S;
		} else {
			if (lightVertex->bsdf.IsVolume())
				++mergeHitsV2S;
			else
				++mergeHitsS2S;
		}*/
	}
}

/*void HashGrid::PrintStatistics() const {
	const double mergeTotal = mergeHitsV2V + mergeHitsV2S + mergeHitsS2S;

	if (mergeTotal == 0.f)
		cout << "Volume2Volume = 0  Volume2Surface = 0  Volume2Volume = 0\n";
	else
		cout << boost::format("Volume2Volume = %d (%.2f%%)  Volume2Surface = %d (%.2f%%)  Surface2Surface = %d (%.2f%%)") %
				mergeHitsV2V % (100.0 * mergeHitsV2V / mergeTotal) %
				mergeHitsV2S % (100.0 * mergeHitsV2S / mergeTotal) %
				mergeHitsS2S % (100.0 * mergeHitsS2S / mergeTotal) << "\n";
}*/
<|endoftext|>


<commit_before>// This is free and unencumbered software released into the public domain.
// For more information, please refer to <http://unlicense.org/>

#include "span_analyzer_config_xml_handler.h"

#include "wx/filename.h"

#include "span_analyzer_app.h"

SpanAnalyzerConfigXmlHandler::SpanAnalyzerConfigXmlHandler() {
}

SpanAnalyzerConfigXmlHandler::~SpanAnalyzerConfigXmlHandler() {
}

wxXmlNode* SpanAnalyzerConfigXmlHandler::CreateNode(
    const SpanAnalyzerConfig& config) {
  // variables used to create XML node
  wxXmlNode* node_root = nullptr;
  wxXmlNode* node_element = nullptr;
  std::string title;
  std::string content;

  // creates a node for the root
  node_root = new wxXmlNode(wxXML_ELEMENT_NODE, "span_analyzer_config");
  node_root->AddAttribute("version", "1");

  // adds child nodes for struct parameters

  // creates log level node
  title = "level_log";
  if (config.level_log == wxLOG_Message) {
    content = "Normal";
  } else if (config.level_log == wxLOG_Info) {
    content = "Verbose";
  } else {
    content = "";
  }
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates filepath-data node
  title = "filepath_data";
  content = config.filepath_data;
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates size-frame node
  title = "size_frame";
  content = "";
  node_element = CreateElementNodeWithContent(title, content);

  wxString str;
  str = std::to_string(config.size_frame.GetWidth());
  node_element->AddAttribute("x", str);
  str = std::to_string(config.size_frame.GetHeight());
  node_element->AddAttribute("y", str);
  node_root->AddChild(node_element);

  // creates perspective node
  title = "perspective";
  content = config.perspective;
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates units node
  title = "units";
  if (config.units == units::UnitSystem::kMetric) {
    content = wxString("Metric");
  } else if (config.units == units::UnitSystem::kImperial) {
    content = wxString("Imperial");
  }
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // returns node
  return node_root;
}

bool SpanAnalyzerConfigXmlHandler::ParseNode(const wxXmlNode* root,
                                             const std::string& filepath,
                                             SpanAnalyzerConfig& config) {
  wxString message;

  // checks for valid root node
  if (root->GetName() != "span_analyzer_config") {
    message = FileAndLineNumber(filepath, root) +
              " Invalid root node. Aborting node parse.";
    wxLogError(message);
    return false;
  }

  // gets version attribute
  wxString version;
  if (root->GetAttribute("version", &version) == false) {
    message = FileAndLineNumber(filepath, root) +
              " Version attribute is missing. Aborting node parse.";
    wxLogError(message);
    return false;
  }

  // sends to proper parsing function
  if (version == "1") {
    return ParseNodeV1(root, filepath, config);
  } else {
    message = FileAndLineNumber(filepath, root) +
              " Invalid version number. Aborting node parse.";
    wxLogError(message);
    return false;
  }
}

bool SpanAnalyzerConfigXmlHandler::ParseNodeV1(const wxXmlNode* root,
                                               const std::string& filepath,
                                               SpanAnalyzerConfig& config) {
  bool status = true;
  wxString message;

  // evaluates each child node
  const wxXmlNode* node = root->GetChildren();
  while (node != nullptr) {
    const wxString title = node->GetName();
    const wxString content = ParseElementNodeWithContent(node);

    if (title == "filepath_data") {
      config.filepath_data = content;
      if (config.filepath_data.empty() == true) {
        message = FileAndLineNumber(filepath, node)
                  + "Application data file isn't defined. Keeping default "
                  "setting.";
        wxLogWarning(message);
      }
    } else if (title == "level_log") {
      if (content == "Normal") {
        config.level_log = wxLOG_Message;
      } else if (content == "Verbose") {
        config.level_log = wxLOG_Info;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Logging level isn't recognized. Keeping default setting.";
        wxLogWarning(message);
      }
    } else if (title == "size_frame") {
      std::string str;
      str = node->GetAttribute("x");
      config.size_frame.SetWidth(std::stoi(str));
      str = node->GetAttribute("y");
      config.size_frame.SetHeight(std::stoi(str));
    } else if (title == "perspective") {
      config.perspective = content;
    } else if (title == "units") {
      if (content == "Metric") {
        config.units = units::UnitSystem::kMetric;
      } else if (content == "Imperial") {
        config.units = units::UnitSystem::kImperial;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Unit system isn't recognized. Keeping default setting.";
        wxLogWarning(message);
      }
    } else {
      message = FileAndLineNumber(filepath, node)
                + "XML node isn't recognized. Skipping.";
      wxLogError(message);
      status = false;
    }

    node = node->GetNext();
  }

  return status;
}
<commit_msg>ConfigXmlHandler fix for blank data filepath.<commit_after>// This is free and unencumbered software released into the public domain.
// For more information, please refer to <http://unlicense.org/>

#include "span_analyzer_config_xml_handler.h"

#include "wx/filename.h"

#include "span_analyzer_app.h"

SpanAnalyzerConfigXmlHandler::SpanAnalyzerConfigXmlHandler() {
}

SpanAnalyzerConfigXmlHandler::~SpanAnalyzerConfigXmlHandler() {
}

wxXmlNode* SpanAnalyzerConfigXmlHandler::CreateNode(
    const SpanAnalyzerConfig& config) {
  // variables used to create XML node
  wxXmlNode* node_root = nullptr;
  wxXmlNode* node_element = nullptr;
  std::string title;
  std::string content;

  // creates a node for the root
  node_root = new wxXmlNode(wxXML_ELEMENT_NODE, "span_analyzer_config");
  node_root->AddAttribute("version", "1");

  // adds child nodes for struct parameters

  // creates log level node
  title = "level_log";
  if (config.level_log == wxLOG_Message) {
    content = "Normal";
  } else if (config.level_log == wxLOG_Info) {
    content = "Verbose";
  } else {
    content = "";
  }
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates filepath-data node
  title = "filepath_data";
  content = config.filepath_data;
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates size-frame node
  title = "size_frame";
  content = "";
  node_element = CreateElementNodeWithContent(title, content);

  wxString str;
  str = std::to_string(config.size_frame.GetWidth());
  node_element->AddAttribute("x", str);
  str = std::to_string(config.size_frame.GetHeight());
  node_element->AddAttribute("y", str);
  node_root->AddChild(node_element);

  // creates perspective node
  title = "perspective";
  content = config.perspective;
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates units node
  title = "units";
  if (config.units == units::UnitSystem::kMetric) {
    content = wxString("Metric");
  } else if (config.units == units::UnitSystem::kImperial) {
    content = wxString("Imperial");
  }
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // returns node
  return node_root;
}

bool SpanAnalyzerConfigXmlHandler::ParseNode(const wxXmlNode* root,
                                             const std::string& filepath,
                                             SpanAnalyzerConfig& config) {
  wxString message;

  // checks for valid root node
  if (root->GetName() != "span_analyzer_config") {
    message = FileAndLineNumber(filepath, root) +
              " Invalid root node. Aborting node parse.";
    wxLogError(message);
    return false;
  }

  // gets version attribute
  wxString version;
  if (root->GetAttribute("version", &version) == false) {
    message = FileAndLineNumber(filepath, root) +
              " Version attribute is missing. Aborting node parse.";
    wxLogError(message);
    return false;
  }

  // sends to proper parsing function
  if (version == "1") {
    return ParseNodeV1(root, filepath, config);
  } else {
    message = FileAndLineNumber(filepath, root) +
              " Invalid version number. Aborting node parse.";
    wxLogError(message);
    return false;
  }
}

bool SpanAnalyzerConfigXmlHandler::ParseNodeV1(const wxXmlNode* root,
                                               const std::string& filepath,
                                               SpanAnalyzerConfig& config) {
  bool status = true;
  wxString message;

  // evaluates each child node
  const wxXmlNode* node = root->GetChildren();
  while (node != nullptr) {
    const wxString title = node->GetName();
    const wxString content = ParseElementNodeWithContent(node);

    if (title == "filepath_data") {
      if (content.empty() == false) {
        config.filepath_data = content;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Application data file isn't defined. Keeping default "
                  "setting.";
        wxLogWarning(message);
      }
    } else if (title == "level_log") {
      if (content == "Normal") {
        config.level_log = wxLOG_Message;
      } else if (content == "Verbose") {
        config.level_log = wxLOG_Info;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Logging level isn't recognized. Keeping default setting.";
        wxLogWarning(message);
      }
    } else if (title == "size_frame") {
      std::string str;
      str = node->GetAttribute("x");
      config.size_frame.SetWidth(std::stoi(str));
      str = node->GetAttribute("y");
      config.size_frame.SetHeight(std::stoi(str));
    } else if (title == "perspective") {
      config.perspective = content;
    } else if (title == "units") {
      if (content == "Metric") {
        config.units = units::UnitSystem::kMetric;
      } else if (content == "Imperial") {
        config.units = units::UnitSystem::kImperial;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Unit system isn't recognized. Keeping default setting.";
        wxLogWarning(message);
      }
    } else {
      message = FileAndLineNumber(filepath, node)
                + "XML node isn't recognized. Skipping.";
      wxLogError(message);
      status = false;
    }

    node = node->GetNext();
  }

  return status;
}
<|endoftext|>