<commit_before>#ifndef ITER_TAKEWHILE_H_
#define ITER_TAKEWHILE_H_

#include "iterbase.hpp"

#include <utility>
#include <iterator>
#include <initializer_list>

namespace iter {

    //Forward declarations of TakeWhile and takewhile
    template <typename FilterFunc, typename Container>
    class TakeWhile;

    template <typename FilterFunc, typename Container>
    TakeWhile<FilterFunc, Container> takewhile(FilterFunc, Container&&);

    template <typename FilterFunc, typename T>
    TakeWhile<FilterFunc, std::initializer_list<T>> takewhile(
            FilterFunc, std::initializer_list<T>);

    template <typename FilterFunc, typename Container>
    class TakeWhile {
        private:
            Container container;
            FilterFunc filter_func;

            friend TakeWhile takewhile<FilterFunc, Container>(
                    FilterFunc, Container&&);

            template <typename FF, typename T>
            friend TakeWhile<FF, std::initializer_list<T>> takewhile(
                    FF, std::initializer_list<T>);

            TakeWhile(FilterFunc filter_func, Container&& container)
                : container(std::forward<Container>(container)),
                filter_func(filter_func)
            { }

        public:

            class Iterator
                : public std::iterator<std::input_iterator_tag,
                    iterator_traits_deref<Container>>
            {
                private:
                    iterator_type<Container> sub_iter;
                    iterator_type<Container> sub_end;
                    DerefHolder<iterator_deref<Container>> item;
                    FilterFunc filter_func;

                    void inc_sub_iter() {
                        ++this->sub_iter;
                        if (this->sub_iter != this->sub_end) {
                            this->item.reset(*this->sub_iter);
                        }
                    }

                    void check_current() {
                        if (this->sub_iter != this->sub_end
                                && !this->filter_func(this->item.get())) {
                            this->sub_iter = this->sub_end;
                        }
                    }

                public:
                    Iterator(iterator_type<Container>&& iter,
                            iterator_type<Container>&& end,
                            FilterFunc filter_func)
                        : sub_iter{std::move(iter)},
                        sub_end{std::move(end)},
                        filter_func(filter_func)
                    {
                        if (this->sub_iter != this->sub_end) {
                            this->item.reset(*this->sub_iter);
                        }
                        this->check_current();
                    }

                    iterator_deref<Container> operator*() {
                        return this->item.pull();
                    }

                    Iterator& operator++() {
                        this->inc_sub_iter();
                        this->check_current();
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->sub_iter != other.sub_iter;
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }

            };

            Iterator begin() {
                return {std::begin(this->container),
                        std::end(this->container),
                        this->filter_func};
            }

            Iterator end() {
                return {std::end(this->container),
                        std::end(this->container),
                        this->filter_func};
            }

    };

    template <typename FilterFunc, typename Container>
    TakeWhile<FilterFunc, Container> takewhile(
            FilterFunc filter_func, Container&& container) {
        return {filter_func, std::forward<Container>(container)};
    }

    template <typename FilterFunc, typename T>
    TakeWhile<FilterFunc, std::initializer_list<T>> takewhile(
            FilterFunc filter_func, std::initializer_list<T> il)
    {
        return {filter_func, std::move(il)};
    }

}

#endif
<commit_msg>takewhile iterator uses FiterFunc*<commit_after>#ifndef ITER_TAKEWHILE_H_
#define ITER_TAKEWHILE_H_

#include "iterbase.hpp"

#include <utility>
#include <iterator>
#include <initializer_list>

namespace iter {

    //Forward declarations of TakeWhile and takewhile
    template <typename FilterFunc, typename Container>
    class TakeWhile;

    template <typename FilterFunc, typename Container>
    TakeWhile<FilterFunc, Container> takewhile(FilterFunc, Container&&);

    template <typename FilterFunc, typename T>
    TakeWhile<FilterFunc, std::initializer_list<T>> takewhile(
            FilterFunc, std::initializer_list<T>);

    template <typename FilterFunc, typename Container>
    class TakeWhile {
        private:
            Container container;
            FilterFunc filter_func;

            friend TakeWhile takewhile<FilterFunc, Container>(
                    FilterFunc, Container&&);

            template <typename FF, typename T>
            friend TakeWhile<FF, std::initializer_list<T>> takewhile(
                    FF, std::initializer_list<T>);

            TakeWhile(FilterFunc filter_func, Container&& container)
                : container(std::forward<Container>(container)),
                filter_func(filter_func)
            { }

        public:

            class Iterator
                : public std::iterator<std::input_iterator_tag,
                    iterator_traits_deref<Container>>
            {
                private:
                    iterator_type<Container> sub_iter;
                    iterator_type<Container> sub_end;
                    DerefHolder<iterator_deref<Container>> item;
                    FilterFunc *filter_func;

                    void inc_sub_iter() {
                        ++this->sub_iter;
                        if (this->sub_iter != this->sub_end) {
                            this->item.reset(*this->sub_iter);
                        }
                    }

                    void check_current() {
                        if (this->sub_iter != this->sub_end
                                && !(*this->filter_func)(this->item.get())) {
                            this->sub_iter = this->sub_end;
                        }
                    }

                public:
                    Iterator(iterator_type<Container>&& iter,
                            iterator_type<Container>&& end,
                            FilterFunc& filter_func)
                        : sub_iter{std::move(iter)},
                        sub_end{std::move(end)},
                        filter_func(&filter_func)
                    {
                        if (this->sub_iter != this->sub_end) {
                            this->item.reset(*this->sub_iter);
                        }
                        this->check_current();
                    }

                    iterator_deref<Container> operator*() {
                        return this->item.pull();
                    }

                    Iterator& operator++() {
                        this->inc_sub_iter();
                        this->check_current();
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->sub_iter != other.sub_iter;
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }

            };

            Iterator begin() {
                return {std::begin(this->container),
                        std::end(this->container),
                        this->filter_func};
            }

            Iterator end() {
                return {std::end(this->container),
                        std::end(this->container),
                        this->filter_func};
            }

    };

    template <typename FilterFunc, typename Container>
    TakeWhile<FilterFunc, Container> takewhile(
            FilterFunc filter_func, Container&& container) {
        return {filter_func, std::forward<Container>(container)};
    }

    template <typename FilterFunc, typename T>
    TakeWhile<FilterFunc, std::initializer_list<T>> takewhile(
            FilterFunc filter_func, std::initializer_list<T> il)
    {
        return {filter_func, std::move(il)};
    }

}

#endif
<|endoftext|>


<commit_before><commit_msg>coverity#982175 Unchecked return value from library<commit_after><|endoftext|>


<commit_before>#include "../include/steadystateproblem.h"
#include "include/amici_model.h"
#include "include/amici_solver.h"
#include "include/edata.h"
#include "include/forwardproblem.h"
#include "include/newton_solver.h"
#include "include/rdata.h"
#include "include/udata.h"
#include <cstring>
#include <ctime>
#include <sundials/sundials_dense.h>
#include <memory>

