GCC Code Coverage Report


Directory: ./
File: include/2geom/choose.h
Date: 2024-03-18 17:01:34
Exec Total Coverage
Lines: 6 9 66.7%
Functions: 2 3 66.7%
Branches: 0 0 -%

Line Branch Exec Source
1 /**
2 * \file
3 * \brief Calculation of binomial cefficients
4 *//*
5 * Copyright 2006 Nathan Hurst <njh@mail.csse.monash.edu.au>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
14 *
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
20 *
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
25 *
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
29 *
30 */
31
32 #ifndef LIB2GEOM_SEEN_CHOOSE_H
33 #define LIB2GEOM_SEEN_CHOOSE_H
34
35 #include <vector>
36
37 namespace Geom {
38
39 /**
40 * @brief Given a multiple of binomial(n, k), modify it to the same multiple of binomial(n + 1, k).
41 */
42 template <typename T>
43 constexpr void binomial_increment_n(T &b, int n, int k)
44 {
45 b = b * (n + 1) / (n + 1 - k);
46 }
47
48 /**
49 * @brief Given a multiple of binomial(n, k), modify it to the same multiple of binomial(n - 1, k).
50 */
51 template <typename T>
52 1960 constexpr void binomial_decrement_n(T &b, int n, int k)
53 {
54 1960 b = b * (n - k) / n;
55 1960 }
56
57 /**
58 * @brief Given a multiple of binomial(n, k), modify it to the same multiple of binomial(n, k + 1).
59 */
60 template <typename T>
61 475134 constexpr void binomial_increment_k(T &b, int n, int k)
62 {
63 475134 b = b * (n - k) / (k + 1);
64 475134 }
65
66 /**
67 * @brief Given a multiple of binomial(n, k), modify it to the same multiple of binomial(n, k - 1).
68 */
69 template <typename T>
70 constexpr void binomial_decrement_k(T &b, int n, int k)
71 {
72 b = b * k / (n + 1 - k);
73 }
74
75 /**
76 * @brief Calculate the (n, k)th binomial coefficient.
77 */
78 template <typename T>
79 constexpr T choose(unsigned n, unsigned k)
80 {
81 if (k > n) {
82 return 0;
83 }
84 T b = 1;
85 int max = std::min(k, n - k);
86 for (int i = 0; i < max; i++) {
87 binomial_increment_k(b, n, i);
88 }
89 return b;
90 }
91
92 /**
93 * @brief Class for calculating and accessing a row of Pascal's triangle.
94 */
95 template <typename ValueType>
96 class BinomialCoefficient
97 {
98 public:
99 using value_type = ValueType;
100 using container_type = std::vector<value_type>;
101
102 BinomialCoefficient(unsigned int _n)
103 : n(_n)
104 {
105 coefficients.reserve(n / 2 + 1);
106 coefficients.emplace_back(1);
107 value_type b = 1;
108 for (int i = 0; i < n / 2; i++) {
109 binomial_increment_k(b, n, i);
110 coefficients.emplace_back(b);
111 }
112 }
113
114 unsigned int size() const
115 {
116 return degree() + 1;
117 }
118
119 unsigned int degree() const
120 {
121 return n;
122 }
123
124 value_type operator[](unsigned int k) const
125 {
126 return coefficients[std::min(k, n - k)];
127 }
128
129 private:
130 int const n;
131 container_type coefficients;
132 };
133
134 } // namespace Geom
135
136 #endif // LIB2GEOM_SEEN_CHOOSE_H
137
138 /*
139 Local Variables:
140 mode:c++
141 c-file-style:"stroustrup"
142 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
143 indent-tabs-mode:nil
144 fill-column:99
145 End:
146 */
147 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
148