
    Q3jt                         d dl Z d dlZd dlmZmZmZmZ d dlm	Z	 d dl
mZ d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZmZ d Zd Z G d d      Zy)    N)is_classifieris_clustereris_outlier_detectoris_regressor)LabelEncoder)_safe_indexing)is_pandas_dfis_polars_df)check_matplotlib_support)_get_response_values)_get_adapter_from_container)PETROFF_COLORS)type_of_target)_is_arraylike_not_scalar_num_featurescheck_is_fittedc                     t        | d      }|r%t        | j                  d         rd}t        |      |dk(  rt	        |       rd}|S g d}|S |}|S )aQ  Validate the response methods to be used with the fitted estimator.

    Parameters
    ----------
    estimator : object
        Fitted estimator to check.

    response_method : {'auto', 'decision_function', 'predict_proba', 'predict'}
        Specifies whether to use :term:`decision_function`, :term:`predict_proba`,
        :term:`predict` as the target response. If set to 'auto', the response method is
        tried in the before mentioned order.

    Returns
    -------
    prediction_method : list of str or str
        The name or list of names of the response methods to use.
    classes_r   zFMulti-label and multi-output multi-class classifiers are not supportedautopredict)decision_functionpredict_probar   )hasattrr   r   
ValueErrorr   )	estimatorresponse_methodhas_classesmsgprediction_methods        W/DATA/.local/lib/python3.12/site-packages/sklearn/inspection/_plot/decision_boundary.py_check_boundary_response_methodr!      sr    $ )Z0K/	0B0B10EFVo& 	" ) 	 !R  ,    c           	      l    ||dk  r
t         d| }nd}t        |t              r| j                  j	                         vrt        d|        j                  j                  |      }|j                  |k  rt        d| d|j                   d| d       |t        j                  d	d
|            S t        |t              rft        |      |k7  rt        d| dt        |       d      t         fd|D              rt        d|        j                  j                  |      S t        d      )av  Select colors for multiclass decision boundary display.

    Parameters
    ----------
    mpl : module
        Imported `matplotlib` module.

    multiclass_colors : str or list of matplotlib colors, default=None
        The colormap or colors to select.

        Possible inputs are:

        * None: defaults to list of accessible `Petroff colors
          <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_
          if `n_classes <= 10`, otherwise 'gist_rainbow' colormap
        * str: name of :class:`matplotlib.colors.Colormap`
        * list: list of length `n_classes` of `matplotlib colors
          <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_

    n_classes : int
        Number of colors to select.

    Returns
    -------
    colors : ndarray of shape (n_classes, 4)
        RGBA colors, one per class.

    N
   gist_rainbowzSWhen 'multiclass_colors' is a string, it must be a valid Matplotlib colormap. Got: z
