<commit_before>/** @file gsKnotVector.hpp

    @brief Definitions of functions from gsKnotVector.h

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): <NAME>, <NAME>, <NAME>
*/

#pragma once

#include <gsNurbs/gsKnotVector.h>
#include <gsIO/gsXml.h>

#include <numeric>


namespace gismo
{

namespace internal
{

/** \brief Read a KnotVector from XML data
    \ingroup Nurbs
*/
template<class T>
class gsXml< gsKnotVector<T> >
{
private:
    gsXml() { }

public:
    GSXML_COMMON_FUNCTIONS(gsKnotVector<T>)
    GSXML_GET_POINTER(gsKnotVector<T>)
    static std::string tag () { return "KnotVector"; }
    static std::string type() { return ""; }

    static void get_into(gsXmlNode * node, gsKnotVector<T> & result)
    {
        // TODO: make it unused when possible.
        int p = atoi(node->first_attribute("degree")->value() );
        //GISMO_UNUSED(p);

        typename gsKnotVector<T>::knotContainer knotValues;

        std::istringstream str;
        str.str( node->value() );
        for (T knot; str >> knot;)
            knotValues.push_back(knot);

        result = gsKnotVector<T>(give(knotValues), p);
    }

    static gsXmlNode * put (const gsKnotVector<T> & obj, gsXmlTree & data)
    {
        // Write the knot values (for now WITH multiplicities)
        std::ostringstream str;
        str << std::setprecision(REAL_DIG+1);

        for ( typename gsKnotVector<T>::iterator it = obj.begin();
              it != obj.end(); ++it )
        {
            str << *it <<" ";
        }

        // Make a new XML KnotVector node
        gsXmlNode * tmp = internal::makeNode("KnotVector", str.str(), data);
        // Append the degree attribure
        str.str(std::string());// clean the ostream
        str<< obj.m_deg;
        tmp->append_attribute( makeAttribute("degree", str.str(),data) );

        return tmp;
    }
};

}// namespace internal


//===============//
// iterator ends //
//===============//

template<typename T>
typename gsKnotVector<T>::iterator gsKnotVector<T>::begin()  const
{
    return m_repKnots.begin();
}

template<typename T>
typename gsKnotVector<T>::iterator gsKnotVector<T>::end()    const
{
    return m_repKnots.end();
}

template<typename T>
typename gsKnotVector<T>::iterator gsKnotVector<T>::beginAt(const mult_t upos)  const
{
    return m_repKnots.begin() + (0 == upos ? 0 : m_multSum[upos-1]);
}

template<typename T>
typename gsKnotVector<T>::iterator gsKnotVector<T>::endAt(const mult_t upos)    const
{
    return m_repKnots.begin() + m_multSum[upos];
}

template<typename T>
typename gsKnotVector<T>::reverse_iterator gsKnotVector<T>::rbegin()  const
{
    return reverse_iterator(end());
}

template<typename T>
bool gsKnotVector<T>::includes(const gsKnotVector<T> & other) const
{
    return std::includes(begin(), end(), other.begin(), other.end() );
}

template<typename T>
void gsKnotVector<T>::symDifference(const gsKnotVector<T> & other,
                                    std::vector<T>& result) const
{
    // Next line is ambiguous on MSVC (std does not overload "abs" for size_t)
    // result.reserve(std::abs(other.size()-size()));

    result.clear();
    std::set_symmetric_difference(begin(), end(),
                                  other.begin(), other.end(),
                                  std::back_inserter(result));
}

template<typename T>
gsKnotVector<T> gsKnotVector<T>::knotUnion(const gsKnotVector<T> & b) const
{
    const gsKnotVector<T> & a = *this;
    knotContainer kv;
    kv.reserve( std::max(b.size(),b.size()) );
    std::set_union(a.m_repKnots.begin(), a.m_repKnots.end(),
                   b.m_repKnots.begin(), b.m_repKnots.begin(), std::back_inserter(kv) );

    // const T newStart = math::min(*a.domainBegin(), *b.domainBegin() );
    // const T newEnd   = math::max(*a.domainEnd()  , *b.domainEnd()   );
    return gsKnotVector<T>( give(kv), std::max(a.m_deg, b.m_deg) );
}

template<typename T>
gsKnotVector<T> gsKnotVector<T>::knotIntersection(const gsKnotVector<T> & b) const
{
    const gsKnotVector<T> & a = *this;
    knotContainer kv;
    kv.reserve( std::min(b.size(),b.size()) );
    std::set_intersection(a.m_repKnots.begin(), a.m_repKnots.end(),
                          b.m_repKnots.begin(), b.m_repKnots.begin(), std::back_inserter(kv) );
    return gsKnotVector<T>( give(kv), std::min(a.m_deg, b.m_deg) );
}

/*
// trim to the minimal domain such that \a dbegin and \a dend are contained
template<typename T>
const gsKnotVector<T> & gsKnotVector<T>::trimDomain(const T dbegin, const T dend) const
{
    iterator lpos = std::upper_bound(begin(), end(), dbegin) - 1; // *lpos<=dbegin
    iterator rpos = std::lower_bound(begin(), end(), dend)      ; // *rpos>=dend
    diffptr_t l = lpos  - begin() - m_deg    ;
    diffptr_t r = end() - rpos    - m_deg - 1;<commit_msg>typo<commit_after>/** @file gsKnotVector.hpp

    @brief Definitions of functions from gsKnotVector.h

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): <NAME>, <NAME>, <NAME>
*/

#pragma once

#include <gsNurbs/gsKnotVector.h>
#include <gsIO/gsXml.h>

#include <numeric>


namespace gismo
{

namespace internal
{

/** \brief Read a KnotVector from XML data
    \ingroup Nurbs
*/
template<class T>
class gsXml< gsKnotVector<T> >
{
private:
    gsXml() { }

public:
    GSXML_COMMON_FUNCTIONS(gsKnotVector<T>)
    GSXML_GET_POINTER(gsKnotVector<T>)
    static std::string tag () { return "KnotVector"; }
    static std::string type() { return ""; }

