LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
monomial_order.hpp
浏览该文件的文档.
1/**
2 * @file monomial_order.hpp
3 * @brief 单项式序:Lex, GrevLex, DegLex, DegRevLex 及相关工具函数。
4 */
5#pragma once
6
7#include <vector>
8#include <numeric>
9#include <algorithm>
10#include <functional>
11
12namespace LMCAS {
13
14/** @brief 单项式类型,以整数向量表示各变量的指数 */
15using Monomial = std::vector<int>;
16
17/** @brief 单项式序的类型枚举 */
19 Lex, ///< 字典序
20 GrevLex, ///< 分次逆字典序
21 DegLex, ///< 分次字典序
22 DegRevLex ///< 分次逆字典序(同 GrevLex)
23};
24
25/**
26 * @brief 计算单项式的全次数
27 * @param m 单项式
28 * @return 各分量指数之和
29 */
30inline int total_degree(const Monomial& m) {
31 return std::accumulate(m.begin(), m.end(), 0);
32}
33
34/**
35 * @brief 计算两个单项式的最小公倍单项式
36 * @param a 第一个单项式
37 * @param b 第二个单项式
38 * @return 各分量取最大值构成的单项式
39 */
40inline Monomial lcm_monomial(const Monomial& a, const Monomial& b) {
41 Monomial result(std::max(a.size(), b.size()), 0);
42 for (size_t i = 0; i < a.size(); ++i)
43 result[i] = std::max(result[i], a[i]);
44 for (size_t i = 0; i < b.size(); ++i)
45 result[i] = std::max(result[i], b[i]);
46 return result;
47}
48
49/**
50 * @brief 判断 divisor 是否整除 target
51 * @param divisor 除数单项式
52 * @param target 被除数单项式
53 * @return divisor 的每个分量都不超过 target 对应分量时返回 true
54 */
55inline bool divides_monomial(const Monomial& divisor, const Monomial& target) {
56 if (divisor.size() > target.size()) {
57 for (size_t i = target.size(); i < divisor.size(); ++i)
58 if (divisor[i] != 0) return false;
59 }
60 for (size_t i = 0; i < std::min(divisor.size(), target.size()); ++i) {
61 if (divisor[i] > target[i]) return false;
62 }
63 return true;
64}
65
66/** @brief 单项式序比较器,支持 Lex、GrevLex、DegLex、DegRevLex */
68public:
69 /**
70 * @brief 构造指定类型的单项式序
71 * @param type 序的类型
72 */
74
75 /**
76 * @brief 比较两个单项式的大小
77 * @param a 左操作数
78 * @param b 右操作数
79 * @return a > b 时返回 true(按当前序)
80 */
81 inline bool operator()(const Monomial& a, const Monomial& b) const {
82 switch (type_) {
84 return compare_lex(a, b);
87 return compare_grevlex(a, b);
89 return compare_deglex(a, b);
90 }
91 return false;
92 }
93
94 /** @brief 获取序的类型 */
95 MonomialOrderType type() const { return type_; }
96
97 /** @brief 创建字典序 */
99
100 /** @brief 创建分次逆字典序 */
102
103 /** @brief 创建分次字典序 */
105
106 /** @brief 创建分次逆字典序(DegRevLex) */
108
109private:
111
112 static inline bool compare_lex(const Monomial& a, const Monomial& b) {
113 size_t n = std::max(a.size(), b.size());
114 for (size_t i = 0; i < n; ++i) {
115 int ai = (i < a.size()) ? a[i] : 0;
116 int bi = (i < b.size()) ? b[i] : 0;
117 if (ai != bi) return ai > bi;
118 }
119 return false;
120 }
121
122 static inline bool compare_grevlex(const Monomial& a, const Monomial& b) {
123 int deg_a = total_degree(a);
124 int deg_b = total_degree(b);
125 if (deg_a != deg_b) return deg_a > deg_b;
126
127 size_t n = std::max(a.size(), b.size());
128 for (size_t i = n; i > 0; --i) {
129 int ai = (i - 1 < a.size()) ? a[i - 1] : 0;
130 int bi = (i - 1 < b.size()) ? b[i - 1] : 0;
131 if (ai != bi) return ai < bi;
132 }
133 return false;
134 }
135
136 static inline bool compare_deglex(const Monomial& a, const Monomial& b) {
137 int deg_a = total_degree(a);
138 int deg_b = total_degree(b);
139 if (deg_a != deg_b) return deg_a > deg_b;
140 return compare_lex(a, b);
141 }
142};
143
144}
static bool compare_grevlex(const Monomial &a, const Monomial &b)
static MonomialOrder deglex()
创建分次字典序
MonomialOrderType type() const
获取序的类型
static bool compare_deglex(const Monomial &a, const Monomial &b)
static MonomialOrder lex()
创建字典序
MonomialOrder(MonomialOrderType type)
构造指定类型的单项式序
static MonomialOrder degrevlex()
创建分次逆字典序(DegRevLex)
static MonomialOrder grevlex()
创建分次逆字典序
bool operator()(const Monomial &a, const Monomial &b) const
比较两个单项式的大小
static bool compare_lex(const Monomial &a, const Monomial &b)
std::vector< int > Monomial
单项式类型,以整数向量表示各变量的指数
Monomial lcm_monomial(const Monomial &a, const Monomial &b)
计算两个单项式的最小公倍单项式
const MultiPoly & b
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
int total_degree(const Monomial &m)
计算单项式的全次数
const ExprPtr & target
bool divides_monomial(const Monomial &divisor, const Monomial &target)
判断 divisor 是否整除 target
MonomialOrderType
单项式序的类型枚举
@ DegRevLex
分次逆字典序(同 GrevLex)