# Path: fedjax/core/dataclasses.py
# def dataclass(clz: type):
#   def replace(self, **updates):
#   def iterate_clz(x):
#   def clz_from_iterable(meta, data):
# 
# Path: fedjax/core/util.py
# def safe_div(a, b):
#   def __getattr__(self, _):
# def import_tf():
# class FakeTensorFlowModule:
# 
# Path: fedjax/core/typing.py

# 
# Path: fedjax/core/typing.py

# 
# Path: fedjax/core/typing.py

# 
# Path: fedjax/core/typing.py



import abc
import functools
import jax
import jax.numpy as jnp
from typing import Optional, Tuple
from fedjax.core import dataclasses
from fedjax.core import util
from fedjax.core.typing import BatchExample
from fedjax.core.typing import BatchPrediction
from fedjax.core.typing import SingleExample
from fedjax.core.typing import SinglePrediction
    logits_mask = (0., 0., 0., jnp.NINF)
    metric = SequenceTokenAccuracy(logits_mask=logits_mask)
    print(metric.evaluate_example(example, prediction))
    # MeanStat(accum=3, weight=5) => 0.6

    per_position_metric = SequenceTokenAccuracy(logits_mask=logits_mask, per_position=True)
    print(per_position_metric.evaluate_example(example, prediction))
    # MeanStat(accum=[1., 0., 1., 1., 0., 0.], weight=[1., 1., 1., 1., 1., 0.]) => [1., 0., 1., 1., 0., 0.]

  Attributes:
    target_key: Key name in ``example`` for target.
    pred_key: Key name in ``prediction`` for unnormalized model output pred.
    masked_target_values: Target values that should be ignored in computation.
      This is typically used to ignore padding values in computation.
    logits_mask: Mask of shape [num_classes] to be applied for preds. This is
      typically used to discount predictions for out-of-vocabulary tokens.
    per_position: Whether to keep output statistic per position or sum across
      positions for the entire sequence.
  """
  target_key: str = 'y'
  pred_key: Optional[str] = None
  masked_target_values: Tuple[int, ...] = (0,)
  # logits_mask cannot be a jnp.ndarray nor np.ndarray because they are not
  # hashable and `Metric`s must be hashable for `evaluate_model`.
  logits_mask: Optional[Tuple[float, ...]] = None
  per_position: bool = False

  def zero(self) -> MeanStat:
    return MeanStat.new(0., 0.)


# Path: fedjax/core/dataclasses.py
# def dataclass(clz: type):
#   def replace(self, **updates):
#   def iterate_clz(x):
#   def clz_from_iterable(meta, data):
# 
# Path: fedjax/core/util.py
# def safe_div(a, b):
#   def __getattr__(self, _):
# def import_tf():
# class FakeTensorFlowModule:
# 
# Path: fedjax/core/typing.py

# 
# Path: fedjax/core/typing.py

# 
# Path: fedjax/core/typing.py

# 
# Path: fedjax/core/typing.py



# Path: fedjax/core/metrics.py
import abc
import functools
import jax
import jax.numpy as jnp
from typing import Optional, Tuple
from fedjax.core import dataclasses
from fedjax.core import util
from fedjax.core.typing import BatchExample
from fedjax.core.typing import BatchPrediction
from fedjax.core.typing import SingleExample
from fedjax.core.typing import SinglePrediction

    logits_mask = (0., 0., 0., jnp.NINF)
    metric = SequenceTokenAccuracy(logits_mask=logits_mask)
    print(metric.evaluate_example(example, prediction))
    # MeanStat(accum=3, weight=5) => 0.6

    per_position_metric = SequenceTokenAccuracy(logits_mask=logits_mask, per_position=True)
    print(per_position_metric.evaluate_example(example, prediction))
    # MeanStat(accum=[1., 0., 1., 1., 0., 0.], weight=[1., 1., 1., 1., 1., 0.]) => [1., 0., 1., 1., 0., 0.]

  Attributes:
    target_key: Key name in ``example`` for target.
    pred_key: Key name in ``prediction`` for unnormalized model output pred.
    masked_target_values: Target values that should be ignored in computation.
      This is typically used to ignore padding values in computation.
    logits_mask: Mask of shape [num_classes] to be applied for preds. This is
      typically used to discount predictions for out-of-vocabulary tokens.
    per_position: Whether to keep output statistic per position or sum across
      positions for the entire sequence.
  """
  target_key: str = 'y'
  pred_key: Optional[str] = None
  masked_target_values: Tuple[int, ...] = (0,)
  # logits_mask cannot be a jnp.ndarray nor np.ndarray because they are not
  # hashable and `Metric`s must be hashable for `evaluate_model`.
  logits_mask: Optional[Tuple[float, ...]] = None
  per_position: bool = False

  def zero(self) -> MeanStat:
    return MeanStat.new(0., 0.)


  def evaluate_example(self, example: SingleExample,