Colormap 'z' only has z colors, but zv classes are to be displayed. Please specify a different colormap or provide a list of colors via 'multiclass_colors'.r      zdWhen 'multiclass_colors' is a list, it must be of the same length as the classes or labels to plot (z), got: .c              3   V   K   | ]   }j                   j                  |        " y wN)colorsis_color_like).0colmpls     r    	<genexpr>z!_select_colors.<locals>.<genexpr>x   s&     P>OsSZZ--c22>Os   &)z[When 'multiclass_colors' is a list, it can only contain valid Matplotlib color names. Got: z,'multiclass_colors' must be a list or a str.)r   
isinstancestrpyplot	colormapsr   get_cmapNnplinspacelistlenanyr*   to_rgba_array	TypeError)r.   multiclass_colors	n_classescmaps   `   r    _select_colorsr@   :   sm   <   ? .z	 : .#S)CJJ$8$8$::-->,?A  zz""#4566I./{466(-+ ''  BKK1i011	%t	, !Y.<<E;h()*!- 
 P>OPP11B0CE  zz''(9:: FGGr"   c                   N    e Zd ZdZdddddZddZedddd	dddddd
	d       Zy)DecisionBoundaryDisplaya  Decisions boundary visualization.

    It is recommended to use
    :func:`~sklearn.inspection.DecisionBoundaryDisplay.from_estimator`
    to create a :class:`DecisionBoundaryDisplay`. All parameters are stored as
    attributes.

    Read more in the :ref:`User Guide <visualizations>`.

    For a detailed example comparing the decision boundaries of multinomial and
    one-vs-rest logistic regression, please see
    :ref:`sphx_glr_auto_examples_linear_model_plot_logistic_multinomial.py`.

    .. versionadded:: 1.1

    Parameters
    ----------
    xx0 : ndarray of shape (grid_resolution, grid_resolution)
        First output of :func:`meshgrid <numpy.meshgrid>`.

    xx1 : ndarray of shape (grid_resolution, grid_resolution)
        Second output of :func:`meshgrid <numpy.meshgrid>`.

    n_classes : int
        Expected number of unique classes or labels if `response` was generated by a
        :term:`classifier` or a :term:`clusterer`.

        For :term:`outlier detectors`, `n_classes` should be set to 2 by definition
        (inlier or outlier).

        For :term:`regressors`, `n_classes` should also be set to 2 by convention
        (continuous responses are displayed the same way as unthresholded binary
        responses).

        .. versionadded:: 1.9

    response : ndarray of shape (grid_resolution, grid_resolution) or             (grid_resolution, grid_resolution, n_classes)
        Values of the response function.

    multiclass_colors : str or list of matplotlib colors, default=None
        Specifies how to color each class when plotting all classes of
        :term:`multiclass` problems.

        Possible inputs are:

        * None: defaults to list of accessible `Petroff colors
          <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_
          if `n_classes <= 10`, otherwise 'gist_rainbow' colormap
        * str: name of :class:`matplotlib.colors.Colormap`
        * list: list of length `n_classes` of `matplotlib colors
          <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_

        Single color (fading to white) colormaps will be generated from the colors in
        the list or colors taken from the colormap, and passed to the `cmap` parameter
        of the `plot_method`.

        When `response_method='predict'` and `plot_method='contour'`,
        `multiclass_colors` is ignored and the class boundaries are plotted in black
        instead as the boundary lines may overlap and the colors don't necessarily
        correspond to the classes.

        For :term:`binary` problems, `multiclass_colors` is also ignored and `cmap` or
        `colors` can be passed as kwargs instead, otherwise, the default colormap
        ('viridis') is used.

        .. versionadded:: 1.7
        .. versionchanged:: 1.9
            `multiclass_colors` is now also used when `response_method="predict"`,
            except for when `plot_method='contour'`, where it is ignored and "black" is
            used instead.
            The default colors changed from 'tab10' to the more accessible `Petroff
            colors <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_.

    xlabel : str, default=None
        Default label to place on x axis.

    ylabel : str, default=None
        Default label to place on y axis.

    Attributes
    ----------
    surface_ : matplotlib `QuadContourSet` or `QuadMesh` or list of such objects
        If `plot_method` is 'contour' or 'contourf', `surface_` is
        :class:`QuadContourSet <matplotlib.contour.QuadContourSet>`. If
        `plot_method` is 'pcolormesh', `surface_` is
        :class:`QuadMesh <matplotlib.collections.QuadMesh>`.

    multiclass_colors_ : array of shape (n_classes, 4)
        Colors used to plot each class in multiclass problems.
        Only defined when `n_classes` > 2.

        .. versionadded:: 1.7

    ax_ : matplotlib Axes
        Axes with decision boundary.

    figure_ : matplotlib Figure
        Figure containing the decision boundary.

    See Also
    --------
    DecisionBoundaryDisplay.from_estimator : Plot decision boundary given an estimator.

    Examples
    --------
    >>> import matplotlib.pyplot as plt
    >>> import matplotlib as mpl
    >>> import numpy as np
    >>> from sklearn.linear_model import LogisticRegression
    >>> from sklearn.inspection import DecisionBoundaryDisplay
    >>> data = np.array([[0, 0], [1, 1], [2, 1], [2, 2], [3, 2], [3, 3]])
    >>> target = np.arange(data.shape[0])
    >>> clf = LogisticRegression().fit(data, target)
    >>> plot_methods = ["contourf", "contour", "pcolormesh"]
    >>> response_methods = ["predict_proba", "decision_function", "predict"]
    >>> _, axes = plt.subplots(
    ...     nrows=3,
    ...     ncols=3,
    ...     figsize=(12, 12),
    ...     constrained_layout=True
    ... )
    >>> for plot_method_idx, plot_method in enumerate(plot_methods):
    ...     for response_method_idx, response_method in enumerate(response_methods):
    ...         ax = axes[plot_method_idx, response_method_idx]
    ...         display = DecisionBoundaryDisplay.from_estimator(
    ...             clf,
    ...             data,
    ...             grid_resolution=300,
    ...             response_method=response_method,
    ...             plot_method=plot_method,
    ...             ax=ax,
    ...             alpha=0.5,
    ...         )
    ...         cmap = mpl.colors.ListedColormap(display.multiclass_colors_)
    ...         ax.scatter(
    ...             data[:, 0],
    ...             data[:, 1],
    ...             c=target.astype(int),
    ...             edgecolors="black",
    ...             cmap=cmap,
    ...         )
    ...         ax.set_title(
    ...             f"plot_method={plot_method}\nresponse_method={response_method}"
    ...         )
    >>> plt.show()
    N)r=   xlabelylabelc                f    || _         || _        || _        || _        || _        || _        || _        y r)   xx0xx1r>   responser=   rC   rD   )selfrG   rH   r>   rI   r=   rC   rD   s           r    __init__z DecisionBoundaryDisplay.__init__  s6     " !2r"   contourfc                    t        d       ddl}ddlm} |dvrt	        d| d      ||j                         \  }}t        ||      }	| j                  dk(  r0 |	| j                  | j                  | j                  fi || _        ndD ]#  }