namespace amici {

void SteadystateProblem::workSteadyStateProblem(const UserData *udata,
                                               ReturnData *rdata,
                                               Solver *solver, Model *model,
                                               int it) {
    /**
     * Tries to determine the steady state of the ODE system by a Newton
     * solver, uses forward intergration, if the Newton solver fails,
     * restarts Newton solver, if integration fails.
     * Computes steady state sensitivities
     *
     * @param[in] udata pointer to the user data object @type UserData
     * @param[in] solver pointer to the AMICI solver object @type Solver
     * @param[in] model pointer to the AMICI model object @type Model
     * @param[in] it integer with the index of the current time step
     * @param[out] rdata pointer to the return data object @type ReturnData
     */
    double run_time;
    clock_t starttime;

    /* First, try to do Newton steps */
    starttime = clock();

    auto newtonSolver = std::unique_ptr<NewtonSolver>(NewtonSolver::getSolver(&t, udata->linsol, model, rdata, udata));

    int newton_status;
    try {
        applyNewtonsMethod(udata, rdata, model, newtonSolver.get(), 1);
        newton_status = 1;
    } catch(NewtonFailure& ex) {
        try {
            /* Newton solver did not find a steady state, so try integration */
            getNewtonSimulation(udata, rdata, solver, model, it);
            newton_status = 2;
        } catch(AmiException& ex) {// may be integration failure from AmiSolve, so NewtonFailure won't do for all cases
            try {
                applyNewtonsMethod(udata, rdata, model, newtonSolver.get(), 2);
                newton_status = 3;
            } catch(NewtonFailure& ex) {
                // TODO: more informative NewtonFailure to give more informative error code
                throw amici::IntegrationFailure(AMICI_CONV_FAILURE,t);
            } catch(...) {
                throw AmiException("Internal error in steady state problem");
            }
        } catch(...) {
            throw AmiException("Internal error in steady state problem");
        }
    } catch(...) {
        throw AmiException("Internal error in steady state problem");
    }
    run_time = (double)((clock() - starttime) * 1000) / CLOCKS_PER_SEC;
    getNewtonOutput(rdata, model, newton_status, run_time, it);

    /* Compute steady state sensitvities */
    if (rdata->sensi_meth == AMICI_SENSI_FSA &&
        rdata->sensi >= AMICI_SENSI_ORDER_FIRST)
        newtonSolver->getSensis(it);

    /* Reinitialize solver with preequilibrated state */
    if (it == AMICI_PREEQUILIBRATE) {
        solver->AMIReInit(t, &x, &dx);
        if (rdata->sensi >= AMICI_SENSI_ORDER_FIRST)
            if (rdata->sensi_meth == AMICI_SENSI_FSA)
                solver->AMISensReInit(udata->ism, &sx, &sdx);
    }
}

/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */

void SteadystateProblem::applyNewtonsMethod(const UserData *udata,
                                           ReturnData *rdata,
                                           Model *model,
                                           NewtonSolver *newtonSolver,
                                           int newton_try) {
    /**
     * Runs the Newton solver iterations and checks for convergence to steady
     * state
     *
     * @param[in] udata pointer to the user data object @type UserData
     * @param[out] rdata pointer to the return data object @type ReturnData
     * @param[in] model pointer to the AMICI model object @type Model
     * @param[in] newtonSolver pointer to the NewtonSolver object @type
     * NewtonSolver
     * @param[in] newton_try integer start number of Newton solver (1 or 2)
     */
    int i_newtonstep = 0;
    int ix = 0;
    double res_tmp;
    double gamma = 1.0;
    bool compNewStep = TRUE;

    /* initialize output von linear solver for Newton step */
    N_VConst(0.0, delta.getNVector());

    /* Check, how fxdot is used exactly within AMICI... */
    model->fxdot(t, &x, &dx, &xdot);
    double res_abs = sqrt(N_VDotProd(xdot.getNVector(), xdot.getNVector()));

    /* Check for relative error, but make sure not to divide by 0!
        Ensure positivity of the state */
    x = x_newton;
    N_VAbs(x_newton.getNVector(), x_newton.getNVector());
    for (ix = 0; ix < model->nx; ix++) {
        if (x_newton[ix] < udata->atol) {
            x_newton[ix] = udata->atol;
        }
    }
    N_VDiv(xdot.getNVector(), x_newton.getNVector(), rel_x_newton.getNVector());
    double res_rel = sqrt(N_VDotProd(rel_x_newton.getNVector(), rel_x_newton.getNVector()));
    x = x_old;
    xdot = xdot_old;

    //rdata->newton_numsteps[newton_try - 1] = 0.0;
    bool converged = (res_abs < udata->atol || res_rel < udata->rtol);
    while (!converged && i_newtonstep < udata->newton_maxsteps) {

        /* If Newton steps are necessary, compute the inital search direction */
        if (compNewStep) {
            try{
                newtonSolver->getStep(newton_try, i_newtonstep, &delta);
            } catch(...) {
                rdata->newton_numsteps[newton_try - 1] = amiGetNaN();
                throw NewtonFailure("Newton method failed to compute new step!");
            }
        }

        /* Try a full, undamped Newton step */
        N_VLinearSum(1.0, x_old.getNVector(), gamma, delta.getNVector(), x.getNVector());
        /* Ensure positivity of the state */
        for (ix = 0; ix < model->nx; ix++)
            if (x[ix] < udata->atol)
                x[ix] = udata->atol;

        /* Compute new xdot and residuals */
        model->fxdot(t, &x, &dx, &xdot);
        N_VDiv(xdot.getNVector(), x.getNVector(), rel_x_newton.getNVector());
        res_rel = sqrt(N_VDotProd(rel_x_newton.getNVector(), rel_x_newton.getNVector()));
        res_tmp = sqrt(N_VDotProd(xdot.getNVector(), xdot.getNVector()));

        if (res_tmp < res_abs) {
            /* If new residuals are smaller than old ones, update state */
            res_abs = res_tmp;
            x = x_old;
            xdot = xdot_old;
            /* New linear solve due to new state */
            compNewStep = TRUE;
            /* Check residuals vs tolerances */
            converged = (res_abs < udata->atol) || (res_rel < udata->rtol);
            /* increase dampening factor (superfluous, if converged) */
            gamma = fmin(1.0, 2.0 * gamma);
        } else {
            /* Reduce dampening factor */
            gamma = gamma / 4.0;
            /* No new linear solve, only try new dampening */
            compNewStep = FALSE;
        }
        /* increase step counter */
        i_newtonstep++;
    }

    /* Set return values */
    rdata->newton_numsteps[newton_try-1] = (double) i_newtonstep;
    if (!converged)
        throw NewtonFailure("Newton method failed to converge!");
}

/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */

void SteadystateProblem::getNewtonOutput(ReturnData *rdata,
                                         Model *model, int newton_status,
                                         double run_time, int it) {
    /**
     * Stores output of workSteadyStateProblem in return data
     *
     * @param[in] model pointer to the AMICI model object @type Model
     * @param[in] newton_status integer flag indicating when a steady state was
     * found
     * @param[in] run_time double coputation time of the solver in milliseconds
     * @param[out] rdata pointer to the return data object @type ReturnData
     * @param[in] it current timepoint index, <0 indicates preequilibration @type int
     */

    /* Get time for Newton solve */
    rdata->newton_time[0] = run_time;
    rdata->newton_status[0] = newton_status;

    /* Steady state was found: set t to t0 if preeq, otherwise to inf */
    if (it == AMICI_PREEQUILIBRATE) {
        t = rdata->ts[0];

        /* Write steady state to output */
        for (int ix = 0; ix < model->nx; ix++) {
            rdata->x0[ix] = x[ix];
        }
    } else {
        t = INFINITY;
    }
}

/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */

void SteadystateProblem::getNewtonSimulation(const UserData *udata,
                                            ReturnData *rdata, Solver *solver,
                                            Model *model, int it) {
    /**
     * Forward simulation is launched, if Newton solver fails in first try
     *
     * @param[in] udata pointer to the user data object @type UserData
     * @param[in] solver pointer to the AMICI solver object @type Solver
     * @param[in] model pointer to the AMICI model object @type Model
     * @param[out] rdata pointer to the return data object @type ReturnData
     * @param[in] it current timepoint index, <0 indicates preequilibration @type int
     */

    realtype tstart;

    /* Newton solver did not work, so try a simulation: reinitialize solver */
    if (it<1)
        tstart = udata->t0();
    else
        tstart = rdata->ts[it-1];
    t = tstart;

    model->fx0(&x, udata);
    solver->AMIReInit(t, &x, &dx);

    /* Loop over steps and check for convergence */
    double res_abs = INFINITY;
    double res_rel = INFINITY;

    int it_newton = 0;
    while(res_abs > udata->atol && res_rel > udata->rtol) {
        /* One step of ODE integration */
        solver->AMISolve(1e12, &x, &dx, &t,
                                  AMICI_ONE_STEP);
        model->fxdot(t, &x, &dx, &xdot);
        res_abs = sqrt(N_VDotProd(xdot.getNVector(), xdot.getNVector()));

        /* Ensure positivity and compute relative residual */
        x=x_newton;
        N_VAbs(x_newton.getNVector(), x_newton.getNVector());
        for (int ix = 0; ix < model->nx; ix++) {
            if (x_newton[ix] < udata->atol) {
                x_newton[ix] = udata->atol;
            }
        }
        N_VDiv(xdot.getNVector(), x_newton.getNVector(), rel_x_newton.getNVector());
        res_rel = sqrt(N_VDotProd(rel_x_newton.getNVector(), rel_x_newton.getNVector()));

        /* Check for convergence */
        if (res_abs < udata->atol || res_rel < udata->rtol)
            break;
        /* increase counter, check for maxsteps */
        it_newton++;
        if (it_newton >= udata->maxsteps)
            throw NewtonFailure("Simulation based steady state failed to converge");

    }
}

} // namespace amici
<commit_msg>fixes steadystateproblems<commit_after>#include "../include/steadystateproblem.h"
#include "include/amici_model.h"
#include "include/amici_solver.h"
#include "include/edata.h"
#include "include/forwardproblem.h"
#include "include/newton_solver.h"
#include "include/rdata.h"
#include "include/udata.h"
#include <cstring>
#include <ctime>
#include <sundials/sundials_dense.h>
#include <memory>

namespace amici {

void SteadystateProblem::workSteadyStateProblem(const UserData *udata,
                                               ReturnData *rdata,
                                               Solver *solver, Model *model,
                                               int it) {
    /**
     * Tries to determine the steady state of the ODE system by a Newton
     * solver, uses forward intergration, if the Newton solver fails,
     * restarts Newton solver, if integration fails.
     * Computes steady state sensitivities
     *
     * @param[in] udata pointer to the user data object @type UserData
     * @param[in] solver pointer to the AMICI solver object @type Solver
     * @param[in] model pointer to the AMICI model object @type Model
     * @param[in] it integer with the index of the current time step
     * @param[out] rdata pointer to the return data object @type ReturnData
     */
    double run_time;
    clock_t starttime;

    /* First, try to do Newton steps */
    starttime = clock();

    auto newtonSolver = std::unique_ptr<NewtonSolver>(NewtonSolver::getSolver(&t, udata->linsol, model, rdata, udata));

    int newton_status;
    try {
        applyNewtonsMethod(udata, rdata, model, newtonSolver.get(), 1);
        newton_status = 1;
    } catch(NewtonFailure& ex) {
        try {
            /* Newton solver did not find a steady state, so try integration */
            getNewtonSimulation(udata, rdata, solver, model, it);
            newton_status = 2;
        } catch(AmiException& ex) {// may be integration failure from AmiSolve, so NewtonFailure won't do for all cases
            try {
                applyNewtonsMethod(udata, rdata, model, newtonSolver.get(), 2);
                newton_status = 3;
            } catch(NewtonFailure& ex) {
                // TODO: more informative NewtonFailure to give more informative error code
                throw amici::IntegrationFailure(AMICI_CONV_FAILURE,t);
            } catch(...) {
                throw AmiException("Internal error in steady state problem");
            }
        } catch(...) {
            throw AmiException("Internal error in steady state problem");
        }
    } catch(...) {
        throw AmiException("Internal error in steady state problem");
    }
    run_time = (double)((clock() - starttime) * 1000) / CLOCKS_PER_SEC;
    getNewtonOutput(rdata, model, newton_status, run_time, it);

    /* Compute steady state sensitvities */
    if (rdata->sensi_meth == AMICI_SENSI_FSA &&
        rdata->sensi >= AMICI_SENSI_ORDER_FIRST)
        newtonSolver->getSensis(it);

    /* Reinitialize solver with preequilibrated state */
    if (it == AMICI_PREEQUILIBRATE) {
        solver->AMIReInit(t, &x, &dx);
        if (rdata->sensi >= AMICI_SENSI_ORDER_FIRST)
            if (rdata->sensi_meth == AMICI_SENSI_FSA)
                solver->AMISensReInit(udata->ism, &sx, &sdx);
    }
}

/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */

void SteadystateProblem::applyNewtonsMethod(const UserData *udata,
                                           ReturnData *rdata,
                                           Model *model,
                                           NewtonSolver *newtonSolver,
                                           int newton_try) {
    /**
     * Runs the Newton solver iterations and checks for convergence to steady
     * state
     *
     * @param[in] udata pointer to the user data object @type UserData
     * @param[out] rdata pointer to the return data object @type ReturnData
     * @param[in] model pointer to the AMICI model object @type Model
     * @param[in] newtonSolver pointer to the NewtonSolver object @type
     * NewtonSolver
     * @param[in] newton_try integer start number of Newton solver (1 or 2)
     */
    int i_newtonstep = 0;
    int ix = 0;
    double res_tmp;
    double gamma = 1.0;
    bool compNewStep = TRUE;

    /* initialize output von linear solver for Newton step */
    N_VConst(0.0, delta.getNVector());

    /* Check, how fxdot is used exactly within AMICI... */
    model->fxdot(t, &x, &dx, &xdot);
    double res_abs = sqrt(N_VDotProd(xdot.getNVector(), xdot.getNVector()));

    /* Check for relative error, but make sure not to divide by 0!
        Ensure positivity of the state */
    x = x_newton;
    N_VAbs(x_newton.getNVector(), x_newton.getNVector());
    for (ix = 0; ix < model->nx; ix++) {
        if (x_newton[ix] < udata->atol) {
            x_newton[ix] = udata->atol;
        }
    }
    N_VDiv(xdot.getNVector(), x_newton.getNVector(), rel_x_newton.getNVector());
    double res_rel = sqrt(N_VDotProd(rel_x_newton.getNVector(), rel_x_newton.getNVector()));
    x_old = x;
    xdot_old = xdot;

    //rdata->newton_numsteps[newton_try - 1] = 0.0;
    bool converged = (res_abs < udata->atol || res_rel < udata->rtol);
    while (!converged && i_newtonstep < udata->newton_maxsteps) {

        /* If Newton steps are necessary, compute the inital search direction */
        if (compNewStep) {
            try{
                newtonSolver->getStep(newton_try, i_newtonstep, &delta);
            } catch(...) {
                rdata->newton_numsteps[newton_try - 1] = amiGetNaN();
                throw NewtonFailure("Newton method failed to compute new step!");
            }
        }

        /* Try a full, undamped Newton step */
        N_VLinearSum(1.0, x_old.getNVector(), gamma, delta.getNVector(), x.getNVector());
        /* Ensure positivity of the state */
        for (ix = 0; ix < model->nx; ix++)
            if (x[ix] < udata->atol)
                x[ix] = udata->atol;

        /* Compute new xdot and residuals */
        model->fxdot(t, &x, &dx, &xdot);
        N_VDiv(xdot.getNVector(), x.getNVector(), rel_x_newton.getNVector());
        res_rel = sqrt(N_VDotProd(rel_x_newton.getNVector(), rel_x_newton.getNVector()));
        res_tmp = sqrt(N_VDotProd(xdot.getNVector(), xdot.getNVector()));

        if (res_tmp < res_abs) {
            /* If new residuals are smaller than old ones, update state */
            res_abs = res_tmp;
            x_old = x;
            xdot_old = xdot;
            /* New linear solve due to new state */
            compNewStep = TRUE;
            /* Check residuals vs tolerances */
            converged = (res_abs < udata->atol) || (res_rel < udata->rtol);
            /* increase dampening factor (superfluous, if converged) */
            gamma = fmin(1.0, 2.0 * gamma);
        } else {
            /* Reduce dampening factor */
            gamma = gamma / 4.0;
            /* No new linear solve, only try new dampening */
            compNewStep = FALSE;
        }
        /* increase step counter */
        i_newtonstep++;
    }

    /* Set return values */
    rdata->newton_numsteps[newton_try-1] = (double) i_newtonstep;
    if (!converged)
        throw NewtonFailure("Newton method failed to converge!");
}

/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */

void SteadystateProblem::getNewtonOutput(ReturnData *rdata,
                                         Model *model, int newton_status,
                                         double run_time, int it) {
    /**
     * Stores output of workSteadyStateProblem in return data
     *
     * @param[in] model pointer to the AMICI model object @type Model
     * @param[in] newton_status integer flag indicating when a steady state was
     * found
     * @param[in] run_time double coputation time of the solver in milliseconds
     * @param[out] rdata pointer to the return data object @type ReturnData
     * @param[in] it current timepoint index, <0 indicates preequilibration @type int
     */

    /* Get time for Newton solve */
    rdata->newton_time[0] = run_time;
    rdata->newton_status[0] = newton_status;

    /* Steady state was found: set t to t0 if preeq, otherwise to inf */
    if (it == AMICI_PREEQUILIBRATE) {
        t = rdata->ts[0];

        /* Write steady state to output */
        for (int ix = 0; ix < model->nx; ix++) {
            rdata->x0[ix] = x[ix];
        }
    } else {
        t = INFINITY;
    }
}

/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */
/* ----------------------------------------------------------------------------------
 */

void SteadystateProblem::getNewtonSimulation(const UserData *udata,
                                            ReturnData *rdata, Solver *solver,
                                            Model *model, int it) {
    /**
     * Forward simulation is launched, if Newton solver fails in first try
     *
     * @param[in] udata pointer to the user data object @type UserData
     * @param[in] solver pointer to the AMICI solver object @type Solver
     * @param[in] model pointer to the AMICI model object @type Model
     * @param[out] rdata pointer to the return data object @type ReturnData
     * @param[in] it current timepoint index, <0 indicates preequilibration @type int
     */

    realtype tstart;

    /* Newton solver did not work, so try a simulation: reinitialize solver */
    if (it<1)
        tstart = udata->t0();
    else
        tstart = rdata->ts[it-1];
    t = tstart;

    model->fx0(&x, udata);
    solver->AMIReInit(t, &x, &dx);

    /* Loop over steps and check for convergence */
    double res_abs = INFINITY;
    double res_rel = INFINITY;

    int it_newton = 0;
    while(res_abs > udata->atol && res_rel > udata->rtol) {
        /* One step of ODE integration */
        solver->AMISolve(1e12, &x, &dx, &t,
                                  AMICI_ONE_STEP);
        model->fxdot(t, &x, &dx, &xdot);
        res_abs = sqrt(N_VDotProd(xdot.getNVector(), xdot.getNVector()));

        /* Ensure positivity and compute relative residual */
        x_newton = x;
        N_VAbs(x_newton.getNVector(), x_newton.getNVector());
        for (int ix = 0; ix < model->nx; ix++) {
            if (x_newton[ix] < udata->atol) {
                x_newton[ix] = udata->atol;
            }
        }
        N_VDiv(xdot.getNVector(), x_newton.getNVector(), rel_x_newton.getNVector());
        res_rel = sqrt(N_VDotProd(rel_x_newton.getNVector(), rel_x_newton.getNVector()));

        /* Check for convergence */
        if (res_abs < udata->atol || res_rel < udata->rtol)
            break;
        /* increase counter, check for maxsteps */
        it_newton++;
        if (it_newton >= udata->maxsteps)
            throw NewtonFailure("Simulation based steady state failed to converge");

    }
}

} // namespace amici
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/bitcoin/network/timeout.hpp>

