Coverage for src/min_circle/mosek.py: 0%

15 statements  

« prev     ^ index     » next       coverage.py v7.10.4, created at 2025-08-19 00:41 +0000

1"""MOSEK implementation for finding the minimum enclosing circle. 

2 

3This module provides functions to find the minimum enclosing circle 

4using the MOSEK Fusion optimization library. 

5""" 

6 

7from typing import Any 

8 

9import mosek.fusion as mf 

10import numpy as np 

11 

12from .utils.circle import Circle 

13 

14 

15def min_circle_mosek(points: np.ndarray, **kwargs: Any) -> Circle: 

16 """Find the minimum enclosing circle using MOSEK Fusion. 

17 

18 Uses the MOSEK Fusion API to formulate and solve the minimum enclosing circle 

19 problem as a second-order cone program (SOCP). 

20 

21 Args: 

22 points: Array of 2D points with shape (n, 2) 

23 **kwargs: Additional keyword arguments to pass to the solver 

24 

25 Returns: 

26 Circle object containing the center and radius of the minimum enclosing circle 

27 

28 Notes: 

29 Implementation based on MOSEK's minimum ellipsoid tutorial: 

30 https://github.com/MOSEK/Tutorials/blob/master/minimum-ellipsoid/minimum-ellipsoid.ipynb 

31 """ 

32 with mf.Model() as model: 

33 # Create variables for radius and center 

34 r = model.variable("Radius", 1) 

35 x = model.variable("Midpoint", [1, points.shape[1]]) 

36 

37 # Number of points 

38 k = points.shape[0] 

39 

40 # Repeat the radius and center variables for each point 

41 r0 = mf.Var.repeat(r, k) 

42 x0 = mf.Var.repeat(x, k) 

43 

44 # Create second-order cone constraints ensuring all points are within the circle 

45 model.constraint(mf.Expr.hstack(r0, mf.Expr.sub(x0, points)), mf.Domain.inQCone()) 

46 

47 # Set the objective to minimize the radius 

48 model.objective("obj", mf.ObjectiveSense.Minimize, r) 

49 

50 # Solve the optimization problem 

51 model.solve(**kwargs) 

52 

53 # Return the circle with the optimal center and radius 

54 return Circle(radius=r.level(), center=x.level())