|
|v st        j                  d	|
 d
       ||
= % t        || j                  | j                        | _        d|vrd|d<   | j                  j"                  dk(  r~t%        | j                         D cg c]9  \  }\  }}}}|j&                  j(                  j+                  d| d|||dfg      ; }}}}}}g | _        t%        |      D ]  \  }}t,        j.                  j1                  | j                  dddd|f   | j                  j3                  d      |k7        }| j                  j5                   |	| j                  | j                  |fd|i|        |dk(  rp| j                  j5                   |	| j                  | j                  | j                  j3                  d      ddt-        j6                  | j                                     n| j                  j"                  dk(  rd|vrU|dk(  r#t-        j6                  | j                        |d<   n-|dk(  r(t-        j6                  | j                  dz         dz
  |d<   |dk(  r1 |	| j                  | j                  | j                  fddi|| _        nU|j&                  j9                  | j                         } |	| j                  | j                  | j                  fd|i|| _        ||j;                         s!|| j<                  n|}|j?                  |       ||jA                         s!|| jB                  n|}|jE                  |       || _#        |jH                  | _%        | S c c}}}}}w )a  Plot visualization.

        Parameters
        ----------
        plot_method : {'contourf', 'contour', 'pcolormesh'}, default='contourf'
            Plotting method to call when plotting the response. Please refer
            to the following matplotlib documentation for details:
            :func:`contourf <matplotlib.pyplot.contourf>`,
            :func:`contour <matplotlib.pyplot.contour>`,
            :func:`pcolormesh <matplotlib.pyplot.pcolormesh>`.

        ax : Matplotlib axes, default=None
            Axes object to plot on. If `None`, a new figure and axes is
            created.

        xlabel : str, default=None
            Overwrite the x-axis label.

        ylabel : str, default=None
            Overwrite the y-axis label.

        **kwargs : dict
            Additional keyword arguments to be passed to the `plot_method`. For
            :term:`binary` problems, `cmap` or `colors` can be set here to specify the
            colormap or colors, otherwise the default colormap ('viridis') is used. If
            not specified by the user, `zorder` is set to -1 to ensure that the decision
            boundary is plotted in the background (in case a scatter plot is added on
            top).

        Returns
        -------
        display: :class:`~sklearn.inspection.DecisionBoundaryDisplay`
            Object that stores computed values.

        See Also
        --------
        DecisionBoundaryDisplay.from_estimator : Plot decision boundary given an
            estimator.

        Examples
        --------
        >>> import matplotlib as mpl
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np
        >>> from sklearn.datasets import load_iris
        >>> from sklearn.inspection import DecisionBoundaryDisplay
        >>> from sklearn.tree import DecisionTreeClassifier
        >>> iris = load_iris()
        >>> feature_1, feature_2 = np.meshgrid(
        ...     np.linspace(iris.data[:, 0].min(), iris.data[:, 0].max()),
        ...     np.linspace(iris.data[:, 1].min(), iris.data[:, 1].max())
        ... )
        >>> grid = np.vstack([feature_1.ravel(), feature_2.ravel()]).T
        >>> tree = DecisionTreeClassifier().fit(iris.data[:, :2], iris.target)
        >>> y_pred = np.reshape(tree.predict(grid), feature_1.shape)
        >>> display = DecisionBoundaryDisplay(
        ...     xx0=feature_1,
        ...     xx1=feature_2,
        ...     n_classes=len(tree.classes_),
        ...     response=y_pred
        ... )
        >>> display.plot()
        <...>
        >>> display.ax_.scatter(
        ...     iris.data[:, 0],
        ...     iris.data[:, 1],
        ...     c=iris.target,
        ...     cmap=mpl.colors.ListedColormap(display.multiclass_colors_),
        ...     edgecolor="black"
        ... )
        <...>
        >>> plt.show()
        zDecisionBoundaryDisplay.plotr   NrL   contour