#include <cstdint>
#include <boost/asio.hpp>
#include <boost/date_time.hpp>
#include <bitcoin/bitcoin/error.hpp>

namespace libbitcoin {
namespace network {

using boost::posix_time::seconds;
using boost::posix_time::minutes;

const timeout timeout::defaults = timeout::timeout();

timeout::timeout(
    uint32_t connect_timeout_seconds,
    uint32_t channel_handshake_seconds,
    uint32_t channel_revival_minutes,
    uint32_t channel_heartbeat_minutes,
    uint32_t channel_inactivity_minutes,
    uint32_t channel_expiration_minutes,
    uint32_t channel_germination_seconds)
  : connect(0, 0, connect_timeout_seconds),
    handshake(0, 0, channel_handshake_seconds),
    revival(0, channel_revival_minutes, 0),
    heartbeat(0, channel_heartbeat_minutes, 0),
    inactivity(0, channel_inactivity_minutes, 0),
    expiration(0, channel_expiration_minutes, 0),
    germination(0, 0, channel_germination_seconds)
{
}

// TODO: wrap boost timers with our own and map error codes internally.
bool timeout::canceled(const boost_code& ec)
{
    return ec == asio::error::operation_aborted;
}

} // namespace network
} // namespace libbitcoin
<commit_msg>Remove static construction.<commit_after>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/bitcoin/network/timeout.hpp>

#include <cstdint>
#include <boost/asio.hpp>
#include <boost/date_time.hpp>
#include <bitcoin/bitcoin/error.hpp>

namespace libbitcoin {
namespace network {

using boost::posix_time::seconds;
using boost::posix_time::minutes;

const timeout timeout::defaults;

timeout::timeout(
    uint32_t connect_timeout_seconds,
    uint32_t channel_handshake_seconds,
    uint32_t channel_revival_minutes,
    uint32_t channel_heartbeat_minutes,
    uint32_t channel_inactivity_minutes,
    uint32_t channel_expiration_minutes,
    uint32_t channel_germination_seconds)
  : connect(0, 0, connect_timeout_seconds),
    handshake(0, 0, channel_handshake_seconds),
    revival(0, channel_revival_minutes, 0),
    heartbeat(0, channel_heartbeat_minutes, 0),
    inactivity(0, channel_inactivity_minutes, 0),
    expiration(0, channel_expiration_minutes, 0),
    germination(0, 0, channel_germination_seconds)
{
}

// TODO: wrap boost timers with our own and map error codes internally.
bool timeout::canceled(const boost_code& ec)
{
    return ec == asio::error::operation_aborted;
}

} // namespace network
} // namespace libbitcoin
<|endoftext|>


<commit_before>#include "command.hh"
#include "attr-path.hh"
#include "common-eval-args.hh"
#include "derivations.hh"
#include "eval-inline.hh"
#include "eval.hh"
#include "get-drvs.hh"
#include "store-api.hh"
#include "shared.hh"

#include <regex>

namespace nix {

SourceExprCommand::SourceExprCommand()
{
    mkFlag()
        .shortName('f')
        .longName("file")
        .label("file")
        .description("evaluate FILE rather than the default")
        .dest(&file);
}

Value * SourceExprCommand::getSourceExpr(EvalState & state)
{
    if (vSourceExpr) return vSourceExpr;

    auto sToplevel = state.symbols.create("_toplevel");

    vSourceExpr = state.allocValue();

    if (file != "")
        state.evalFile(lookupFileArg(state, file), *vSourceExpr);

    else {

        /* Construct the installation source from $NIX_PATH. */

        auto searchPath = state.getSearchPath();

        state.mkAttrs(*vSourceExpr, searchPath.size() + 1);

        mkBool(*state.allocAttr(*vSourceExpr, sToplevel), true);

        std::unordered_set<std::string> seen;

        for (auto & i : searchPath) {
            if (i.first == "") continue;
            if (seen.count(i.first)) continue;
            seen.insert(i.first);
#if 0
            auto res = state.resolveSearchPathElem(i);
            if (!res.first) continue;
            if (!pathExists(res.second)) continue;
            mkApp(*state.allocAttr(*vSourceExpr, state.symbols.create(i.first)),
                state.getBuiltin("import"),
                mkString(*state.allocValue(), res.second));
#endif
            Value * v1 = state.allocValue();
            mkPrimOpApp(*v1, state.getBuiltin("findFile"), state.getBuiltin("nixPath"));
            Value * v2 = state.allocValue();
            mkApp(*v2, *v1, mkString(*state.allocValue(), i.first));
            mkApp(*state.allocAttr(*vSourceExpr, state.symbols.create(i.first)),
                state.getBuiltin("import"), *v2);
        }

        vSourceExpr->attrs->sort();
    }

    return vSourceExpr;
}

ref<EvalState> SourceExprCommand::getEvalState()
{
    if (!evalState)
        evalState = std::make_shared<EvalState>(searchPath, getStore());
    return ref<EvalState>(evalState);
}

Buildable Installable::toBuildable()
{
    auto buildables = toBuildables();
    if (buildables.size() != 1)
        throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size());
    return std::move(buildables[0]);
}

struct InstallableStorePath : Installable
{
    Path storePath;

    InstallableStorePath(const Path & storePath) : storePath(storePath) { }

    std::string what() override { return storePath; }

    Buildables toBuildables() override
    {
        return {{"", {{"out", storePath}}}};
    }
};

struct InstallableValue : Installable
{
    SourceExprCommand & cmd;

    InstallableValue(SourceExprCommand & cmd) : cmd(cmd) { }

    Buildables toBuildables() override
    {
        auto state = cmd.getEvalState();

        auto v = toValue(*state);

        Bindings & autoArgs = *cmd.getAutoArgs(*state);

        DrvInfos drvs;
        getDerivations(*state, *v, "", autoArgs, drvs, false);

        Buildables res;

        PathSet drvPaths;

        for (auto & drv : drvs) {
            Buildable b{drv.queryDrvPath()};
            drvPaths.insert(b.drvPath);

            auto outputName = drv.queryOutputName();
            if (outputName == "")
                throw Error("derivation '%s' lacks an 'outputName' attribute", b.drvPath);

            b.outputs.emplace(outputName, drv.queryOutPath());

            res.push_back(std::move(b));
        }

        // Hack to recognize .all: if all drvs have the same drvPath,
        // merge the buildables.
        if (drvPaths.size() == 1) {
            Buildable b{*drvPaths.begin()};
            for (auto & b2 : res)
                b.outputs.insert(b2.outputs.begin(), b2.outputs.end());
            return {b};
        } else
            return res;
    }
};

