Problem Generator Examples¶
This document showcases various problem generator implementations available in the CALT library. These examples demonstrate different mathematical operations and can be used as templates for creating your own problem generators.
Reference files:
scripts/dataset_generation/sagemath/other_polynomial_problems.py
- Polynomial problem generatorsscripts/dataset_generation/sagemath/arithmetic_problem_generation.py
- Arithmetic problem generatorsscripts/dataset_generation/sagemath/transposed_matrix_problem_generation.py
- Polynomial matrix problem generators
Symbolic Problems¶
1. Sum Problem Generator¶
Problem: Given a list of polynomials $F = [f_1, f_2, ..., f_n]$, compute their sum $g = f_1 + f_2 + ... + f_n$.
Please refer to scripts/dataset_generation/sagemath/other_polynomial_problems.py
.
class SumProblemGenerator:
def __init__(
self, sampler: PolynomialSampler, min_polynomials: int, max_polynomials: int
):
self.sampler = sampler
self.min_polynomials = min_polynomials
self.max_polynomials = max_polynomials
def __call__(
self, seed: int
) -> tuple[list[MPolynomial_libsingular], MPolynomial_libsingular]:
# Set random seed for SageMath's random state
randstate.set_random_seed(seed)
# Choose number of polynomials for this sample
num_polys = randint(self.min_polynomials, self.max_polynomials)
# Generate problem polynomials using sampler
F = self.sampler.sample(num_samples=num_polys)
# Generate solution polynomial g (sum of F)
g = sum(F)
return F, g
2. GCD Problem Generator¶
Problem: Given a pair of polynomials $F = [f_1, f_2]$, compute their greatest common divisor $g = \text{GCD}(f_1, f_2)$.
Please refer to scripts/dataset_generation/sagemath/other_polynomial_problems.py
.
class GCDProblemGenerator:
def __init__(self, sampler: PolynomialSampler):
self.sampler = sampler
def __call__(
self, seed: int
) -> tuple[list[MPolynomial_libsingular], MPolynomial_libsingular]:
# Get ring from sampler
ring = self.sampler.get_ring()
# Set random seed for SageMath's random state
randstate.set_random_seed(seed)
# Generate problem polynomials using sampler
gcd, q1, q2 = self.sampler.sample(num_samples=3)
# Generate solution polynomial g (GCD of F)
_gcd = q1.gcd(q2)
gcd, q1, q2 = gcd * _gcd, ring(q1 / _gcd), ring(q2 / _gcd)
F = [gcd * q1, gcd * q2]
g = ring(gcd / gcd.lc())
return F, g
3. Product Problem Generator¶
Problem: Given a list of polynomials $F = [f_1, f_2, ..., f_n]$, compute their product $g = f_1 \times f_2 \times ... \times f_n$.
Please refer to scripts/dataset_generation/sagemath/other_polynomial_problems.py
.
class ProductProblemGenerator:
def __init__(
self, sampler: PolynomialSampler, min_polynomials: int, max_polynomials: int
):
self.sampler = sampler
self.min_polynomials = min_polynomials
self.max_polynomials = max_polynomials
def __call__(
self, seed: int
) -> tuple[list[MPolynomial_libsingular], MPolynomial_libsingular]:
# Get ring from sampler
ring = self.sampler.get_ring()
# Set random seed for SageMath's random state
randstate.set_random_seed(seed)
# Choose number of polynomials for this sample
num_polys = randint(self.min_polynomials, self.max_polynomials)
# Generate problem polynomials using sampler
F = self.sampler.sample(num_samples=num_polys)
# Generate solution polynomial g (product of F)
g = ring(1)
for f in F:
g *= f
return F, g
4. Partial Sum Problem Generator¶
Problem: Given a list of polynomials $F = [f_1, f_2, ..., f_n]$, compute partial sums $G = [g_1, g_2, ..., g_n]$ where $g_i = f_1 + f_2 + ... + f_i$.
Please refer to scripts/dataset_generation/sagemath/polynomial_problem_generation.py
.
class PartialSumProblemGenerator:
def __init__(
self, sampler: PolynomialSampler, min_polynomials: int, max_polynomials: int
):
self.sampler = sampler
self.min_polynomials = min_polynomials
self.max_polynomials = max_polynomials
def __call__(
self, seed: int
) -> tuple[list[MPolynomial_libsingular], list[MPolynomial_libsingular]]:
# Set random seed for SageMath's random state
randstate.set_random_seed(seed)
# Choose number of polynomials for this sample
num_polys = randint(self.min_polynomials, self.max_polynomials)
# Generate problem polynomials using sampler
F = self.sampler.sample(num_samples=num_polys)
# Generate partial sums for solution
G = [sum(F[: i + 1]) for i in range(len(F))]
return F, G
5. Partial Product Problem Generator¶
Problem: Given a list of polynomials $F = [f_1, f_2, ..., f_n]$, compute partial products $G = [g_1, g_2, ..., g_n]$ where $g_i = f_1 \times f_2 \times ... \times f_i$.
Please refer to scripts/dataset_generation/sagemath/other_polynomial_problems.py
.
class PartialProdProblemGenerator:
def __init__(
self, sampler: PolynomialSampler, min_polynomials: int, max_polynomials: int
):
self.sampler = sampler
self.min_polynomials = min_polynomials
self.max_polynomials = max_polynomials
def __call__(
self, seed: int
) -> tuple[list[MPolynomial_libsingular], list[MPolynomial_libsingular]]:
# Get ring from sampler
ring = self.sampler.get_ring()
# Set random seed for SageMath's random state
randstate.set_random_seed(seed)
# Choose number of polynomials for this sample
num_polys = randint(self.min_polynomials, self.max_polynomials)
# Generate problem polynomials using sampler
F = self.sampler.sample(num_samples=num_polys)
# Generate partial products for solution
G = []
current_prod = ring(1)
for f in F:
current_prod *= f
G.append(current_prod)
return F, G
6. Matrix Transpose Problem Generator¶
Problem: Given a polynomial matrix $F$, compute its transpose matrix $G = F^\mathrm{T}$.
Please refer to scripts/dataset_generation/sagemath/transposed_matrix_problem_generation.py
.
class PolyMatrixTransposeProblemGenerator:
def __init__(
self, sampler: PolynomialSampler, min_matrix_size: int, max_matrix_size: int
):
self.sampler = sampler
self.min_matrix_size = min_matrix_size
self.max_matrix_size = max_matrix_size
def __call__(
self, seed: int
) -> tuple[
list[list[MPolynomial_libsingular]], list[list[MPolynomial_libsingular]]
]:
# Set random seed for SageMath's random state
randstate.set_random_seed(seed)
# Choose matrix size for this sample
matrix_size = randint(self.min_matrix_size, self.max_matrix_size)
# Generate matrix of polynomials using sampler
matrix_list = self.sampler.sample(
size=(matrix_size, matrix_size), num_samples=1
)
_F = matrix_list[0]
# Transpose the matrix
_G = _F.transpose()
# Convert the matrix to a two-level nested list of polynomials
F = list(map(list, _F))
G = list(map(list, _G))
return F, G
Arithmetic Problems¶
Integer Factorization Problem Generator¶
Problem: Given an integer $n$, find its prime factorization as a list of prime factors in ascending order.
Please refer to scripts/dataset_generation/sagemath/arithmetic_problem_generation.py
.
class IntFactorProblemGenerator:
def __init__(self, prime_upper_bound: int, min_factors: int, max_factors: int):
self.prime_upper_bound = prime_upper_bound
self.min_factors = min_factors
self.max_factors = max_factors
self.prime_lst = list(prime_range(2, self.prime_upper_bound + 1))
def __call__(self, seed: int) -> tuple[int, list[int]]:
# Set random seed for SageMath's random state
randstate.set_random_seed(seed)
# Choose number of factors for this sample
num_factors = randint(self.min_factors, self.max_factors)
# Generate random prime factors
factors = [choice(self.prime_lst) for _ in range(num_factors)]
# Sort factors in ascending order
factors.sort()
# Calculate problem integer by multiplying factors
n = 1
for p in factors:
n *= p
return n, factors