pcolormeshz@plot_method must be 'contourf', 'contour', or 'pcolormesh'. Got 	 instead.   )r?   r*   'zD' is ignored in favor of 'multiclass_colors' in the multiclass case.zorder   	colormap_)      ?rX   rX   rX   rX   axis)maskr?   rO   black)r*   rT   levelsr]   rL   r&   g      ?r*   )&r   
matplotlibmatplotlib.pyplotr2   r   subplotsgetattrr>   rG   rH   rI   surface_warningswarnr@   r=   multiclass_colors_ndim	enumerater*   LinearSegmentedColormap	from_listr6   maarrayargmaxappendarangeListedColormap
get_xlabelrC   
set_xlabel
get_ylabelrD   
set_ylabelax_figurefigure_)rJ   plot_methodaxrC   rD   kwargsr.   plt_	plot_funckwarg	class_idxrgbmulticlass_cmapsr?   rI   s                     r    plotzDecisionBoundaryDisplay.plot+  s   T 	!!?@ 'CC"m9. 
 :LLNEArB,	>>Q%dhh$--R6RDM+F?MME7 #2 2 u , '5T++T^^'D# v%#%x }}!!Q& 4=T=T=T3U$
 4V/	<Aq!Q	 JJ66@@#I;/-1a~> 4V ! $ !#'01A'BOIt!uu{{aIo6"mm222:iG  +  H MM((!$((DHHhTTTVT (C )+MM((! HH HH MM00a08#*#%#%99T^^#<
 ##q(6)"i/+-99T^^+Dx($