struct InstallableExpr : InstallableValue
{
    std::string text;

    InstallableExpr(SourceExprCommand & cmd, const std::string & text)
         : InstallableValue(cmd), text(text) { }

    std::string what() override { return text; }

    Value * toValue(EvalState & state) override
    {
        auto v = state.allocValue();
        state.eval(state.parseExprFromString(text, absPath(".")), *v);
        return v;
    }
};

struct InstallableAttrPath : InstallableValue
{
    std::string attrPath;

    InstallableAttrPath(SourceExprCommand & cmd, const std::string & attrPath)
        : InstallableValue(cmd), attrPath(attrPath)
    { }

    std::string what() override { return attrPath; }

    Value * toValue(EvalState & state) override
    {
        auto source = cmd.getSourceExpr(state);

        Bindings & autoArgs = *cmd.getAutoArgs(state);

        Value * v = findAlongAttrPath(state, attrPath, autoArgs, *source);
        state.forceValue(*v);

        return v;
    }
};

// FIXME: extend
std::string attrRegex = R"([A-Za-z_][A-Za-z0-9-_+]*)";
static std::regex attrPathRegex(fmt(R"(%1%(\.%1%)*)", attrRegex));

static std::vector<std::shared_ptr<Installable>> parseInstallables(
    SourceExprCommand & cmd, ref<Store> store, std::vector<std::string> ss, bool useDefaultInstallables)
{
    std::vector<std::shared_ptr<Installable>> result;

    if (ss.empty() && useDefaultInstallables) {
        if (cmd.file == "")
            cmd.file = ".";
        ss = {""};
    }

    for (auto & s : ss) {

        if (s.compare(0, 1, "(") == 0)
            result.push_back(std::make_shared<InstallableExpr>(cmd, s));

        else if (s.find("/") != std::string::npos) {

            auto path = store->toStorePath(store->followLinksToStore(s));

            if (store->isStorePath(path))
                result.push_back(std::make_shared<InstallableStorePath>(path));
        }

        else if (s == "" || std::regex_match(s, attrPathRegex))
            result.push_back(std::make_shared<InstallableAttrPath>(cmd, s));

        else
            throw UsageError("don't know what to do with argument '%s'", s);
    }

    return result;
}

std::shared_ptr<Installable> parseInstallable(
    SourceExprCommand & cmd, ref<Store> store, const std::string & installable,
    bool useDefaultInstallables)
{
    auto installables = parseInstallables(cmd, store, {installable}, false);
    assert(installables.size() == 1);
    return installables.front();
}

Buildables build(ref<Store> store, RealiseMode mode,
    std::vector<std::shared_ptr<Installable>> installables)
{
    if (mode != Build)
        settings.readOnlyMode = true;

    Buildables buildables;

    PathSet pathsToBuild;

    for (auto & i : installables) {
        for (auto & b : i->toBuildables()) {
            if (b.drvPath != "") {
                StringSet outputNames;
                for (auto & output : b.outputs)
                    outputNames.insert(output.first);
                pathsToBuild.insert(
                    b.drvPath + "!" + concatStringsSep(",", outputNames));
            } else
                for (auto & output : b.outputs)
                    pathsToBuild.insert(output.second);
            buildables.push_back(std::move(b));
        }
    }

    if (mode == DryRun)
        printMissing(store, pathsToBuild, lvlError);
    else if (mode == Build)
        store->buildPaths(pathsToBuild);

    return buildables;
}

PathSet toStorePaths(ref<Store> store, RealiseMode mode,
    std::vector<std::shared_ptr<Installable>> installables)
{
    PathSet outPaths;

    for (auto & b : build(store, mode, installables))
        for (auto & output : b.outputs)
            outPaths.insert(output.second);

    return outPaths;
}

Path toStorePath(ref<Store> store, RealiseMode mode,
    std::shared_ptr<Installable> installable)
{
    auto paths = toStorePaths(store, mode, {installable});

    if (paths.size() != 1)
            throw Error("argument '%s' should evaluate to one store path", installable->what());

    return *paths.begin();
}

PathSet toDerivations(ref<Store> store,
    std::vector<std::shared_ptr<Installable>> installables, bool useDeriver)
{
    PathSet drvPaths;

    for (auto & i : installables)
        for (auto & b : i->toBuildables()) {
            if (b.drvPath.empty()) {
                if (!useDeriver)
                    throw Error("argument '%s' did not evaluate to a derivation", i->what());
                for (auto & output : b.outputs) {
                    auto derivers = store->queryValidDerivers(output.second);
                    if (derivers.empty())
                        throw Error("'%s' does not have a known deriver", i->what());
                    // FIXME: use all derivers?
                    drvPaths.insert(*derivers.begin());
                }
            } else
                drvPaths.insert(b.drvPath);
        }

    return drvPaths;
}

void InstallablesCommand::prepare()
{
    installables = parseInstallables(*this, getStore(), _installables, useDefaultInstallables());
}

void InstallableCommand::prepare()
{
    installable = parseInstallable(*this, getStore(), _installable, false);
}

}
<commit_msg>Slightly questionable workaround for #2342<commit_after>#include "command.hh"
#include "attr-path.hh"
#include "common-eval-args.hh"
#include "derivations.hh"
#include "eval-inline.hh"
#include "eval.hh"
#include "get-drvs.hh"
#include "store-api.hh"
#include "shared.hh"

#include <regex>

namespace nix {

SourceExprCommand::SourceExprCommand()
{
    mkFlag()
        .shortName('f')
        .longName("file")
        .label("file")
        .description("evaluate FILE rather than the default")
        .dest(&file);
}

Value * SourceExprCommand::getSourceExpr(EvalState & state)
{
    if (vSourceExpr) return vSourceExpr;

    auto sToplevel = state.symbols.create("_toplevel");

    vSourceExpr = state.allocValue();

    if (file != "")
        state.evalFile(lookupFileArg(state, file), *vSourceExpr);

    else {

        /* Construct the installation source from $NIX_PATH. */

        auto searchPath = state.getSearchPath();

        state.mkAttrs(*vSourceExpr, searchPath.size() + 1);

        mkBool(*state.allocAttr(*vSourceExpr, sToplevel), true);

        std::unordered_set<std::string> seen;

        for (auto & i : searchPath) {
            if (i.first == "") continue;
            if (seen.count(i.first)) continue;
            seen.insert(i.first);
#if 0
            auto res = state.resolveSearchPathElem(i);
            if (!res.first) continue;
            if (!pathExists(res.second)) continue;
            mkApp(*state.allocAttr(*vSourceExpr, state.symbols.create(i.first)),
                state.getBuiltin("import"),
                mkString(*state.allocValue(), res.second));
#endif
            Value * v1 = state.allocValue();
            mkPrimOpApp(*v1, state.getBuiltin("findFile"), state.getBuiltin("nixPath"));
            Value * v2 = state.allocValue();
            mkApp(*v2, *v1, mkString(*state.allocValue(), i.first));
            mkApp(*state.allocAttr(*vSourceExpr, state.symbols.create(i.first)),
                state.getBuiltin("import"), *v2);
        }

        vSourceExpr->attrs->sort();
    }

    return vSourceExpr;
}

ref<EvalState> SourceExprCommand::getEvalState()
{
    if (!evalState)
        evalState = std::make_shared<EvalState>(searchPath, getStore());
    return ref<EvalState>(evalState);
}

Buildable Installable::toBuildable()
{
    auto buildables = toBuildables();
    if (buildables.size() != 1)
        throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size());
    return std::move(buildables[0]);
}

struct InstallableStorePath : Installable
{
    Path storePath;

    InstallableStorePath(const Path & storePath) : storePath(storePath) { }

    std::string what() override { return storePath; }

    Buildables toBuildables() override
    {
        return {{isDerivation(storePath) ? storePath : "", {{"out", storePath}}}};
    }
};

struct InstallableValue : Installable
{
    SourceExprCommand & cmd;

    InstallableValue(SourceExprCommand & cmd) : cmd(cmd) { }

    Buildables toBuildables() override
    {
        auto state = cmd.getEvalState();

        auto v = toValue(*state);

        Bindings & autoArgs = *cmd.getAutoArgs(*state);

        DrvInfos drvs;
        getDerivations(*state, *v, "", autoArgs, drvs, false);

        Buildables res;

        PathSet drvPaths;

        for (auto & drv : drvs) {
            Buildable b{drv.queryDrvPath()};
            drvPaths.insert(b.drvPath);

            auto outputName = drv.queryOutputName();
            if (outputName == "")
                throw Error("derivation '%s' lacks an 'outputName' attribute", b.drvPath);

            b.outputs.emplace(outputName, drv.queryOutPath());

            res.push_back(std::move(b));
        }

        // Hack to recognize .all: if all drvs have the same drvPath,
        // merge the buildables.
        if (drvPaths.size() == 1) {
            Buildable b{*drvPaths.begin()};
            for (auto & b2 : res)
                b.outputs.insert(b2.outputs.begin(), b2.outputs.end());
            return {b};
        } else
            return res;
    }
};

struct InstallableExpr : InstallableValue
{
    std::string text;

    InstallableExpr(SourceExprCommand & cmd, const std::string & text)
         : InstallableValue(cmd), text(text) { }

    std::string what() override { return text; }

    Value * toValue(EvalState & state) override
    {
        auto v = state.allocValue();
        state.eval(state.parseExprFromString(text, absPath(".")), *v);
        return v;
    }
};

struct InstallableAttrPath : InstallableValue
{
    std::string attrPath;

    InstallableAttrPath(SourceExprCommand & cmd, const std::string & attrPath)
        : InstallableValue(cmd), attrPath(attrPath)
    { }

    std::string what() override { return attrPath; }

    Value * toValue(EvalState & state) override
    {
        auto source = cmd.getSourceExpr(state);

        Bindings & autoArgs = *cmd.getAutoArgs(state);

        Value * v = findAlongAttrPath(state, attrPath, autoArgs, *source);
        state.forceValue(*v);

        return v;
    }
};

// FIXME: extend
std::string attrRegex = R"([A-Za-z_][A-Za-z0-9-_+]*)";
static std::regex attrPathRegex(fmt(R"(%1%(\.%1%)*)", attrRegex));

static std::vector<std::shared_ptr<Installable>> parseInstallables(
    SourceExprCommand & cmd, ref<Store> store, std::vector<std::string> ss, bool useDefaultInstallables)
{
    std::vector<std::shared_ptr<Installable>> result;

    if (ss.empty() && useDefaultInstallables) {
        if (cmd.file == "")
            cmd.file = ".";
        ss = {""};
    }

    for (auto & s : ss) {

        if (s.compare(0, 1, "(") == 0)
            result.push_back(std::make_shared<InstallableExpr>(cmd, s));

        else if (s.find("/") != std::string::npos) {

            auto path = store->toStorePath(store->followLinksToStore(s));

            if (store->isStorePath(path))
                result.push_back(std::make_shared<InstallableStorePath>(path));
        }

        else if (s == "" || std::regex_match(s, attrPathRegex))
            result.push_back(std::make_shared<InstallableAttrPath>(cmd, s));

        else
            throw UsageError("don't know what to do with argument '%s'", s);
    }

    return result;
}

