1. Introduction à la théorie des ensembles avec SymPy
1.1. Objectif du tutoriel
Apprendre à manipuler les ensembles mathématiques en Python pour résoudre des problèmes de mathématiques discrètes, d'analyse et d'algèbre.
1.2. Installation et configuration
|
1 2 3 4 5 6 7 8 9 10 11 |
# Installation !pip install sympy # Importations principales import sympy as sp from sympy import symbols, oo, pi, E from sympy.sets import * from sympy.calculus.util import continuous_domain # Vérification de la version print(f"SymPy version: {sp.__version__}") |
2. Les ensembles de base dans SymPy
2.1. Ensembles numériques fondamentaux
|
1 2 3 4 5 6 7 8 9 10 11 |
# Ensembles de nombres de base print("Naturals:", Naturals) # ℕ = {1, 2, 3, ...} print("Naturals0:", Naturals0) # ℕ₀ = {0, 1, 2, ...} print("Integers:", Integers) # ℤ = {..., -2, -1, 0, 1, 2, ...} print("Reals:", Reals) # ℝ print("Rationals:", Rationals) # ℚ print("Complexes:", Complexes) # ℂ # Propriétés des ensembles print(f"Naturals est infini: {Naturals.is_infinite}") print(f"Cardinal de Integers: {Integers.cardinality()}") |
2.2. Création d'ensembles personnalisés
|
1 2 3 4 5 6 7 8 9 10 11 |
# Intervalle simple I1 = Interval(0, 5) # [0, 5] I2 = Interval(-2, 2, left_open=True) # (-2, 2] # Ensemble fini A = FiniteSet(1, 2, 3, 4, 5) B = FiniteSet(3, 4, 5, 6, 7) print(f"A = {A}") print(f"B = {B}") print(f"I1 = {I1}") |
3. Opérations sur les ensembles
3.1. Opérations ensemblistes de base
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# Union, intersection, différence union_AB = Union(A, B) intersection_AB = Intersection(A, B) difference_AB = A - B # ou Complement(B, A) print(f"Union A ∪ B = {union_AB}") print(f"Intersection A ∩ B = {intersection_AB}") print(f"Différence A - B = {difference_AB}") # Test d'appartenance x = symbols('x') contains_test = Contains(3, A) print(f"3 ∈ A : {contains_test}") # Sous-ensembles C = FiniteSet(1, 2) print(f"C ⊆ A : {C.is_subset(A)}") print(f"A ⊇ C : {A.is_superset(C)}") |
3.2. Opérations avancées
|
1 2 3 4 5 6 7 8 9 10 |
# Produit cartésien A_cart = FiniteSet(1, 2) B_cart = FiniteSet('a', 'b') cartesian_product = ProductSet(A_cart, B_cart) print(f"A × B = {cartesian_product}") # Puissance d'un ensemble (ensemble des parties) power_set = A.powerset() print(f"P(A) = {power_set}") print(f"Taille de P(A): {len(list(power_set))}") |
4. Travail avec les intervalles
4.1. Types d'intervalles et propriétés
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# Différents types d'intervalles closed_interval = Interval(0, 1) # [0, 1] open_interval = Interval(0, 1, True, True) # (0, 1) half_open_interval = Interval(0, 1, False, True) # [0, 1) # Intervalles infinis infinite_positive = Interval(0, oo) # [0, ∞) infinite_negative = Interval(-oo, 0) # (-∞, 0] all_reals = Interval(-oo, oo) # (-∞, ∞) print(f"[0,1] ∩ (0,1) = {Intersection(closed_interval, open_interval)}") print(f"[0,1] ∪ [1,2] = {Union(Interval(0,1), Interval(1,2))}") |
4.2. Applications des intervalles
|
1 2 3 4 5 6 7 8 9 10 |
# Résolution d'inégalités x = symbols('x') inequality_solution = Interval(-2, 2) print(f"Solution de |x| ≤ 2: {inequality_solution}") # Vérification d'appartenance test_points = [-3, -1, 0, 1, 3] for point in test_points: belongs = point in inequality_solution print(f"{point} ∈ [-2,2] : {belongs}") |
5. Ensembles conditionnels et images
5.1. ConditionSet - Ensembles définis par conditions
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
x = symbols('x', real=True) # Ensemble des solutions de x² < 4 condition_set1 = ConditionSet(x, x**2 < 4, Reals) print(f"{{x ∈ ℝ | x² < 4}} = {condition_set1}") # Ensemble des nombres pairs n = symbols('n', integer=True) even_numbers = ConditionSet(n, sp.Eq(n % 2, 0), Integers) print(f"Nombres pairs: {even_numbers}") # Vérification de conditions test_even = 4 in even_numbers test_odd = 3 in even_numbers print(f"4 est pair: {test_even}") print(f"3 est pair: {test_odd}") |
5.2. ImageSet - Images d'ensembles par des fonctions
|
1 2 3 4 5 6 7 8 9 10 11 |
# Carrés des entiers square_set = ImageSet(lambda x: x**2, Integers) print(f"{{x² | x ∈ ℤ}} = {square_set}") # Fonction linéaire linear_set = ImageSet(lambda x: 2*x + 1, Integers) print(f"{{2x+1 | x ∈ ℤ}} = {linear_set}") # Fonction trigonométrique trig_set = ImageSet(lambda x: sp.sin(x), Interval(0, pi)) print(f"{{sin(x) | x ∈ [0,π]}} = {trig_set}") |
6. Applications pratiques avancées
6.1. Domaines de fonctions
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def find_domain(expression, variable): """Trouve le domaine de définition d'une fonction""" return continuous_domain(expression, variable, Reals) x = symbols('x') # Domaines de différentes fonctions f1 = sp.sqrt(x - 1) f2 = 1/(x - 2) f3 = sp.log(x + 3) print(f"Domaine de √(x-1): {find_domain(f1, x)}") print(f"Domaine de 1/(x-2): {find_domain(f2, x)}") print(f"Domaine de ln(x+3): {find_domain(f3, x)}") |
6.2. Résolution de systèmes d'inéquations
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def solve_inequality_system(inequalities, variable): """Résout un système d'inéquations""" solution = Reals for inequality in inequalities: solution = Intersection(solution, solveset(inequality, variable, Reals)) return solution x = symbols('x', real=True) # Système: x > 0 et x < 5 et x ≠ 2 inequalities = [x > 0, x < 5, sp.Ne(x, 2)] solution = solve_inequality_system(inequalities, x) print(f"Solution du système: {solution}") |
6.3. Probabilités et espaces d'événements
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Espace probabilisable sample_space = FiniteSet(1, 2, 3, 4, 5, 6) event_A = FiniteSet(2, 4, 6) # Nombres pairs event_B = FiniteSet(1, 3, 5) # Nombres impairs event_C = FiniteSet(1, 2, 3) # Petits nombres # Opérations probabilistes union_AC = Union(event_A, event_C) intersection_AC = Intersection(event_A, event_C) complement_A = sample_space - event_A print(f"Espace: {sample_space}") print(f"A ∪ C: {union_AC}") print(f"A ∩ C: {intersection_AC}") print(f"Aᶜ: {complement_A}") |
7. Fonctions avancées et propriétés topologiques
7.1. Propriétés topologiques des ensembles
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Analyse d'intervalles interval = Interval(0, 5) print(f"Intervalle: {interval}") print(f"Bornes: {interval.boundary}") # Frontière print(f"Intérieur: {interval.interior}") # Intérieur print(f"Adhérence: {interval.closure}") # Adhérence print(f"Est ouvert: {interval.is_open}") print(f"Est fermé: {interval.is_closed}") # Ensemble vide empty_set = EmptySet print(f"Ensemble vide: {empty_set}") print(f"Cardinal de ∅: {empty_set.cardinality()}") |
7.2. Relations complexes entre ensembles
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# Ensembles complexes A = Interval(0, 3) B = Interval(1, 4) C = Interval(5, 7) print(f"A et B disjoints: {A.is_disjoint(B)}") print(f"A et C disjoints: {A.is_disjoint(C)}") print(f"A ⊆ B: {A.is_subset(B)}") print(f"A ⊇ B: {A.is_superset(B)}") # Partition def is_partition(sets, universe): """Vérifie si une famille d'ensembles forme une partition""" # Union doit être l'univers union_all = Union(*sets) if union_all != universe: return False # Ensembles deux à deux disjoints for i in range(len(sets)): for j in range(i + 1, len(sets)): if not sets[i].is_disjoint(sets[j]): return False return True # Test de partition sets_family = [Interval(0, 1), Interval(1, 2), Interval(2, 3)] print(f"Forme une partition: {is_partition(sets_family, Interval(0, 3))}") |
8. Études de cas complètes
8.1. Problème : Domaines de fonctions complexes
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
def analyze_function(expression, variable): """Analyse complète d'une fonction""" print(f"Fonction: {expression}") # Domaine domain = continuous_domain(expression, variable, Reals) print(f"Domaine: {domain}") # Image try: image = sp.calculus.util.function_range(expression, variable, domain) print(f"Image: {image}") except: print("Image: Calcul complexe") # Zéros zeros = sp.solveset(expression, variable, domain) print(f"Zéros: {zeros}") return domain x = symbols('x', real=True) # Analyse de différentes fonctions print("=== Analyse de fonctions ===") f1 = sp.sqrt(4 - x**2) analyze_function(f1, x) print("\n" + "="*40) f2 = 1/sp.sqrt(x - 1) analyze_function(f2, x) |
8.2. Problème : Optimisation sous contraintes
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def feasible_region(constraints, variables): """Détermine la région réalisable d'un problème d'optimisation""" region = Reals for constraint in constraints: region = Intersection(region, sp.solveset(constraint, variables[0], Reals)) return region x = symbols('x', real=True) # Contraintes: x ≥ 0, x ≤ 5, x² - 3x + 2 ≥ 0 constraints = [x >= 0, x <= 5, x**2 - 3*x + 2 >= 0] feasible = feasible_region(constraints, [x]) print(f"Région réalisable: {feasible}") print(f"Est bornée: {feasible.is_bounded}") |
9. Bonnes pratiques et optimisation
9.1. Conseils de performance
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Méthode efficace vs inefficace A_large = Interval(0, 1000) B_large = Interval(500, 1500) # EFFICACE: Utiliser les méthodes natives union_fast = Union(A_large, B_large) intersection_fast = Intersection(A_large, B_large) # INEFFICACE: Convertir en listes (pour grands ensembles) try: A_list = list(A_large) # Ne fonctionne pas pour les intervalles infinis B_list = list(B_large) except: print("Conversion impossible pour les intervalles infinis") print(f"Union efficace: {union_fast}") |
9.2. Gestion des erreurs courantes
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def safe_set_operation(set1, set2, operation): """Exécute une opération ensembliste avec gestion d'erreurs""" try: if operation == 'union': return Union(set1, set2) elif operation == 'intersection': return Intersection(set1, set2) elif operation == 'difference': return set1 - set2 except Exception as e: print(f"Erreur lors de l'opération {operation}: {e}") return None # Test avec différents types d'ensembles A = FiniteSet(1, 2, 3) B = Interval(0, 5) result = safe_set_operation(A, B, 'union') print(f"A ∪ B = {result}") |
10. Exercices pratiques
10.1. Exercices guidés
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
def exercice_1(): """Exercice : Opérations sur les ensembles""" A = FiniteSet(1, 3, 5, 7, 9) B = FiniteSet(2, 3, 5, 7) C = FiniteSet(1, 2, 3) # Calculer (A ∩ B) ∪ C result = Union(Intersection(A, B), C) return result def exercice_2(): """Exercice : Résolution d'inéquations""" x = symbols('x', real=True) # Résoudre: x² - 5x + 6 < 0 solution = solveset(x**2 - 5*x + 6 < 0, x, Reals) return solution def exercice_3(): """Exercice : Domaines de définition""" x = symbols('x', real=True) f = sp.sqrt(x - 1) / (x - 3) domain = continuous_domain(f, x, Reals) return domain # Solutions print("Exercice 1:", exercice_1()) print("Exercice 2:", exercice_2()) print("Exercice 3:", exercice_3()) |
10.2. Projet final : Calculateur d'ensembles
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
class SetCalculator: """Calculateur d'ensembles interactif""" def __init__(self): self.sets = {} self.variables = symbols('x y z') def create_set(self, name, set_type, *args): """Crée un ensemble""" if set_type == 'finite': self.sets[name] = FiniteSet(*args) elif set_type == 'interval': self.sets[name] = Interval(*args) elif set_type == 'condition': var, condition, base = args self.sets[name] = ConditionSet(var, condition, base) def evaluate_operation(self, expression): """Évalue une expression ensembliste""" try: # Remplace les noms d'ensembles par leurs objets for name, set_obj in self.sets.items(): expression = expression.replace(name, f'self.sets["{name}"]') return eval(expression) except Exception as e: return f"Erreur: {e}" # Utilisation du calculateur calculator = SetCalculator() calculator.create_set('A', 'finite', 1, 2, 3, 4) calculator.create_set('B', 'finite', 3, 4, 5, 6) calculator.create_set('I', 'interval', 0, 10) result = calculator.evaluate_operation('Union(A, B)') print(f"A ∪ B = {result}") |
Notes importantes
- Tous les exemples de code sont exécutables indépendamment
- Les imports doivent être faits au début de votre script
- Pensez à gérer les exceptions pour les opérations complexes
- Utilisez les méthodes natives de SymPy pour de meilleures performances


