+// does Hoelder convolution. see [BBB] (7.0)
+cln::cl_N zeta_do_Hoelder_convolution(const std::vector<int>& m_, const std::vector<int>& s_)
+{
+ // prepare parameters
+ // holds Li arguments in [BBB] notation
+ std::vector<int> s = s_;
+ std::vector<int> m_p = m_;
+ std::vector<int> m_q;
+ // holds Li arguments in nested sums notation
+ std::vector<cln::cl_N> s_p(s.size(), cln::cl_N(1));
+ s_p[0] = s_p[0] * cln::cl_N("1/2");
+ // convert notations
+ int sig = 1;
+ for (int i=0; i<s_.size(); i++) {
+ if (s_[i] < 0) {
+ sig = -sig;
+ s_p[i] = -s_p[i];
+ }
+ s[i] = sig * std::abs(s[i]);
+ }
+ std::vector<cln::cl_N> s_q;
+ cln::cl_N signum = 1;
+
+ // first term
+ cln::cl_N res = multipleLi_do_sum(m_p, s_p);
+
+ // middle terms
+ do {
+
+ // change parameters
+ if (s.front() > 0) {
+ if (m_p.front() == 1) {
+ m_p.erase(m_p.begin());
+ s_p.erase(s_p.begin());
+ if (s_p.size() > 0) {
+ s_p.front() = s_p.front() * cln::cl_N("1/2");
+ }
+ s.erase(s.begin());
+ m_q.front()++;
+ } else {
+ m_p.front()--;
+ m_q.insert(m_q.begin(), 1);
+ if (s_q.size() > 0) {
+ s_q.front() = s_q.front() * 2;
+ }
+ s_q.insert(s_q.begin(), cln::cl_N("1/2"));
+ }
+ } else {
+ if (m_p.front() == 1) {
+ m_p.erase(m_p.begin());
+ cln::cl_N spbuf = s_p.front();
+ s_p.erase(s_p.begin());
+ if (s_p.size() > 0) {
+ s_p.front() = s_p.front() * spbuf;
+ }
+ s.erase(s.begin());
+ m_q.insert(m_q.begin(), 1);
+ if (s_q.size() > 0) {
+ s_q.front() = s_q.front() * 4;
+ }
+ s_q.insert(s_q.begin(), cln::cl_N("1/4"));
+ signum = -signum;
+ } else {
+ m_p.front()--;
+ m_q.insert(m_q.begin(), 1);
+ if (s_q.size() > 0) {
+ s_q.front() = s_q.front() * 2;
+ }
+ s_q.insert(s_q.begin(), cln::cl_N("1/2"));
+ }
+ }
+
+ // exiting the loop
+ if (m_p.size() == 0) break;
+
+ res = res + signum * multipleLi_do_sum(m_p, s_p) * multipleLi_do_sum(m_q, s_q);
+
+ } while (true);
+
+ // last term
+ res = res + signum * multipleLi_do_sum(m_q, s_q);
+
+ return res;
+}
+
+