std::shared_ptr<Installable> parseInstallable(
    SourceExprCommand & cmd, ref<Store> store, const std::string & installable,
    bool useDefaultInstallables)
{
    auto installables = parseInstallables(cmd, store, {installable}, false);
    assert(installables.size() == 1);
    return installables.front();
}

Buildables build(ref<Store> store, RealiseMode mode,
    std::vector<std::shared_ptr<Installable>> installables)
{
    if (mode != Build)
        settings.readOnlyMode = true;

    Buildables buildables;

    PathSet pathsToBuild;

    for (auto & i : installables) {
        for (auto & b : i->toBuildables()) {
            if (b.drvPath != "") {
                StringSet outputNames;
                for (auto & output : b.outputs)
                    outputNames.insert(output.first);
                pathsToBuild.insert(
                    b.drvPath + "!" + concatStringsSep(",", outputNames));
            } else
                for (auto & output : b.outputs)
                    pathsToBuild.insert(output.second);
            buildables.push_back(std::move(b));
        }
    }

    if (mode == DryRun)
        printMissing(store, pathsToBuild, lvlError);
    else if (mode == Build)
        store->buildPaths(pathsToBuild);

    return buildables;
}

PathSet toStorePaths(ref<Store> store, RealiseMode mode,
    std::vector<std::shared_ptr<Installable>> installables)
{
    PathSet outPaths;

    for (auto & b : build(store, mode, installables))
        for (auto & output : b.outputs)
            outPaths.insert(output.second);

    return outPaths;
}

Path toStorePath(ref<Store> store, RealiseMode mode,
    std::shared_ptr<Installable> installable)
{
    auto paths = toStorePaths(store, mode, {installable});

    if (paths.size() != 1)
            throw Error("argument '%s' should evaluate to one store path", installable->what());

    return *paths.begin();
}

PathSet toDerivations(ref<Store> store,
    std::vector<std::shared_ptr<Installable>> installables, bool useDeriver)
{
    PathSet drvPaths;

    for (auto & i : installables)
        for (auto & b : i->toBuildables()) {
            if (b.drvPath.empty()) {
                if (!useDeriver)
                    throw Error("argument '%s' did not evaluate to a derivation", i->what());
                for (auto & output : b.outputs) {
                    auto derivers = store->queryValidDerivers(output.second);
                    if (derivers.empty())
                        throw Error("'%s' does not have a known deriver", i->what());
                    // FIXME: use all derivers?
                    drvPaths.insert(*derivers.begin());
                }
            } else
                drvPaths.insert(b.drvPath);
        }

    return drvPaths;
}

void InstallablesCommand::prepare()
{
    installables = parseInstallables(*this, getStore(), _installables, useDefaultInstallables());
}

void InstallableCommand::prepare()
{
    installable = parseInstallable(*this, getStore(), _installable, false);
}

}
<|endoftext|>


<commit_before>/**\file
 * \brief Test cases for the VT100 I/O code
 *
 * Covers the functionality in the terminal.h and vt100.h headers.
 *
 * \copyright
 * Copyright (c) 2012-2014, ef.gy Project Members
 * \copyright
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: http://git.becquerel.org/jyujin/libefgy.git
 */

#include <iostream>

#include <ef.gy/test-case.h>
#include <ef.gy/vt100.h>
#include <ef.gy/random.h>

using namespace efgy;

/**\brief VT100 output tests
 * \test Tries to create some output on the current terminal using the vt100
 *       helpers.
 *
 * \param[out] log A stream for test cases to log messages to.
 *
 * \return Zero when everything went as expected, nonzero otherwise.
 */
int testVT100 (std::ostream &log)
{
    terminal::vt100<> output;
    random::mersenneTwister<> mt(1337);

    output.resize(output.getOSDimensions());

    std::array<std::size_t,2> s = output.size();

    log << s[0] << "x" << s[1] << "\n";

    for (unsigned int i = 0; i < 100000; i++)
    {
        std::size_t l = mt() % s[1];
        std::size_t c = mt() % s[0];
        output.target[l][c].content = mt() % (1<<7);
        output.target[l][c].foregroundColour = mt() % 256;
        output.target[l][c].backgroundColour = mt() % 256;

        if ((i % 100) == 0)
        {
            output.flush(0, 2048);
        }
    }

    int i = 0;
    std::size_t ops;
    while ((ops = output.flush()) > 0)
    {
        i++;
    }

    std::cout << "iterations: " << i << "\n";

    return 0;
}

TEST_BATCH(testVT100)
<commit_msg>this test case will mess up test output and is not too helpful since we have the 'matrix' demo to provide pretty much the same functionality<commit_after><|endoftext|>


<commit_before>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplicationRegistry.h"
#include "itksys/SystemTools.hxx"

namespace otb
{
namespace Wrapper
{

ApplicationRegistry::ApplicationRegistry()
{
}

ApplicationRegistry::~ApplicationRegistry()
{
}

void
ApplicationRegistry::SetApplicationPath(std::string newpath)
{
  std::ostringstream putEnvPath;
  putEnvPath << "ITK_AUTOLOAD_PATH=" << newpath;

  // do NOT use putenv() directly, since the string memory must be managed carefully
  itksys::SystemTools::PutEnv(putEnvPath.str().c_str());

  // Reload factories to take into account new path
  itk::ObjectFactoryBase::ReHash();
}

void
ApplicationRegistry::AddApplicationPath(std::string newpath)
{
  std::ostringstream putEnvPath;
  putEnvPath << "ITK_AUTOLOAD_PATH=";

  // Can be NULL if the env var is not set
  const char* currentEnv = itksys::SystemTools::GetEnv("ITK_AUTOLOAD_PATH");

#if defined(WIN32)
  char pathSeparator = ';';
#else
  char pathSeparator = ':';
#endif

  if (currentEnv && strlen(currentEnv) > 0)
    {
    putEnvPath << currentEnv;

    // The current value of the env var can already end with the pathSeparator
    char lastChar = currentEnv[ strlen(currentEnv) - 1 ];
    if ( lastChar != pathSeparator )
      {
      putEnvPath << pathSeparator;
      }
    }
  putEnvPath << newpath;

  std::cout << "ITK_AUTOLOAD_PATH " << putEnvPath.str() << std::endl;
  // do NOT use putenv() directly, since the string memory must be managed carefully
  itksys::SystemTools::PutEnv(putEnvPath.str().c_str());

  // Reload factories to take into account new path
  itk::ObjectFactoryBase::ReHash();

}

Application::Pointer
ApplicationRegistry::CreateApplication(const std::string& name)
{
  ApplicationPointer appli;

  std::list<ApplicationPointer> possibleApp;
  std::list<LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("otbWrapperApplication");

  // Downcast and Sanity check
  for (std::list<LightObject::Pointer>::iterator i = allobjects.begin(); i != allobjects.end(); ++i)
    {
    Application* io = dynamic_cast<Application*> (i->GetPointer());
    if (io)
      {
      possibleApp.push_back(io);
      }
    else
      {
      otbMsgDevMacro( << "Error ApplicationRegistry factory did not return an Application: " << (*i)->GetNameOfClass() << std::endl );
      }
    }

  // Return the app with the desired name
  for(std::list<ApplicationPointer>::iterator k = possibleApp.begin();
      k != possibleApp.end(); ++k)
    {
    if ( (*k)->GetName() == name )
      {
      return *k;
      }
    }

  return appli;
}

std::vector<std::string>
ApplicationRegistry::GetAvailableApplications()
{
  ApplicationPointer appli;

  std::list<ApplicationPointer> possibleApp;
  std::list<LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("otbWrapperApplication");

  // Downcast and Sanity check
  for (std::list<LightObject::Pointer>::iterator i = allobjects.begin(); i != allobjects.end(); ++i)
    {
    Application* io = dynamic_cast<Application*> (i->GetPointer());
    if (io)
      {
      possibleApp.push_back(io);
      }
    else
      {
      otbMsgDevMacro( "Error ApplicationRegistry factory did not return an Application: " << (*i)->GetNameOfClass() << std::endl );
      }
    }

  // Return the app list
  std::vector<std::string> availableApp;
  for(std::list<ApplicationPointer>::iterator k = possibleApp.begin();
      k != possibleApp.end(); ++k)
    {
    availableApp.push_back((*k)->GetName());
    }
  // If the ITK_AUTOLOAD_PATH contains
  // several times the same path, application will appears several
  // times in the list.To be cleaner, we erase multiple
  std::vector<std::string>::iterator it;
  it = std::unique(availableApp.begin(), availableApp.end());
  availableApp.resize( it - availableApp.begin() );

  return availableApp;
}

} // end namespace Wrapper
} //end namespace otb
<commit_msg>ENH: simplify code, and put the given path in front of the path list, instead of at end<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplicationRegistry.h"
#include "itksys/SystemTools.hxx"

namespace otb
{
namespace Wrapper
{

ApplicationRegistry::ApplicationRegistry()
{
}

ApplicationRegistry::~ApplicationRegistry()
{
}

void
ApplicationRegistry::SetApplicationPath(std::string newpath)
{
  std::ostringstream putEnvPath;
  putEnvPath << "ITK_AUTOLOAD_PATH=" << newpath;

  // do NOT use putenv() directly, since the string memory must be managed carefully
  itksys::SystemTools::PutEnv(putEnvPath.str().c_str());

  // Reload factories to take into account new path
  itk::ObjectFactoryBase::ReHash();
}

void
ApplicationRegistry::AddApplicationPath(std::string newpath)
{
  std::ostringstream putEnvPath;
  putEnvPath << "ITK_AUTOLOAD_PATH=";

  // Can be NULL if the env var is not set
  const char* currentEnv = itksys::SystemTools::GetEnv("ITK_AUTOLOAD_PATH");

#if defined(WIN32)
  const char pathSeparator = ';';
#else
  const char pathSeparator = ':';
#endif

  putEnvPath << newpath << pathSeparator;

  if (currentEnv)
    {
    putEnvPath << currentEnv;
    }

  // do NOT use putenv() directly, since the string memory must be managed carefully
  itksys::SystemTools::PutEnv(putEnvPath.str().c_str());

  // Reload factories to take into account new path
  itk::ObjectFactoryBase::ReHash();

}

Application::Pointer
ApplicationRegistry::CreateApplication(const std::string& name)
{
  ApplicationPointer appli;

  std::list<ApplicationPointer> possibleApp;
  std::list<LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("otbWrapperApplication");

  // Downcast and Sanity check
  for (std::list<LightObject::Pointer>::iterator i = allobjects.begin(); i != allobjects.end(); ++i)
    {
    Application* io = dynamic_cast<Application*> (i->GetPointer());
    if (io)
      {
      possibleApp.push_back(io);
      }
    else
      {
      otbMsgDevMacro( << "Error ApplicationRegistry factory did not return an Application: " << (*i)->GetNameOfClass() << std::endl );
      }
    }

  // Return the app with the desired name
  for(std::list<ApplicationPointer>::iterator k = possibleApp.begin();
      k != possibleApp.end(); ++k)
    {
    if ( (*k)->GetName() == name )
      {
      return *k;
      }
    }

  return appli;
}

std::vector<std::string>
ApplicationRegistry::GetAvailableApplications()
{
  ApplicationPointer appli;

  std::list<ApplicationPointer> possibleApp;
  std::list<LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("otbWrapperApplication");

  // Downcast and Sanity check
  for (std::list<LightObject::Pointer>::iterator i = allobjects.begin(); i != allobjects.end(); ++i)
    {
    Application* io = dynamic_cast<Application*> (i->GetPointer());
    if (io)
      {
      possibleApp.push_back(io);
      }
    else
      {
      otbMsgDevMacro( "Error ApplicationRegistry factory did not return an Application: " << (*i)->GetNameOfClass() << std::endl );
      }
    }

  // Return the app list
  std::vector<std::string> availableApp;
  for(std::list<ApplicationPointer>::iterator k = possibleApp.begin();
      k != possibleApp.end(); ++k)
    {
    availableApp.push_back((*k)->GetName());
    }
  // If the ITK_AUTOLOAD_PATH contains
  // several times the same path, application will appears several
  // times in the list.To be cleaner, we erase multiple
  std::vector<std::string>::iterator it;
  it = std::unique(availableApp.begin(), availableApp.end());
  availableApp.resize( it - availableApp.begin() );

  return availableApp;
}

} // end namespace Wrapper
} //end namespace otb
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Realm Inc.
 *
 * 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 <jni.h>
