• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daisytuner / sdfglib / 15822095523

23 Jun 2025 10:43AM UTC coverage: 63.824% (-0.02%) from 63.84%
15822095523

push

github

web-flow
Merge pull request #99 from daisytuner/delinearization

adds support for delinearizing affine expressions

69 of 103 new or added lines in 8 files covered. (66.99%)

3 existing lines in 2 files now uncovered.

8084 of 12666 relevant lines covered (63.82%)

149.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.79
/src/symbolic/series.cpp
1
#include "sdfg/symbolic/series.h"
2

3
#include "sdfg/symbolic/extreme_values.h"
4
#include "sdfg/symbolic/polynomials.h"
5

6
namespace sdfg {
7
namespace symbolic {
8
namespace series {
9

10
bool is_monotonic_affine(const Expression& expr, const Symbol& sym, const Assumptions& assums) {
232✔
11
    SymbolVec symbols = {sym};
232✔
12
    auto poly = polynomial(expr, symbols);
232✔
13
    if (poly == SymEngine::null) {
232✔
NEW
14
        return false;
×
15
    }
16
    auto coeffs = affine_coefficients(poly, symbols);
232✔
17
    if (coeffs.empty()) {
232✔
NEW
18
        return false;
×
19
    }
20
    auto mul = minimum(coeffs[sym], {}, assums);
232✔
21
    if (mul == SymEngine::null) {
232✔
NEW
22
        return false;
×
23
    }
24
    auto offset = minimum(coeffs[symbol("__daisy_constant__")], {}, assums);
232✔
25
    if (offset == SymEngine::null) {
232✔
26
        return false;
1✔
27
    }
28
    if (!SymEngine::is_a<SymEngine::Integer>(*mul) ||
462✔
29
        !SymEngine::is_a<SymEngine::Integer>(*offset)) {
231✔
NEW
30
        return false;
×
31
    }
32
    auto mul_int = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(mul);
231✔
33
    auto offset_int = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(offset);
231✔
34
    if (mul_int->as_int() <= 0 || offset_int->as_int() <= 0) {
231✔
35
        return false;
1✔
36
    }
37

38
    return true;
230✔
39
}
232✔
40

41
bool is_monotonic_pow(const Expression& expr, const Symbol& sym, const Assumptions& assums) {
2✔
42
    if (SymEngine::is_a<SymEngine::Pow>(*expr)) {
2✔
NEW
43
        auto pow = SymEngine::rcp_dynamic_cast<const SymEngine::Pow>(expr);
×
NEW
44
        auto base = pow->get_base();
×
NEW
45
        auto exp = pow->get_exp();
×
NEW
46
        if (SymEngine::is_a<SymEngine::Integer>(*exp) &&
×
NEW
47
            SymEngine::is_a<SymEngine::Symbol>(*base)) {
×
NEW
48
            auto exp_int = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(exp);
×
NEW
49
            if (exp_int->as_int() <= 0) {
×
NEW
50
                return false;
×
51
            }
NEW
52
            auto base_sym = SymEngine::rcp_static_cast<const SymEngine::Symbol>(base);
×
NEW
53
            auto ub_sym = minimum(base_sym, {}, assums);
×
NEW
54
            if (ub_sym == SymEngine::null) {
×
NEW
55
                return false;
×
56
            }
NEW
57
            auto positive = symbolic::Ge(ub_sym, symbolic::integer(0));
×
NEW
58
            return symbolic::is_true(positive);
×
NEW
59
        }
×
NEW
60
    }
×
61

62
    return false;
2✔
63
}
2✔
64

65
bool is_monotonic(const Expression& expr, const Symbol& sym, const Assumptions& assums) {
232✔
66
    if (is_monotonic_affine(expr, sym, assums)) {
232✔
67
        return true;
230✔
68
    }
69
    return is_monotonic_pow(expr, sym, assums);
2✔
70
}
232✔
71

72
bool is_contiguous(const Expression& expr, const Symbol& sym, const Assumptions& assums) {
35✔
73
    SymbolVec symbols = {sym};
35✔
74
    auto poly = polynomial(expr, symbols);
35✔
75
    if (poly == SymEngine::null) {
35✔
NEW
76
        return false;
×
77
    }
78
    auto coeffs = affine_coefficients(poly, symbols);
35✔
79
    if (coeffs.empty()) {
35✔
NEW
80
        return false;
×
81
    }
82
    auto mul = minimum(coeffs[sym], {}, assums);
35✔
83
    if (mul == SymEngine::null) {
35✔
NEW
84
        return false;
×
85
    }
86
    auto offset = minimum(coeffs[symbol("__daisy_constant__")], {}, assums);
35✔
87
    if (offset == SymEngine::null) {
35✔
NEW
88
        return false;
×
89
    }
90
    if (!SymEngine::is_a<SymEngine::Integer>(*mul) ||
70✔
91
        !SymEngine::is_a<SymEngine::Integer>(*offset)) {
35✔
NEW
92
        return false;
×
93
    }
94
    auto mul_int = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(mul);
35✔
95
    auto offset_int = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(offset);
35✔
96
    if (mul_int->as_int() == 1 && offset_int->as_int() == 1) {
35✔
97
        return true;
33✔
98
    }
99

100
    return false;
2✔
101
}
35✔
102

103
}  // namespace series
104
}  // namespace symbolic
105
}  // namespace sdfg
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc