Пример #1
0
		/**
		 * @param[in] args reference set of piranha::symbol.
		 * 
		 * @return degree of the monomial.
		 * 
		 * @throws std::invalid_argument if the size of \p args is greater than one or
		 * if the size is zero and the exponent is not zero.
		 * @throws unspecified any exception thrown by piranha::math::is_zero().
		 */
		T degree(const symbol_set &args) const
		{
			if (unlikely(args.size() > 1u || (!args.size() && !math::is_zero(m_value)))) {
				piranha_throw(std::invalid_argument,"invalid symbol set");
			}
			return m_value;
		}
Пример #2
0
		void multiply(univariate_monomial &retval, const univariate_monomial<U> &other, const symbol_set &args) const
		{
			if (unlikely(args.size() > 1u || (!args.size() && (!math::is_zero(m_value) || !math::is_zero(other.m_value))))) {
				piranha_throw(std::invalid_argument,"invalid symbol set");
			}
			retval.m_value = m_value;
			retval.m_value += other.m_value;
		}
Пример #3
0
		/**
		 * A monomial is unitary if piranha::math::is_zero() on its exponent returns \p true.
		 * 
		 * @param[in] args reference set of piranha::symbol.
		 * 
		 * @return \p true if the monomial is unitary, \p false otherwise.
		 * 
		 * @throws std::invalid_argument if the size of \p args is greater than one or
		 * if the size is zero and the exponent is not zero.
		 * @throws unspecified any exception thrown by piranha::math::is_zero().
		 */
		bool is_unitary(const symbol_set &args) const
		{
			const bool is_zero = math::is_zero(m_value);
			if (unlikely(args.size() > 1u || (!args.size() && !is_zero))) {
				piranha_throw(std::invalid_argument,"invalid symbol set");
			}
			return is_zero;
		}
Пример #4
0
		/**
		 * Will print to stream a human-readable representation of the monomial.
		 * 
		 * @param[in] os target stream.
		 * @param[in] args reference set of piranha::symbol.
		 * 
		 * @throws std::invalid_argument if the size of \p args is greater than one or
		 * if the size is zero and the exponent is not zero.
		 * @throws unspecified any exception thrown by:
		 * - piranha::math::is_zero(),
		 * - construction of the exponent type from \p int,
		 * - comparison of exponents,
		 * - printing exponents to stream.
		 */
		void print(std::ostream &os, const symbol_set &args) const
		{
			if (unlikely(args.size() > 1u || (!args.size() && !math::is_zero(m_value)))) {
				piranha_throw(std::invalid_argument,"invalid symbol set");
			}
			const value_type zero(0), one(1);
			if (args.size() && m_value != zero) {
				os << args[0u].get_name();
				if (m_value != one) {
					os << "**" << m_value;
				}
			}
		}
Пример #5
0
		/**
		 * Partial degree of the monomial: only the symbols with names in \p active_args are considered during the computation
		 * of the degree. Symbols in \p active_args not appearing in \p args are not considered.
		 * 
		 * @param[in] active_args names of the symbols that will be considered in the computation of the partial degree of the monomial.
		 * @param[in] args reference set of piranha::symbol.
		 * 
		 * @return the summation of all the exponents of the monomial corresponding to the symbols in
		 * \p active_args, or <tt>value_type(0)</tt> if no symbols in \p active_args appear in \p args.
		 * 
		 * @throws std::invalid_argument if the size of \p args is greater than one or
		 * if the size is zero and the exponent is not zero.
		 * @throws unspecified any exception thrown by piranha::math::is_zero() or by constructing an instance of \p T from zero.
		 */
		T degree(const std::set<std::string> &active_args, const symbol_set &args) const
		{
			if (unlikely(args.size() > 1u || (!args.size() && !math::is_zero(m_value)))) {
				piranha_throw(std::invalid_argument,"invalid symbol set");
			}
			if (!args.size()) {
				return T(0);
			}
			piranha_assert(args.size() == 1u);
			// Look for the only symbol in active args, if we find it return its exponent.
			const bool is_present = std::binary_search(active_args.begin(),active_args.end(),args[0].get_name());
			if (is_present) {
				return m_value;
			} else {
				return T(0);
			}
		}
Пример #6
0
		/**
		 * Will print to stream a TeX representation of the monomial.
		 * 
		 * @param[in] os target stream.
		 * @param[in] args reference set of piranha::symbol.
		 * 
		 * @throws std::invalid_argument if the size of \p args is greater than one or
		 * if the size is zero and the exponent is not zero.
		 * @throws unspecified any exception thrown by:
		 * - piranha::math::is_zero() and piranha::math::negate(),
		 * - construction of the exponent type,
		 * - comparison of exponents,
		 * - printing exponents to stream.
		 */
		void print_tex(std::ostream &os, const symbol_set &args) const
		{
			if (unlikely(args.size() > 1u || (!args.size() && !math::is_zero(m_value)))) {
				piranha_throw(std::invalid_argument,"invalid symbol set");
			}
			const value_type zero(0), one(1);
			value_type copy(m_value);
			bool sign_change = false;
			if (args.size() && copy != zero) {
				if (copy < zero) {
					math::negate(copy);
					os << "\\frac{1}{";
					sign_change = true;
				}
				os << "{" << args[0u].get_name() << "}";
				if (copy != one) {
					os << "^{" << copy << "}";
				}
				if (sign_change) {
					os << "}";
				}
			}
		}