#include <jni_util/log.hpp>
#include "io_realm_RealmFileUserStore.h"
#include "sync/sync_manager.hpp"
#include "sync/sync_user.hpp"
#include "util.hpp"

using namespace realm;

static const char* ERR_NO_LOGGED_IN_USER = "No user logged in yet.";
static const char* ERR_COULD_NOT_ALLOCATE_MEMORY = "Could not allocate memory to return all users.";

JNIEXPORT jstring JNICALL
Java_io_realm_RealmFileUserStore_nativeGetCurrentUser (JNIEnv *env, jclass)
{
    TR_ENTER()
    try {

        const std::shared_ptr<SyncUser> &user = SyncManager::shared().get_current_user();
        if (user) {
            return to_jstring(env, user->refresh_token().data());
        } else {
            return nullptr;
        }
    } CATCH_STD()
    return nullptr;
}

JNIEXPORT void JNICALL
Java_io_realm_RealmFileUserStore_nativeUpdateOrCreateUser (JNIEnv *env, jclass, jstring identity, jstring jsonToken, jstring url)
{
    TR_ENTER()
    try {
        JStringAccessor user_identity(env, identity); // throws
        JStringAccessor user_json_token(env, jsonToken); // throws
        JStringAccessor auth_url(env, url); // throws

        SyncManager::shared().get_user(user_identity, user_json_token, std::string(auth_url));
    } CATCH_STD()
}

JNIEXPORT void JNICALL
Java_io_realm_RealmFileUserStore_nativeLogoutCurrentUser (JNIEnv *env, jclass)
{
    TR_ENTER()
    try {
        const std::shared_ptr<SyncUser>& user = SyncManager::shared().get_current_user();
        if (user) {
            user->log_out();
        } else {
            throw std::runtime_error(ERR_NO_LOGGED_IN_USER);
        }
    } CATCH_STD()
}

JNIEXPORT void JNICALL
Java_io_realm_RealmFileUserStore_nativeConfigureMetaDataSystem (JNIEnv *env, jclass, jstring baseFile)
{
    TR_ENTER()
    try {
        JStringAccessor base_file_path(env, baseFile); // throws
        SyncManager::shared().configure_file_system(base_file_path, SyncManager::MetadataMode::NoEncryption);
    } CATCH_STD()
}

JNIEXPORT jobjectArray JNICALL
Java_io_realm_RealmFileUserStore_nativeGetAllUsers (JNIEnv *env, jclass)
{
    TR_ENTER()
    std::vector<std::shared_ptr<SyncUser>> all_users = SyncManager::shared().all_logged_in_users();
    if (!all_users.empty()) {
        std::vector<std::shared_ptr<SyncUser>> valid_users;
        jsize array_length = std::count_if(all_users.begin(),all_users.end(),
                        [&](const std::shared_ptr<SyncUser>& user) {
                            if (user->state() == SyncUser::State::Active) {
                                valid_users.emplace_back(std::move(user));
                                return true;
                            }
                            return false;
                        });

        jobjectArray users_token = env->NewObjectArray(array_length, java_lang_string, 0);
        if (users_token == NULL) {
            ThrowException(env, OutOfMemory, ERR_COULD_NOT_ALLOCATE_MEMORY);
            return nullptr;
        }

        for (auto user : valid_users) {
            env->SetObjectArrayElement(users_token, --array_length, to_jstring(env, user->refresh_token().data()));
        }

        return users_token;
    }
    return nullptr;
}

JNIEXPORT void JNICALL
Java_io_realm_RealmFileUserStore_nativeResetForTesting (JNIEnv *, jclass)
{
    TR_ENTER();
    SyncManager::shared().reset_for_testing();
}

<commit_msg>all_logged_in_users does checking active<commit_after>/*
 * Copyright 2016 Realm Inc.
 *
 * 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 <jni.h>
#include <jni_util/log.hpp>
#include "io_realm_RealmFileUserStore.h"
#include "sync/sync_manager.hpp"
#include "sync/sync_user.hpp"
#include "util.hpp"

using namespace realm;

static const char* ERR_NO_LOGGED_IN_USER = "No user logged in yet.";
static const char* ERR_COULD_NOT_ALLOCATE_MEMORY = "Could not allocate memory to return all users.";

JNIEXPORT jstring JNICALL
Java_io_realm_RealmFileUserStore_nativeGetCurrentUser (JNIEnv *env, jclass)
{
    TR_ENTER()
    try {

        const std::shared_ptr<SyncUser> &user = SyncManager::shared().get_current_user();
        if (user) {
            return to_jstring(env, user->refresh_token().data());
        } else {
            return nullptr;
        }
    } CATCH_STD()
    return nullptr;
}

JNIEXPORT void JNICALL
Java_io_realm_RealmFileUserStore_nativeUpdateOrCreateUser (JNIEnv *env, jclass, jstring identity, jstring jsonToken, jstring url)
{
    TR_ENTER()
    try {
        JStringAccessor user_identity(env, identity); // throws
        JStringAccessor user_json_token(env, jsonToken); // throws
        JStringAccessor auth_url(env, url); // throws

        SyncManager::shared().get_user(user_identity, user_json_token, std::string(auth_url));
    } CATCH_STD()
}

JNIEXPORT void JNICALL
Java_io_realm_RealmFileUserStore_nativeLogoutCurrentUser (JNIEnv *env, jclass)
{
    TR_ENTER()
    try {
        const std::shared_ptr<SyncUser>& user = SyncManager::shared().get_current_user();
        if (user) {
            user->log_out();
        } else {
            throw std::runtime_error(ERR_NO_LOGGED_IN_USER);
        }
    } CATCH_STD()
}

JNIEXPORT void JNICALL
Java_io_realm_RealmFileUserStore_nativeConfigureMetaDataSystem (JNIEnv *env, jclass, jstring baseFile)
{
    TR_ENTER()
    try {
        JStringAccessor base_file_path(env, baseFile); // throws
        SyncManager::shared().configure_file_system(base_file_path, SyncManager::MetadataMode::NoEncryption);
    } CATCH_STD()
}

JNIEXPORT jobjectArray JNICALL
Java_io_realm_RealmFileUserStore_nativeGetAllUsers (JNIEnv *env, jclass)
{
    TR_ENTER()
    std::vector<std::shared_ptr<SyncUser>> all_users = SyncManager::shared().all_logged_in_users();
    if (!all_users.empty()) {
        size_t len = all_users.size();
        jobjectArray users_token = env->NewObjectArray(len, java_lang_string, 0);
        if (users_token == nullptr) {
            ThrowException(env, OutOfMemory, ERR_COULD_NOT_ALLOCATE_MEMORY);
            return nullptr;
        }
        for (int i = 0; i < len; ++i) {
            env->SetObjectArrayElement(users_token, i, to_jstring(env, all_users[i]->refresh_token().data()));
        }

        return users_token;
    }
    return nullptr;
}

JNIEXPORT void JNICALL
Java_io_realm_RealmFileUserStore_nativeResetForTesting (JNIEnv *, jclass)
{
    TR_ENTER();
    SyncManager::shared().reset_for_testing();
}

<|endoftext|>


<commit_before>/** @file CPropertyExtractor.cpp
 *
 *  @author Kristofer Björnson
 */

#include "../include/CPropertyExtractor.h"
#include "../include/Functions.h"
#include "../include/Util.h"

using namespace std;

namespace TBTK{

CPropertyExtractor::CPropertyExtractor(ChebyshevSolver *cSolver,
					int numCoefficients,
					int energyResolution,
					bool useGPUToCalculateCoefficients,
					bool useGPUToGenerateGreensFunctions,
					bool useLookupTable,
					double lowerBound,
					double upperBound){
	this->cSolver = cSolver;
	this->numCoefficients = numCoefficients;
	this->energyResolution = energyResolution;
	this->lowerBound = lowerBound;
	this->upperBound = upperBound;
	this->useGPUToCalculateCoefficients = useGPUToCalculateCoefficients;
	this->useGPUToGenerateGreensFunctions = useGPUToGenerateGreensFunctions;
	this->useLookupTable = useLookupTable;

	if(useLookupTable){
		cSolver->generateLookupTable(numCoefficients, energyResolution, lowerBound, upperBound);
		if(useGPUToGenerateGreensFunctions)
			cSolver->loadLookupTableGPU();
	}
	else if(useGPUToGenerateGreensFunctions){
		cout << "Error in PropertyExtractorChebyshev: useLookupTable cannot be false if useGPUToGenerateGreensFunction is true.\n";
		exit(1);
	}
}

CPropertyExtractor::~CPropertyExtractor(){
	if(useGPUToGenerateGreensFunctions)
		cSolver->destroyLookupTableGPU();
}

complex<double>* CPropertyExtractor::calculateGreensFunction(Index to, Index from, ChebyshevSolver::GreensFunctionType type){
	vector<Index> toIndices;
	toIndices.push_back(to);

	return calculateGreensFunctions(toIndices, from, type);
}

complex<double>* CPropertyExtractor::calculateGreensFunctions(vector<Index> &to, Index from, ChebyshevSolver::GreensFunctionType type){
	complex<double> *coefficients = new complex<double>[numCoefficients*to.size()];

	if(useGPUToCalculateCoefficients){
		cSolver->calculateCoefficientsGPU(to, from, coefficients, numCoefficients);
	}
	else{
		cSolver->calculateCoefficients(to, from, coefficients, numCoefficients);
//		cout << "Error in PropertyExtractorChebyshev::calculateGreensFunctions: CPU generation of coefficients not yet supported.\n";
//		exit(1);
	}

	complex<double> *greensFunction = new complex<double>[energyResolution*to.size()];

	if(useGPUToGenerateGreensFunctions){
		for(unsigned int n = 0; n < to.size(); n++){
			cSolver->generateGreensFunctionGPU(greensFunction,
								&(coefficients[n*numCoefficients]),
								type);
		}
	}
	else{
		if(useLookupTable){
			#pragma omp parallel for
			for(unsigned int n = 0; n < to.size(); n++){
				cSolver->generateGreensFunction(greensFunction,
								&(coefficients[n*numCoefficients]),
								type);
			}
		}
		else{
			#pragma omp parallel for
			for(unsigned int n = 0; n < to.size(); n++){
				cSolver->generateGreensFunction(greensFunction,
								&(coefficients[n*numCoefficients]),
								numCoefficients,
								energyResolution,
								lowerBound,
								upperBound,
								type);
			}
		}
	}

	delete [] coefficients;

	return greensFunction;
}

double* CPropertyExtractor::calculateDensity(Index pattern, Index ranges){
	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) >= 0)
			ranges.indices.at(n) = 1;
	}

	int densityArraySize = 1;
	for(unsigned int n = 0; n < ranges.indices.size(); n++){
		if(pattern.indices.at(n) < IDX_SUM_ALL)
			densityArraySize *= ranges.indices.at(n);
	}
	double *density = new double[densityArraySize];
	for(int n = 0; n < densityArraySize; n++)
		density[n] = 0.;

	calculate(calculateDensityCallback, (void*)density, pattern, ranges, 0, 1);

	return density;
}

