Skip to content

Commit

Permalink
Several changes where made: (#181)
Browse files Browse the repository at this point in the history
- A class called Function2D was created to allow several types of polynomial functions to be created and used in the aspherical surfaces.
- The Poly1Drot was rewriten to use eigen instead of numpy ans some bugs were fixed, now is called PolyR
- The aspheric_lesn.py  (where the AsphericLens Component is defined), was fixed to use the new PolyR class
- The import of several clases was fixed to follow the new structure Function2D->Poly2D
- The Aperture class had a bug that created problems when used as a surface to define Components. This was fixed (the AsphericLensComponent may use Apertures in its definition)
- The Cylinder class (used to define the AsphericLens) had a bug. It was corrected
  • Loading branch information
ramezquitao authored Jan 26, 2025
1 parent c7b1de1 commit b977f64
Show file tree
Hide file tree
Showing 31 changed files with 817 additions and 314 deletions.
17 changes: 5 additions & 12 deletions pyoptools/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Enable warnings in Jupyter
import warnings
warnings.filterwarnings('always', category=DeprecationWarning)

"""
Package containing modules and submodules defining an *API* for optical
raytracing and wave propagation calculations.
"""

# Import all pyoptools packages

Expand All @@ -48,8 +41,8 @@
from pyoptools.misc.lsq import *
from pyoptools.misc.pmisc import *
from pyoptools.misc.plist import *
from pyoptools.misc.poly_2d import *
from pyoptools.misc.Poly1Drot import *
from pyoptools.misc.function_2d.poly_2d import *
from pyoptools.misc.function_2d.poly_r import *
from pyoptools.misc.resources import *

from pyoptools.raytrace.calc import *
Expand All @@ -67,9 +60,6 @@
from pyoptools.wavefront.psurfrep import *
from pyoptools.wavefront.zernike import *


#
#
# Import graphic packages This should be imported somewhere else
from pyoptools.gui.plotutils import *

Expand All @@ -78,3 +68,6 @@

# Module implemented using pythreejs
from pyoptools.gui.ipywidgets import *


warnings.filterwarnings('always', category=DeprecationWarning)
129 changes: 0 additions & 129 deletions pyoptools/misc/Poly1Drot/Poly1Drot.pyx

This file was deleted.

3 changes: 0 additions & 3 deletions pyoptools/misc/Poly1Drot/__init__.py

This file was deleted.

Empty file.
12 changes: 12 additions & 0 deletions pyoptools/misc/function_2d/function_2d.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from pyoptools.misc.cmisc.eigen cimport VectorXd, VectorXi, MatrixXd


cdef class Function2D:
"""
Base class declaration for 2D functions defined in Cartesian coordinates.
This file is for importing the `Function2D` API in other `.pyx` files.
"""
cdef double eval_cy(self, double x, double y) noexcept nogil
cdef void eval2d(self, MatrixXd& x, MatrixXd& y, MatrixXd& result) noexcept nogil
# def eval(self, double[:, ::1] x, double[:, ::1] y)
cpdef tuple[Function2D, Function2D] dxdy(self)
125 changes: 125 additions & 0 deletions pyoptools/misc/function_2d/function_2d.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from pyoptools.misc.cmisc.eigen cimport MatrixXd
from numpy import empty, float64
cimport cython

cdef class Function2D:
"""
Abstract base class for 2D functions defined in Cartesian coordinates.
This class provides a framework for representing and evaluating 2D mathematical
functions, including their partial derivatives. All concrete implementations
should inherit from this class and implement the required methods.
Notes
-----
The class provides two main evaluation methods:
- eval2d: A nogil Cython method using Eigen matrices
- eval: A Python-accessible method using NumPy arrays
Subclasses must implement:
- eval_cy: Core evaluation function
- dx: x-derivative
- dy: y-derivative
"""

cdef void eval2d(self, MatrixXd& x, MatrixXd& y, MatrixXd& result) noexcept nogil:
"""
Evaluate the function for matrices of x and y coordinates using Eigen.
Parameters
----------
x : MatrixXd&
Matrix of x coordinates
y : MatrixXd&
Matrix of y coordinates
result : MatrixXd&
Output matrix to store results
Notes
-----
This is a nogil implementation using Eigen matrices for high performance.
"""
cdef Py_ssize_t i, j, n_cols, n_rows

n_cols = x.cols()
n_rows = x.rows()
result.resize(n_rows, n_cols)

for i in range(n_rows):
for j in range(n_cols):
(<double*>(&(result(i, j))))[0] = self.eval_cy(x(i, j), y(i, j))

@cython.boundscheck(False)
@cython.wraparound(False)
def eval(self, double[:, ::1] x, double[:, ::1] y):
"""
Evaluate the function for arrays of x and y coordinates.
Parameters
----------
x : ndarray
2D array of x coordinates
y : ndarray
2D array of y coordinates
Returns
-------
ndarray
2D array containing function values at each (x,y) point
Notes
-----
This is the Python-accessible implementation using NumPy arrays.
Decorated for maximum performance with bounds checking disabled.
"""
cdef int n_rows = x.shape[0]
cdef int n_cols = x.shape[1]

z_array = empty((n_rows, n_cols), dtype=float64)
cdef double[:, ::1] z = z_array

cdef int i, j
for i in range(n_rows):
for j in range(n_cols):
z[i, j] = self.eval_cy(x[i, j], y[i, j])

return z_array

cdef double eval_cy(self, double x, double y) noexcept nogil:
"""
Core evaluation method for a single point.
Parameters
----------
x : double
x coordinate
y : double
y coordinate
Returns
-------
double
Function value at (x,y)
Notes
-----
This method must be implemented by all subclasses.
It is the fundamental evaluation method used by both eval() and eval2d().
"""
with gil:
raise NotImplementedError("Subclasses must implement eval_cy()")

cpdef tuple[Function2D, Function2D] dxdy(self):
"""
Compute both partial derivatives simultaneously.
Returns
-------
tuple[Function2D, Function2D]
A tuple containing (∂f/∂x, ∂f/∂y)
Notes
-----
This method must be implemented by all subclasses.
"""
raise NotImplementedError("Subclasses must implement dxdy()")
3 changes: 3 additions & 0 deletions pyoptools/misc/function_2d/poly_2d/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# from . import Poly2D, indices_to_powers, ord2i, pxpy2i

# __all__ = ["Poly2D", "indices_to_powers", "ord2i", "pxpy2i"]
31 changes: 31 additions & 0 deletions pyoptools/misc/function_2d/poly_2d/poly_2d.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from pyoptools.misc.cmisc.eigen cimport VectorXd, VectorXi, MatrixXd
from ..function_2d cimport Function2D

cdef class Poly2D(Function2D):
"""
Represents a 2D polynomial of the form:
f(x, y) = Σ c[i] * x^(px[i]) * y^(py[i])
where px and py are the powers of x and y respectively for each term.
"""

# Polynomial coefficients and powers
cdef VectorXi px # Power of x for each term
cdef VectorXi py # Power of y for each term
cdef VectorXd _coeff # Coefficients for each term
cdef public int order # Order (degree) of the polynomial
cdef int _num_coeff # Number of coefficients/terms in the polynomial

# Cached derivatives
cdef Poly2D dx # Cached derivative with respect to x (∂f/∂x)
cdef Poly2D dy # Cached derivative with respect to y (∂f/∂y)

# Evaluation methods
cdef double eval_cy(self, double x, double y) noexcept nogil

cpdef tuple[Function2D, Function2D] dxdy(self)

# Utility functions
cpdef int pxpy2i(int px, int py)
cpdef int ord2i(int o)
cpdef tuple[int, int] index_to_powers(int i)
cpdef tuple indices_to_powers(int[:] indices)
Loading

0 comments on commit b977f64

Please sign in to comment.