    static void get_into(gsXmlNode * node, gsKnotVector<T> & result)
    {
        // TODO: make it unused when possible.
        int p = atoi(node->first_attribute("degree")->value() );
        //GISMO_UNUSED(p);

        typename gsKnotVector<T>::knotContainer knotValues;

        std::istringstream str;
        str.str( node->value() );
        for (T knot; str >> knot;)
            knotValues.push_back(knot);

        result = gsKnotVector<T>(give(knotValues), p);
    }

    static gsXmlNode * put (const gsKnotVector<T> & obj, gsXmlTree & data)
    {
        // Write the knot values (for now WITH multiplicities)
        std::ostringstream str;
        str << std::setprecision(REAL_DIG+1);

        for ( typename gsKnotVector<T>::iterator it = obj.begin();
              it != obj.end(); ++it )
        {
            str << *it <<" ";
        }

        // Make a new XML KnotVector node
        gsXmlNode * tmp = internal::makeNode("KnotVector", str.str(), data);
        // Append the degree attribure
        str.str(std::string());// clean the ostream
        str<< obj.m_deg;
        tmp->append_attribute( makeAttribute("degree", str.str(),data) );

        return tmp;
    }
};

}// namespace internal


//===============//
// iterator ends //
//===============//

template<typename T>
typename gsKnotVector<T>::iterator gsKnotVector<T>::begin()  const
{
    return m_repKnots.begin();
}

template<typename T>
typename gsKnotVector<T>::iterator gsKnotVector<T>::end()    const
{
    return m_repKnots.end();
}

template<typename T>
typename gsKnotVector<T>::iterator gsKnotVector<T>::beginAt(const mult_t upos)  const
{
    return m_repKnots.begin() + (0 == upos ? 0 : m_multSum[upos-1]);
}

template<typename T>
typename gsKnotVector<T>::iterator gsKnotVector<T>::endAt(const mult_t upos)    const
{
    return m_repKnots.begin() + m_multSum[upos];
}

template<typename T>
typename gsKnotVector<T>::reverse_iterator gsKnotVector<T>::rbegin()  const
{
    return reverse_iterator(end());
}

template<typename T>
bool gsKnotVector<T>::includes(const gsKnotVector<T> & other) const
{
    return std::includes(begin(), end(), other.begin(), other.end() );
}

template<typename T>
void gsKnotVector<T>::symDifference(const gsKnotVector<T> & other,
                                    std::vector<T>& result) const
{
    // Next line is ambiguous on MSVC (std does not overload "abs" for size_t)
    // result.reserve(std::abs(other.size()-size()));

    result.clear();
    std::set_symmetric_difference(begin(), end(),
                                  other.begin(), other.end(),
                                  std::back_inserter(result));
}

template<typename T>
gsKnotVector<T> gsKnotVector<T>::knotUnion(const gsKnotVector<T> & b) const
{
    const gsKnotVector<T> & a = *this;
    knotContainer kv;
    kv.reserve( std::max(a.size(),b.size()) );
    std::set_union(a.m_repKnots.begin(), a.m_repKnots.end(),
                   b.m_repKnots.begin(), b.m_repKnots.begin(), std::back_inserter(kv) );

    // const T newStart = math::min(*a.domainBegin(), *b.domainBegin() );
    // const T newEnd   = math::max(*a.domainEnd()  , *b.domainEnd()   );
    return gsKnotVector<T>( give(kv), std::max(a.m_deg, b.m_deg) );
}

template<typename T>
gsKnotVector<T> gsKnotVector<T>::knotIntersection(const gsKnotVector<T> & b) const
{
    const gsKnotVector<T> & a = *this;
    knotContainer kv;
    kv.reserve( std::min(a.size(),b.size()) );
    std::set_intersection(a.m_repKnots.begin(), a.m_repKnots.end(),
                          b.m_repKnots.begin(), b.m_repKnots.begin(), std::back_inserter(kv) );
    return gsKnotVector<T>( give(kv), std::min(a.m_deg, b.m_deg) );
}

/*
// trim to the minimal domain such that \a dbegin and \a dend are contained
template<typename T>
const gsKnotVector<T> & gsKnotVector<T>::trimDomain(const T dbegin, const T dend) const
{
    iterator lpos = std::upper_bound(begin(), end(), dbegin) - 1; // *lpos<=dbegin
    iterator rpos = std::lower_bound(begin(), end(), dend)      ; // *rpos>=dend
    diffptr_t l = lpos  - begin() - m_deg    ;
    diffptr_t r = end() - rpos    - m_deg - 1;
{'fraction_non_alphanumeric': 0.15619694397283532, 'fraction_numerical': 0.001997403375611705, 'mean_word_length': 3.0923579893747446, 'pattern_counts': {'":': 0, '<': 127, '<?xml version=': 0, '>': 123, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2202178', 'n_tokens_mistral': 3578, 'n_tokens_neox': 3476, 'n_words': 771}