complex<double>* CPropertyExtractor::calculateMAG(Index pattern, Index ranges){
	hint = new int[1];
	((int*)hint)[0] = -1;
	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) == IDX_SPIN){
			((int*)hint)[0] = n;
			pattern.indices.at(n) = 0;
			ranges.indices.at(n) = 1;
			break;
		}
	}
	if(((int*)hint)[0] == -1){
		cout << "Error in PropertyExtractorChebyshev::calculateMAG: No spin index indicated.\n";
		delete [] (int*)hint;
		return NULL;
	}

	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) >= 0)
			ranges.indices.at(n) = 1;
	}

	int magArraySize = 1;
	for(unsigned int n = 0; n < ranges.indices.size(); n++){
		if(pattern.indices.at(n) < IDX_SUM_ALL)
			magArraySize *= ranges.indices.at(n);
	}
	complex<double> *mag = new complex<double>[4*magArraySize];
	for(int n = 0; n < 4*magArraySize; n++)
		mag[n] = 0.;

	calculate(calculateMAGCallback, (void*)mag, pattern, ranges, 0, 1);

	delete [] (int*)hint;

	return mag;
}

double* CPropertyExtractor::calculateLDOS(Index pattern, Index ranges){
	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) >= 0)
			ranges.indices.at(n) = 1;
	}

	int ldosArraySize = 1.;
	for(unsigned int n = 0; n < ranges.indices.size(); n++){
		if(pattern.indices.at(n) < IDX_SUM_ALL)
			ldosArraySize *= ranges.indices.at(n);
	}
	double *ldos = new double[energyResolution*ldosArraySize];
	for(int n = 0; n < energyResolution*ldosArraySize; n++)
		ldos[n] = 0.;

	calculate(calculateLDOSCallback, (void*)ldos, pattern, ranges, 0, 1);

	return ldos;
}

complex<double>* CPropertyExtractor::calculateSP_LDOS(Index pattern, Index ranges){
	hint = new int[1];
	((int*)hint)[0] = -1;
	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) == IDX_SPIN){
			((int*)hint)[0] = n;
			pattern.indices.at(n) = 0;
			ranges.indices.at(n) = 1;
			break;
		}
	}
	if(((int*)hint)[0] == -1){
		cout << "Error in PropertyExtractorChebyshev::calculateSP_LDOS: No spin index indicated.\n";
		delete [] (int*)hint;
		return NULL;
	}

	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) >= 0)
			ranges.indices.at(n) = 1;
	}

	int sp_ldosArraySize = 1;
	for(unsigned int n = 0; n < ranges.indices.size(); n++){
		if(pattern.indices.at(n) < IDX_SUM_ALL)
			sp_ldosArraySize *= ranges.indices.at(n);
	}
	complex<double> *sp_ldos = new complex<double>[4*energyResolution*sp_ldosArraySize];
	for(int n = 0; n < 4*energyResolution*sp_ldosArraySize; n++)
		sp_ldos[n] = 0.;

	calculate(calculateSP_LDOSCallback, (void*)sp_ldos, pattern, ranges, 0, 1);

	delete [] (int*)hint;

	return sp_ldos;
}

void CPropertyExtractor::calculateDensityCallback(CPropertyExtractor *cb_this, void *density, const Index &index, int offset){
	complex<double> *greensFunction = cb_this->calculateGreensFunction(index, index);
	Model::Statistics statistics = cb_this->cSolver->getModel()->getStatistics();

	for(int e = 0; e < cb_this->energyResolution; e++){
		double weight;
		if(statistics == Model::Statistics::FermiDirac){
			weight = Functions::fermiDiracDistribution((2.*e/(double)cb_this->energyResolution - 1.)*cb_this->cSolver->getScaleFactor(),
									cb_this->cSolver->getModel()->getChemicalPotential(),
									cb_this->cSolver->getModel()->getTemperature());
		}
		else{
			weight = Functions::boseEinsteinDistribution((2.*e/(double)cb_this->energyResolution - 1.)*cb_this->cSolver->getScaleFactor(),
									cb_this->cSolver->getModel()->getChemicalPotential(),
									cb_this->cSolver->getModel()->getTemperature());
		}

		((double*)density)[offset] -= weight*imag(greensFunction[e])/M_PI;
	}

	delete [] greensFunction;
}

void CPropertyExtractor::calculateMAGCallback(CPropertyExtractor *cb_this, void *mag, const Index &index, int offset){
	int spinIndex = ((int*)(cb_this->hint))[0];
	Index to(index);
	Index from(index);
	complex<double> *greensFunction;
	Model::Statistics statistics = cb_this->cSolver->getModel()->getStatistics();

	for(int n = 0; n < 4; n++){
		to.indices.at(spinIndex) = n/2;		//up, up, down, down
		from.indices.at(spinIndex) = n%2;	//up, down, up, down
		greensFunction = cb_this->calculateGreensFunction(to, from);

		for(int e = 0; e < cb_this->energyResolution; e++){
			double weight;
			if(statistics == Model::Statistics::FermiDirac){
				weight = Functions::fermiDiracDistribution((2.*e/(double)cb_this->energyResolution - 1.)*cb_this->cSolver->getScaleFactor(),
										cb_this->cSolver->getModel()->getChemicalPotential(),
										cb_this->cSolver->getModel()->getTemperature());
			}
			else{
				weight = Functions::boseEinsteinDistribution((2.*e/(double)cb_this->energyResolution - 1.)*cb_this->cSolver->getScaleFactor(),
										cb_this->cSolver->getModel()->getChemicalPotential(),
										cb_this->cSolver->getModel()->getTemperature());
			}

			((complex<double>*)mag)[4*offset + n] += weight*greensFunction[e];
		}

		delete [] greensFunction;
	}
}

void CPropertyExtractor::calculateLDOSCallback(CPropertyExtractor *cb_this, void *ldos, const Index &index, int offset){
	complex<double> *greensFunction = cb_this->calculateGreensFunction(index, index);

	for(int n = 0; n < cb_this->energyResolution; n++)
		((double*)ldos)[cb_this->energyResolution*offset + n] -= imag(greensFunction[n])/M_PI;

	delete [] greensFunction;
}

void CPropertyExtractor::calculateSP_LDOSCallback(CPropertyExtractor *cb_this, void *sp_ldos, const Index &index, int offset){
	int spinIndex = ((int*)(cb_this->hint))[0];
	Index to(index);
	Index from(index);
	complex<double> *greensFunction;

	for(int n = 0; n < 4; n++){
		to.indices.at(spinIndex) = n/2;		//up, up, down, down
		from.indices.at(spinIndex) = n%2;	//up, down, up, down
		greensFunction = cb_this->calculateGreensFunction(to, from);

		for(int e = 0; e < cb_this->energyResolution; e++)
			((complex<double>*)sp_ldos)[4*cb_this->energyResolution*offset + 4*e + n] = greensFunction[e];

		delete [] greensFunction;
	}
}

void CPropertyExtractor::calculate(void (*callback)(CPropertyExtractor *cb_this, void *memory, const Index &index, int offset),
					void *memory, Index pattern, const Index &ranges, int currentOffset, int offsetMultiplier){
	int currentSubindex = pattern.indices.size()-1;
	for(; currentSubindex >= 0; currentSubindex--){
		if(pattern.indices.at(currentSubindex) < 0)
			break;
	}

	if(currentSubindex == -1){
		callback(this, memory, pattern, currentOffset);
	}
	else{
		int nextOffsetMultiplier = offsetMultiplier;
		if(pattern.indices.at(currentSubindex) < IDX_SUM_ALL)
			nextOffsetMultiplier *= ranges.indices.at(currentSubindex);
		bool isSumIndex = false;
		if(pattern.indices.at(currentSubindex) == IDX_SUM_ALL)
			isSumIndex = true;
		for(int n = 0; n < ranges.indices.at(currentSubindex); n++){
			pattern.indices.at(currentSubindex) = n;
			calculate(callback,
					memory,
					pattern,
					ranges,
					currentOffset,
					nextOffsetMultiplier
			);
			if(!isSumIndex)
				currentOffset += offsetMultiplier;
		}
	}
}

};	//End of namespace TBTK
<commit_msg>Updated CPropertyExtractor to use NonPrincipal Green's functions, avoiding spurious complex contributions to the calculated quantities<commit_after>/** @file CPropertyExtractor.cpp
 *
 *  @author Kristofer Björnson
 */

#include "../include/CPropertyExtractor.h"
#include "../include/Functions.h"
#include "../include/Util.h"

using namespace std;

