# Path: formulaic/utils/stateful_transforms.py
# def stateful_transform(func: Callable) -> Callable:
#     """
#     Transform a callable object into a stateful transform.
# 
#     This is done by adding special arguments to the callable's signature:
#     - _state: The existing state or an empty dictionary.
#     - _metadata: Any extra metadata passed about the factor being evaluated.
#     - _spec: The `ModelSpec` instance being evaluated (or an empty `ModelSpec`).
#     If the callable has any of these in its signature, these will be passed onto
#     it; otherwise, they will be swallowed by the stateful transform wrapper.
# 
#     Stateful transforms are also transformed into single dispatches, allowing
#     different implementations for incoming data types.
# 
#     Args:
#         func: The function (or other callable) to be made into a stateful
#             transform.
# 
#     Returns:
#         The stateful transform callable.
#     """
#     func = functools.singledispatch(func)
#     params = inspect.signature(func).parameters.keys()
# 
#     @functools.wraps(func)
#     def wrapper(data, *args, _metadata=None, _state=None, _spec=None, **kwargs):
#         from formulaic.model_spec import ModelSpec
# 
#         _state = {} if _state is None else _state
#         extra_params = {}
#         if "_metadata" in params:
#             extra_params["_metadata"] = _metadata
#         if "_spec" in params:
#             extra_params["_spec"] = _spec or ModelSpec([])
# 
#         if isinstance(data, dict):
#             results = {}
#             for key, datum in data.items():
#                 if isinstance(key, str) and key.startswith("__"):
#                     results[key] = datum
#                 else:
#                     statum = _state.get(key, {})
#                     results[key] = wrapper(
#                         datum, *args, _state=statum, **extra_params, **kwargs
#                     )
#                     if statum:
#                         _state[key] = statum
#             return results
#         return func(data, *args, _state=_state, **extra_params, **kwargs)
# 
#     wrapper.__is_stateful_transform__ = True
#     return wrapper


import numpy
import scipy.sparse as spsparse
from formulaic.utils.stateful_transforms import stateful_transform
            _state["center"] = numpy.mean(data, axis=0)
        elif not isinstance(center, bool):
            _state["center"] = numpy.array(center)
        else:
            _state["center"] = None
    if _state["center"] is not None:
        data = data - _state["center"]

    # Handle scaling
    if "scale" not in _state:
        if isinstance(scale, bool) and scale:
            _state["scale"] = numpy.sqrt(
                numpy.sum(data ** 2, axis=0) / (data.shape[0] - ddof)
            )
        elif not isinstance(scale, bool):
            _state["scale"] = numpy.array(scale)
        else:
            _state["scale"] = None
    if _state["scale"] is not None:
        data = data / _state["scale"]

    return data


@scale.register(spsparse.spmatrix)
def _(data, *args, **kwargs):
    assert data.shape[1] == 1
    return scale(data.toarray()[:, 0], *args, **kwargs)



# Path: formulaic/utils/stateful_transforms.py
# def stateful_transform(func: Callable) -> Callable:
#     """
#     Transform a callable object into a stateful transform.
# 
#     This is done by adding special arguments to the callable's signature:
#     - _state: The existing state or an empty dictionary.
#     - _metadata: Any extra metadata passed about the factor being evaluated.
#     - _spec: The `ModelSpec` instance being evaluated (or an empty `ModelSpec`).
#     If the callable has any of these in its signature, these will be passed onto
#     it; otherwise, they will be swallowed by the stateful transform wrapper.
# 
#     Stateful transforms are also transformed into single dispatches, allowing
#     different implementations for incoming data types.
# 
#     Args:
#         func: The function (or other callable) to be made into a stateful
#             transform.
# 
#     Returns:
#         The stateful transform callable.
#     """
#     func = functools.singledispatch(func)
#     params = inspect.signature(func).parameters.keys()
# 
#     @functools.wraps(func)
#     def wrapper(data, *args, _metadata=None, _state=None, _spec=None, **kwargs):
#         from formulaic.model_spec import ModelSpec
# 
#         _state = {} if _state is None else _state
#         extra_params = {}
#         if "_metadata" in params:
#             extra_params["_metadata"] = _metadata
#         if "_spec" in params:
#             extra_params["_spec"] = _spec or ModelSpec([])
# 
#         if isinstance(data, dict):
#             results = {}
#             for key, datum in data.items():
#                 if isinstance(key, str) and key.startswith("__"):
#                     results[key] = datum
#                 else:
#                     statum = _state.get(key, {})
#                     results[key] = wrapper(
#                         datum, *args, _state=statum, **extra_params, **kwargs
#                     )
#                     if statum:
#                         _state[key] = statum
#             return results
#         return func(data, *args, _state=_state, **extra_params, **kwargs)
# 
#     wrapper.__is_stateful_transform__ = True
#     return wrapper


# Path: formulaic/transforms/scale.py
import numpy
import scipy.sparse as spsparse
from formulaic.utils.stateful_transforms import stateful_transform

            _state["center"] = numpy.mean(data, axis=0)
        elif not isinstance(center, bool):
            _state["center"] = numpy.array(center)
        else:
            _state["center"] = None
    if _state["center"] is not None:
        data = data - _state["center"]

    # Handle scaling
    if "scale" not in _state:
        if isinstance(scale, bool) and scale:
            _state["scale"] = numpy.sqrt(
                numpy.sum(data ** 2, axis=0) / (data.shape[0] - ddof)
            )
        elif not isinstance(scale, bool):
            _state["scale"] = numpy.array(scale)
        else:
            _state["scale"] = None
    if _state["scale"] is not None:
        data = data / _state["scale"]

    return data


@scale.register(spsparse.spmatrix)
def _(data, *args, **kwargs):
    assert data.shape[1] == 1
    return scale(data.toarray()[:, 0], *args, **kwargs)



@stateful_transform