2+-99T^^a5G+H3+Nx()+$-$((DMM%BI%MS%DM
 ::44T5L5LMD$-$((DMM%@D%HN%DM R]]_$*NT[[FMM&!R]]_$*NT[[FMM&!yyw$s   >O5d   rX   r   )	grid_resolutionepsrw   r   class_of_interestr=   rC   rD   rx   c       	   	      @   t        |       |dkD  st        d| d      |dk\  st        d| d      d}||vr#dj                  |      }t        d| d	| d      t        |      }|d
k7  rt        d| d      t	        |dd      t	        |dd      }}|j                         |z
  |j                         |z   }}|j                         |z
  |j                         |z   }}t        j                  t        j                  |||      t        j                  |||            \  }}t        j                  |j                         |j                         f   }t        |      st        |      r)t        |      }|j                  |||j                         }t#        ||      }|5t%        |d      r)||j&                  vrt        d| d|j&                         t)        ||||d      \  }}}|dk(  r8t%        |d      r,t+               }|j&                  |_        |j-                  |      }|t/        |      st1        |      rd
}nt3        |      r"t%        |d      rt5        |j&                        }nt7        |      r5t%        |d      r)t5        t        j8                  |j:                              }nYt=        |      } | dv rd
}nG| dk(  rt5        t        j8                  |            }n#t        d|j>                  j@                   d      |jB                  dk(  r |jD                  |jF                   }nt/        |      rt        d      |Ft        jH                  |j&                  |k(        d   }! |dd|!f   jD                  |jF                   }n+ |jD                  g |jF                  |jF                  d    }|	t%        |d      r|j                   d   nd}	|
t%        |d      r|j                   d   nd}
 | ||||||	|
      }" |"jJ                  d ||d|S )!a.  Plot decision boundary given an estimator.

        Read more in the :ref:`User Guide <visualizations>`.

        Parameters
        ----------
        estimator : object
            Trained estimator used to plot the decision boundary.

        X : {array-like, sparse matrix, dataframe} of shape (n_samples, 2)
            Input data that should be only 2-dimensional.

        grid_resolution : int, default=100
            Number of grid points to use for plotting decision boundary.
            Higher values will make the plot look nicer but be slower to
            render.

        eps : float, default=1.0
            Extends the minimum and maximum values of X for evaluating the
            response function.

        plot_method : {'contourf', 'contour', 'pcolormesh'}, default='contourf'
            Plotting method to call when plotting the response. Please refer
            to the following matplotlib documentation for details:
            :func:`contourf <matplotlib.pyplot.contourf>`,
            :func:`contour <matplotlib.pyplot.contour>`,
            :func:`pcolormesh <matplotlib.pyplot.pcolormesh>`.

        response_method : {'auto', 'decision_function', 'predict_proba',                 'predict'}, default='auto'
            Specifies whether to use :term:`decision_function`,
            :term:`predict_proba` or :term:`predict` as the target response.
            If set to 'auto', the response method is tried in the order as
            listed above.

            .. versionchanged:: 1.6
                For multiclass problems, 'auto' no longer defaults to 'predict'.

        class_of_interest : int, float, bool or str, default=None
            The class to be plotted. For :term:`binary` classifiers, if None,
            `estimator.classes_[1]` is considered the positive class. For
            :term:`multiclass` classifiers, if None, all classes will be represented in
            the decision boundary plot; when `response_method` is :term:`predict_proba`
            or :term:`decision_function`, the class with the highest response value
            at each point is plotted. The color of each class can be set via
            `multiclass_colors`.

            .. versionadded:: 1.4

        multiclass_colors : str or list of matplotlib colors, default=None
            Specifies how to color each class when plotting :term:`multiclass` problems
            and `class_of_interest` is None.

            Possible inputs are:

            * None: defaults to list of accessible `Petroff colors
              <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_
              if `n_classes <= 10`, otherwise 'gist_rainbow' colormap
            * str: name of :class:`matplotlib.colors.Colormap`
            * list: list of length `n_classes` of `matplotlib colors
              <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_

            Single color (fading to white) colormaps will be generated from the colors
            in the list or colors taken from the colormap, and passed to the `cmap`
            parameter of the `plot_method`.

            When `response_method='predict'` and `plot_method='contour'`,
            `multiclass_colors` is ignored and the class boundaries are plotted in black
            instead as the boundary lines may overlap and the colors don't necessarily
            correspond to the classes.

            For :term:`binary` problems, `multiclass_colors` is also ignored and `cmap`
            or `colors` can be passed as kwargs instead, otherwise, the default colormap
            ('viridis') is used.

            .. versionadded:: 1.7
            .. versionchanged:: 1.9
                `multiclass_colors` is now also used when `response_method="predict"`,
                except for when `plot_method='contour'`, where it is ignored and "black"
                is used instead.
                The default colors changed from 'tab10' to the more accessible `Petroff
                colors <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_.

        xlabel : str, default=None
            The label used for the x-axis. If `None`, an attempt is made to
            extract a label from `X` if it is a dataframe, otherwise an empty
            string is used.

        ylabel : str, default=None
            The label used for the y-axis. If `None`, an attempt is made to
            extract a label from `X` if it is a dataframe, otherwise an empty
            string is used.

        ax : Matplotlib axes, default=None
            Axes object to plot on. If `None`, a new figure and axes is
            created.

        **kwargs : dict
            Additional keyword arguments to be passed to the `plot_method`.

        Returns
        -------
        display : :class:`~sklearn.inspection.DecisionBoundaryDisplay`
            Object that stores the result.

        See Also
        --------
        DecisionBoundaryDisplay : Decision boundary visualization.
        sklearn.metrics.ConfusionMatrixDisplay.from_estimator : Plot the
            confusion matrix given an estimator, the data, and the label.
        sklearn.metrics.ConfusionMatrixDisplay.from_predictions : Plot the
            confusion matrix given the true and predicted labels.

        Examples
        --------
        >>> import matplotlib as mpl
        >>> import matplotlib.pyplot as plt
        >>> from sklearn.datasets import load_iris
        >>> from sklearn.linear_model import LogisticRegression
        >>> from sklearn.inspection import DecisionBoundaryDisplay
        >>> iris = load_iris()
        >>> X = iris.data[:, :2]
        >>> classifier = LogisticRegression().fit(X, iris.target)
        >>> disp = DecisionBoundaryDisplay.from_estimator(
        ...     classifier, X, response_method="predict",
        ...     xlabel=iris.feature_names[0], ylabel=iris.feature_names[1],
        ...     alpha=0.5,
        ... )
        >>> cmap = mpl.colors.ListedColormap(disp.multiclass_colors_)
        >>> disp.ax_.scatter(X[:, 0], X[:, 1], c=iris.target, edgecolor="k", cmap=cmap)
        <...>
        >>> plt.show()
        r&   z,grid_resolution must be greater than 1. Got rQ   r   z,eps must be greater than or equal to 0. Got rN   z, zplot_method must be one of z. Got rR   z#n_features must be equal to 2. Got rY   )columnsNr   zclass_of_interest=z+ is not a valid label: It should be one of T)r   	pos_labelreturn_response_method_usedr   labels_)binary
continuous
multiclassz4Number of classes or labels cannot be inferred from z. Please make sure your estimator follows scikit-learn's estimator API as described here: https://scikit-learn.org/stable/developers/develop.html#rolling-your-own-estimatorz)Multi-output regressors are not supportedrU   r    rF   )rx   rw    )&r   r   joinr   r   minmaxr6   meshgridr7   c_ravelr	   r
   r   create_containerr   r!   r   r   r   r   	transformr   r   r   r9   r   uniquer   r   	__class____name__rf   reshapeshapeflatnonzeror   )#clsr   Xr   r   rw   r   r   r=   rC   rD   rx   ry   possible_plot_methodsavailable_methodsnum_featuresx0x1x0_minx0_maxx1_minx1_maxrG   rH   X_gridadapterr   rI   r{   response_method_usedencoderr>   target_typecol_idxdisplays#                                      r    from_estimatorz&DecisionBoundaryDisplay.from_estimator  sI   l 		""#$I/ 
 ax>se9M  !F33 $		*? @-.?-@ A"m9. 
 %Q'15l^9M   11-~a/KBCCCC;;KK8KK8
S
 syy{CIIK/0?l1o1!4G--		 . F <IW)gi.LY%7%77$%6$7 8$$-$6$6#79 
 -A-'(,-
)!)  9,J1O"nG(11G((2H )I&"9-I9%')Z*HI../I)$I)FBIIi&7&789I(2K66	,		( 34	 J **334 5ii  ==A'x''3HI& !LMM , ..););?P)PQRST78AwJ/77C+8++KSYYKr8JK>%,Q	%:QYYq\F>%,Q	%:QYYq\F/
 w||Er{EfEEr"   )rL   NNN)r   
__module____qualname____doc__rK   r   classmethodr   r   r"   r    rB   rB      sU    Rv &iV  QF QFr"   rB   ) rc   numpyr6   sklearn.baser   r   r   r   sklearn.preprocessingr   sklearn.utilsr   sklearn.utils._dataframer	   r
   $sklearn.utils._optional_dependenciesr   sklearn.utils._responser   sklearn.utils._set_outputr   sklearn.utils.fixesr   sklearn.utils.multiclassr   sklearn.utils.validationr   r   r   r!   r@   rB   r   r"   r    <module>r      sQ      W W . ( ? I 8 A . 3 DFHRe	F e	Fr"   