namespace TBTK{

CPropertyExtractor::CPropertyExtractor(ChebyshevSolver *cSolver,
					int numCoefficients,
					int energyResolution,
					bool useGPUToCalculateCoefficients,
					bool useGPUToGenerateGreensFunctions,
					bool useLookupTable,
					double lowerBound,
					double upperBound){
	this->cSolver = cSolver;
	this->numCoefficients = numCoefficients;
	this->energyResolution = energyResolution;
	this->lowerBound = lowerBound;
	this->upperBound = upperBound;
	this->useGPUToCalculateCoefficients = useGPUToCalculateCoefficients;
	this->useGPUToGenerateGreensFunctions = useGPUToGenerateGreensFunctions;
	this->useLookupTable = useLookupTable;

	if(useLookupTable){
		cSolver->generateLookupTable(numCoefficients, energyResolution, lowerBound, upperBound);
		if(useGPUToGenerateGreensFunctions)
			cSolver->loadLookupTableGPU();
	}
	else if(useGPUToGenerateGreensFunctions){
		cout << "Error in PropertyExtractorChebyshev: useLookupTable cannot be false if useGPUToGenerateGreensFunction is true.\n";
		exit(1);
	}
}

CPropertyExtractor::~CPropertyExtractor(){
	if(useGPUToGenerateGreensFunctions)
		cSolver->destroyLookupTableGPU();
}

complex<double>* CPropertyExtractor::calculateGreensFunction(Index to, Index from, ChebyshevSolver::GreensFunctionType type){
	vector<Index> toIndices;
	toIndices.push_back(to);

	return calculateGreensFunctions(toIndices, from, type);
}

complex<double>* CPropertyExtractor::calculateGreensFunctions(vector<Index> &to, Index from, ChebyshevSolver::GreensFunctionType type){
	complex<double> *coefficients = new complex<double>[numCoefficients*to.size()];

	if(useGPUToCalculateCoefficients){
		cSolver->calculateCoefficientsGPU(to, from, coefficients, numCoefficients);
	}
	else{
		cSolver->calculateCoefficients(to, from, coefficients, numCoefficients);
//		cout << "Error in PropertyExtractorChebyshev::calculateGreensFunctions: CPU generation of coefficients not yet supported.\n";
//		exit(1);
	}

	complex<double> *greensFunction = new complex<double>[energyResolution*to.size()];

	if(useGPUToGenerateGreensFunctions){
		for(unsigned int n = 0; n < to.size(); n++){
			cSolver->generateGreensFunctionGPU(greensFunction,
								&(coefficients[n*numCoefficients]),
								type);
		}
	}
	else{
		if(useLookupTable){
			#pragma omp parallel for
			for(unsigned int n = 0; n < to.size(); n++){
				cSolver->generateGreensFunction(greensFunction,
								&(coefficients[n*numCoefficients]),
								type);
			}
		}
		else{
			#pragma omp parallel for
			for(unsigned int n = 0; n < to.size(); n++){
				cSolver->generateGreensFunction(greensFunction,
								&(coefficients[n*numCoefficients]),
								numCoefficients,
								energyResolution,
								lowerBound,
								upperBound,
								type);
			}
		}
	}

	delete [] coefficients;

	return greensFunction;
}

double* CPropertyExtractor::calculateDensity(Index pattern, Index ranges){
	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) >= 0)
			ranges.indices.at(n) = 1;
	}

	int densityArraySize = 1;
	for(unsigned int n = 0; n < ranges.indices.size(); n++){
		if(pattern.indices.at(n) < IDX_SUM_ALL)
			densityArraySize *= ranges.indices.at(n);
	}
	double *density = new double[densityArraySize];
	for(int n = 0; n < densityArraySize; n++)
		density[n] = 0.;

	calculate(calculateDensityCallback, (void*)density, pattern, ranges, 0, 1);

	return density;
}

complex<double>* CPropertyExtractor::calculateMAG(Index pattern, Index ranges){
	hint = new int[1];
	((int*)hint)[0] = -1;
	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) == IDX_SPIN){
			((int*)hint)[0] = n;
			pattern.indices.at(n) = 0;
			ranges.indices.at(n) = 1;
			break;
		}
	}
	if(((int*)hint)[0] == -1){
		cout << "Error in PropertyExtractorChebyshev::calculateMAG: No spin index indicated.\n";
		delete [] (int*)hint;
		return NULL;
	}

	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) >= 0)
			ranges.indices.at(n) = 1;
	}

	int magArraySize = 1;
	for(unsigned int n = 0; n < ranges.indices.size(); n++){
		if(pattern.indices.at(n) < IDX_SUM_ALL)
			magArraySize *= ranges.indices.at(n);
	}
	complex<double> *mag = new complex<double>[4*magArraySize];
	for(int n = 0; n < 4*magArraySize; n++)
		mag[n] = 0.;

	calculate(calculateMAGCallback, (void*)mag, pattern, ranges, 0, 1);

	delete [] (int*)hint;

	return mag;
}

double* CPropertyExtractor::calculateLDOS(Index pattern, Index ranges){
	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) >= 0)
			ranges.indices.at(n) = 1;
	}

	int ldosArraySize = 1.;
	for(unsigned int n = 0; n < ranges.indices.size(); n++){
		if(pattern.indices.at(n) < IDX_SUM_ALL)
			ldosArraySize *= ranges.indices.at(n);
	}
	double *ldos = new double[energyResolution*ldosArraySize];
	for(int n = 0; n < energyResolution*ldosArraySize; n++)
		ldos[n] = 0.;

	calculate(calculateLDOSCallback, (void*)ldos, pattern, ranges, 0, 1);

	return ldos;
}

complex<double>* CPropertyExtractor::calculateSP_LDOS(Index pattern, Index ranges){
	hint = new int[1];
	((int*)hint)[0] = -1;
	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) == IDX_SPIN){
			((int*)hint)[0] = n;
			pattern.indices.at(n) = 0;
			ranges.indices.at(n) = 1;
			break;
		}
	}
	if(((int*)hint)[0] == -1){
		cout << "Error in PropertyExtractorChebyshev::calculateSP_LDOS: No spin index indicated.\n";
		delete [] (int*)hint;
		return NULL;
	}

	for(unsigned int n = 0; n < pattern.indices.size(); n++){
		if(pattern.indices.at(n) >= 0)
			ranges.indices.at(n) = 1;
	}

	int sp_ldosArraySize = 1;
	for(unsigned int n = 0; n < ranges.indices.size(); n++){
		if(pattern.indices.at(n) < IDX_SUM_ALL)
			sp_ldosArraySize *= ranges.indices.at(n);
	}
	complex<double> *sp_ldos = new complex<double>[4*energyResolution*sp_ldosArraySize];
	for(int n = 0; n < 4*energyResolution*sp_ldosArraySize; n++)
		sp_ldos[n] = 0.;

	calculate(calculateSP_LDOSCallback, (void*)sp_ldos, pattern, ranges, 0, 1);

	delete [] (int*)hint;

	return sp_ldos;
}

void CPropertyExtractor::calculateDensityCallback(CPropertyExtractor *cb_this, void *density, const Index &index, int offset){
	complex<double> *greensFunction = cb_this->calculateGreensFunction(index, index, ChebyshevSolver::GreensFunctionType::NonPrincipal);
	Model::Statistics statistics = cb_this->cSolver->getModel()->getStatistics();

	for(int e = 0; e < cb_this->energyResolution; e++){
		double weight;
		if(statistics == Model::Statistics::FermiDirac){
			weight = Functions::fermiDiracDistribution((2.*e/(double)cb_this->energyResolution - 1.)*cb_this->cSolver->getScaleFactor(),
									cb_this->cSolver->getModel()->getChemicalPotential(),
									cb_this->cSolver->getModel()->getTemperature());
		}
		else{
			weight = Functions::boseEinsteinDistribution((2.*e/(double)cb_this->energyResolution - 1.)*cb_this->cSolver->getScaleFactor(),
									cb_this->cSolver->getModel()->getChemicalPotential(),
									cb_this->cSolver->getModel()->getTemperature());
		}

		((double*)density)[offset] -= weight*imag(greensFunction[e])/M_PI;
	}

	delete [] greensFunction;
}

void CPropertyExtractor::calculateMAGCallback(CPropertyExtractor *cb_this, void *mag, const Index &index, int offset){
	int spinIndex = ((int*)(cb_this->hint))[0];
	Index to(index);
	Index from(index);
	complex<double> *greensFunction;
	Model::Statistics statistics = cb_this->cSolver->getModel()->getStatistics();

	for(int n = 0; n < 4; n++){
		to.indices.at(spinIndex) = n/2;		//up, up, down, down
		from.indices.at(spinIndex) = n%2;	//up, down, up, down
		greensFunction = cb_this->calculateGreensFunction(to, from, ChebyshevSolver::GreensFunctionType::NonPrincipal);

		for(int e = 0; e < cb_this->energyResolution; e++){
			double weight;
			if(statistics == Model::Statistics::FermiDirac){
				weight = Functions::fermiDiracDistribution((2.*e/(double)cb_this->energyResolution - 1.)*cb_this->cSolver->getScaleFactor(),
										cb_this->cSolver->getModel()->getChemicalPotential(),
										cb_this->cSolver->getModel()->getTemperature());
			}
			else{
				weight = Functions::boseEinsteinDistribution((2.*e/(double)cb_this->energyResolution - 1.)*cb_this->cSolver->getScaleFactor(),
										cb_this->cSolver->getModel()->getChemicalPotential(),
										cb_this->cSolver->getModel()->getTemperature());
			}

			((complex<double>*)mag)[4*offset + n] += weight*greensFunction[e];
		}

		delete [] greensFunction;
	}
}

void CPropertyExtractor::calculateLDOSCallback(CPropertyExtractor *cb_this, void *ldos, const Index &index, int offset){
	complex<double> *greensFunction = cb_this->calculateGreensFunction(index, index, ChebyshevSolver::GreensFunctionType::NonPrincipal);

	for(int n = 0; n < cb_this->energyResolution; n++)
		((double*)ldos)[cb_this->energyResolution*offset + n] -= imag(greensFunction[n])/M_PI;

	delete [] greensFunction;
}

void CPropertyExtractor::calculateSP_LDOSCallback(CPropertyExtractor *cb_this, void *sp_ldos, const Index &index, int offset){
	int spinIndex = ((int*)(cb_this->hint))[0];
	Index to(index);
	Index from(index);
	complex<double> *greensFunction;

	for(int n = 0; n < 4; n++){
		to.indices.at(spinIndex) = n/2;		//up, up, down, down
		from.indices.at(spinIndex) = n%2;	//up, down, up, down
		greensFunction = cb_this->calculateGreensFunction(to, from, ChebyshevSolver::GreensFunctionType::NonPrincipal);

		for(int e = 0; e < cb_this->energyResolution; e++)
			((complex<double>*)sp_ldos)[4*cb_this->energyResolution*offset + 4*e + n] = greensFunction[e];

		delete [] greensFunction;
	}
}

void CPropertyExtractor::calculate(void (*callback)(CPropertyExtractor *cb_this, void *memory, const Index &index, int offset),
					void *memory, Index pattern, const Index &ranges, int currentOffset, int offsetMultiplier){
	int currentSubindex = pattern.indices.size()-1;
	for(; currentSubindex >= 0; currentSubindex--){
		if(pattern.indices.at(currentSubindex) < 0)
			break;
	}

	if(currentSubindex == -1){
		callback(this, memory, pattern, currentOffset);
	}
	else{
		int nextOffsetMultiplier = offsetMultiplier;
		if(pattern.indices.at(currentSubindex) < IDX_SUM_ALL)
			nextOffsetMultiplier *= ranges.indices.at(currentSubindex);
		bool isSumIndex = false;
		if(pattern.indices.at(currentSubindex) == IDX_SUM_ALL)
			isSumIndex = true;
		for(int n = 0; n < ranges.indices.at(currentSubindex); n++){
			pattern.indices.at(currentSubindex) = n;
			calculate(callback,
					memory,
					pattern,
					ranges,
					currentOffset,
					nextOffsetMultiplier
			);
			if(!isSumIndex)
				currentOffset += offsetMultiplier;
		}
	}
}

};	//End of namespace TBTK
<|endoftext|>