Пример #7
0
		/**
		 * Arguments merging in case of univariate monomial is meaningful only when extending a zero-arguments
		 * monomial to one argument. Therefore, this method will either throw or return a default-constructed monomial.
		 * 
		 * @param[in] orig_args original arguments.
		 * @param[in] new_args new arguments.
		 * 
		 * @return a default-constructed instance of piranha::univariate_monomial.
		 * 
		 * @throws std::invalid_argument if the size of \p new_args is different from 1 or the size of \p orig_args is not zero.
		 * @throws unspecified any exception thrown by the default constructor of piranha::univariate_monomial.
		 */
		univariate_monomial merge_args(const symbol_set &orig_args, const symbol_set &new_args) const
		{
			piranha_assert(std::is_sorted(orig_args.begin(),orig_args.end()));
			piranha_assert(std::is_sorted(new_args.begin(),new_args.end()));
			if (unlikely(new_args.size() != 1u || orig_args.size())) {
				piranha_throw(std::invalid_argument,"invalid symbol set");
			}
			piranha_assert(math::is_zero(m_value));
			// The only valid possibility here is that a monomial with zero args is extended
			// to one arg. Default construction is ok.
			return univariate_monomial();
		}
Пример #8
0
/// \brief Moves to a new state when the specified range of symbols are encountered
inline void ndfa::builder::add_with_surrogates(const symbol_set& symbols) {
    // Get the state that should be moved to by this transition
    int nextState = m_NextState;
    m_NextState = -1;
    
    // Use a new state if no state has been explicitly set
    if (nextState == -1) {
        nextState = m_Ndfa->add_state();
    }

    // If generate surrogates is turned on, and the symbol set ends outside the surrogate range
    if (m_GenerateSurrogates) {
        // Search to see if there are any surrogate ranges
        symbol_set surrogates;
        symbol_set nonSurrogates;

        // Look through the symbol set
        for (symbol_set::iterator syms = symbols.begin(); syms != symbols.end(); ++syms) {
            // Ignore empty ranges
            if (syms->lower() >= syms->upper()) continue;

            if (syms->upper() > 0x10000) {
                // Surrogate range
                if (syms->lower() <= 0xffff) {
                    // Split range
                    nonSurrogates   |= range<int>(syms->lower(), 0x10000);
                    surrogates      |= range<int>(0x10000, syms->upper());
                } else {
                    // Just a surrogate range
                    surrogates |= *syms;
                }
            } else {
                // Not a surrogate range
                nonSurrogates |= *syms;
            }
        }

        // See if there were any surrogate ranges
        if (!surrogates.empty()) {
            // Push before this surrogate
            push();

            if (!nonSurrogates.empty()) {
                // Just add a transition on the non-surrogate range
                m_Ndfa->add_transition(m_CurrentState, nonSurrogates, nextState);
            }

            // Add a surrogate transition for each surrogate range
            for (symbol_set::iterator syms = surrogates.begin(); syms != surrogates.end(); ++syms) {
                add_surrogate_transition(*syms, m_CurrentState, nextState, m_Ndfa);
            }

            // Update the current state
            m_PreviousState = m_CurrentState;
            m_CurrentState  = nextState;

            // Pop afterwards
            pop();

            // Done
            return;
        }
    }
    
    // Add the transition for these symbols
    m_Ndfa->add_transition(m_CurrentState, symbols, nextState);
    m_PreviousState = m_CurrentState;
    m_CurrentState  = nextState;
}
Пример #9
0
		/** 
		 * @param[in] args reference arguments set.
		 * 
		 * @return \p true if the size of \p args is 1 or if the size of \p args is 0 and piranha::math::is_zero()
		 * on the exponent returns \p true.
		 */
		bool is_compatible(const symbol_set &args) const noexcept(true)
		{
			const auto size = args.size();
			return (size == 1u || (!size && math::is_zero(m_value)));
		}
Пример #10
0
		/**
		 * This constructor will initialise the value of the exponent to 0.
		 * 
		 * @param[in] args set of symbols used for construction.
		 * 
		 * @throws std::invalid_argument if the size of \p args is greater than 1.
		 * @throws unspecified any exception thrown by the construction of an instance of \p T from 0.
		 */
		explicit univariate_monomial(const symbol_set &args):m_value(0)
		{
			if (unlikely(args.size() > 1u)) {
				piranha_throw(std::invalid_argument,"excessive number of symbols for univariate monomial");
			}
		}