
    J-j                     B   d Z ddlmZmZmZ ddlZddlmZmZm	Z	 ddl
ZddlmZmZmZmZ ddlmZ [[[ G d d	e      Z G d
 de      Z G d de      Z G d de      Zd Zd ZeZ	  G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z y)z9Search space transformation and encoding/decoding classes    )absolute_importdivisionprint_functionN)arrayisfinitelog   )rglenprint_warningis_oneSolutionDict)rangec                   $    e Zd ZdZddZd Zd Zy)ConstRandnShiftaE  ``ConstRandnShift()(x)`` adds a fixed realization of
    ``stddev * randn(len(x))`` to the vector ``x``.

    By default, the realized shift is the same for each instance of
    `ConstRandnShift`, see ``seed`` argument. This class is used in
    class `Shifted` as default transformation.

    :See also: class `Shifted`
    c                 .    || _         || _        i | _        y)z;with ``seed=None`` each instance realizes a different shiftN)seedstddev_xopt)selfr   r   s      a/Users/jameslopez/projects/TradingBot25/.venv/lib/python3.12/site-packages/cma/transformations.py__init__zConstRandnShift.__init__   s    	
    c                 n   	 | j                   t        |         }t	        j                  |      |z
  S # t        $ r | j                  )t        j
                  j                  t        |            }nt        j
                  j                         }t        j
                  j                  | j                         t        j
                  j                  t        |            }t        j
                  j                  |       | j                   j                  t        |      | j                  |z        }Y w xY w)z(return "shifted" ``x - shift``

        )r   lenKeyErrorr   nprandomrandn	get_state	set_state
setdefaultr   asarray)r   xx_optshiftrstates        r   __call__zConstRandnShift.__call__   s    
	GJJs1v&E zz!}u$$  	Gyy 		A/,,.		tyy)		A/		##F+JJ))#a&$++2EFE	Gs   2 C>D43D4c                 J    | j                  t        j                  |            S )a  return shift applied to ``zeros(dimension)``

            >>> import numpy as np, cma
            >>> s = cma.transformations.ConstRandnShift()
            >>> assert all(s(-s.get(3)) == np.zeros(3))
            >>> assert all(s.get(3) == s(np.zeros(3)))

        )r'   r   zeros)r   	dimensions     r   getzConstRandnShift.get+   s     }}RXXi011r   N)   r	   )__name__
__module____qualname____doc__r   r'   r+    r   r   r   r      s    
% 	2r   r   c                        e Zd ZdZddZddZy)Rotationa  implement an orthogonal linear transformation for each dimension.

    By default each `Rotation` instance provides a different "random"
    but fixed rotation. This class is used to implement non-separable
    test functions, most conveniently via `Rotated`.

    Example:

    >>> import cma, numpy as np
    >>> R = cma.transformations.Rotation()
    >>> R2 = cma.transformations.Rotation() # another rotation
    >>> x = np.array((1,2,3))
    >>> np.round(R(R(x), inverse=1), 9).tolist()
    [1.0, 2.0, 3.0]

    :See also: `Rotated`

    Nc                      || _         i | _        y)zsame ``seed`` means same rotation, by default a random but
        fixed once and for all rotation, different for each instance
        N)r   dicMatrices)r   r   s     r   r   zRotation.__init__I   s     	r   c           
         t        j                  |      }|j                  d   }|| j                  vrOt         j                  j                         }| j                  r)t         j                  j                  | j                        nt         j                  j                          t         j                  j                         | _        t         j                  j                  ||      }t         j                  j                  |       t        |      D ]_  }t        d|      D ]/  }||xx   t        j                  ||   ||         ||   z  z  cc<   1 ||xx   t        ||   dz        dz  z  cc<   a || j                  |<   |r-t        j                  | j                  |   j                  |      S t        j                  | j                  |   |      S )zkRotates the input array `x` with a fixed rotation matrix
           (``self.dicMatrices[len(x)]``)
        r            ?)r   r"   shaper5   r   r   r   stater   r    r   dotsumT)	r   r#   inversekwargsNr&   Bijs	            r   r'   zRotation.__call__O   sZ    JJqMGGAJD$$$YY((*F)-BIINN499%		8H,,.DJ		1%AII'1Xq!AaDBFF1Q41.155D %!AaD!Gc))  #$DQ66$**1-//3366$**1-q11r   NF)r-   r.   r/   r0   r   r'   r1   r   r   r3   r3   6   s    $2r   r3   c                   P    e Zd ZdZd Zd Zd Zd Zd ZeZ	d Z
d Zd	 Zd
 Zd Zy) BoxConstraintsTransformationBasea  Implements a transformation into boundaries and is used in
    top level boundary handling classes.

    Example::

        tf = BoxConstraintsTransformationAnyDerivedClass([[1, 4]])
        x = [3, 2, 4.4]
        y = tf(x)  # "repaired" solution
        print(tf([2.5]))  # middle value is never changed
        [2.5]
        assert all([yi <= 4 for yi in y])

    :See also: `BoundTransform`

    c                     	 t        |d         dk7  rt        	 || _        | j                          y #  t        d      xY w)Nr   r7   z bounds must be either [[lb0, ub0]] or [[lb0, ub0], [lb1, ub1],...], 
 where in both cases the last entry is reused for all remaining dimensions)r   
ValueErrorbounds
initialize)r   rJ   s     r   r   z)BoxConstraintsTransformationBase.__init__u   sS    	r6!9~"   # 	r  q  r  rs   2 ?c                     | j                   D cg c]  }|d   	 c}| _        | j                   D cg c]  }|d   	 c}| _        yc c}w c c}w )zinitialize in base classr   r	   N)rJ   _lb_ub)r   bs     r   rK   z+BoxConstraintsTransformationBase.initialize~   sF    "&++.+QAaD+."&++.+QAaD+. /.s
   AAc                     t        j                  t        j                  |      t        j                  t        j                  |      |g      g      S rD   )r   maxmin)r   arO   cs       r   _loweruppervalz/BoxConstraintsTransformationBase._lowerupperval   s3    vvrvvay"&&"&&)Q"89::r   c                 >    | j                   | j                  |         S )z-return ``[ith_lower_bound, ith_upper_bound]``)rJ   _indexr   rB   s     r   bounds_iz)BoxConstraintsTransformationBase.bounds_i   s    {{4;;q>**r   c                 l    t        |      D cg c]  \  }}| j                  ||       }}}|S c c}}w rD   )	enumerate_transform_i)r   solution_in_genotyperB   r#   ress        r   r'   z)BoxConstraintsTransformationBase.__call__   s:    3<=Q3RS3R41at  A&3RS
 Ts   0c                 j    t        |      D cg c]  \  }}| j                  ||       c}}S c c}}w rD   )r[   
_inverse_i)r   solution_in_phenotypeargskwarsrB   ys         r   r>   z(BoxConstraintsTransformationBase.inverse   s1    2;<Q2RS2R$!Q1%2RSSSs   /c                 H    t        |t        | j                        dz
  f      S Nr	   )rR   r   rJ   rX   s     r   rW   z'BoxConstraintsTransformationBase._index   s     As4;;'!+,--r   c                     t        d      NzJthis is an abstract method that should be implemented in the derived classNotImplementedErrorr   r#   rB   s      r   r\   z-BoxConstraintsTransformationBase._transform_i       !"noor   c                     t        d      rh   ri   r   rd   rB   s      r   r`   z+BoxConstraintsTransformationBase._inverse_i   rl   r   c                 0    | j                   | |            S )aE  return the reference solution that has the same ``box_constraints_transformation(solution)``
        value, i.e. ``tf.shift_or_mirror_into_invertible_domain(x) = tf.inverse(tf.transform(x))``.
        This is an idempotent mapping (leading to the same result independent how often it is
        repeatedly applied).

        )r>   rj   )r   solution_genotypes     r   &shift_or_mirror_into_invertible_domainzGBoxConstraintsTransformationBase.shift_or_mirror_into_invertible_domain   s     ||D!2344r   N)r-   r.   r/   r0   r   rK   rU   rY   r'   	transformr>   rW   r\   r`   rq   r1   r   r   rG   rG   e   sD    /
;+ IT.pppr   rG   c                   f     e Zd ZdZ fdZd Zd Zd Zej                  ez   Z xZ	S #  Y  xZ	S xY w)%_BoxConstraintsTransformationTemplatezPcopy/paste this template to implement a new boundary handling
    transformationc                 ,    t         t        |   |       y rD   )superrt   r   )r   rJ   	__class__s     r   r   z._BoxConstraintsTransformationTemplate.__init__   s    3TCFKr   c                 .    t         j                  |        y rD   )rG   rK   r   s    r   rK   z0_BoxConstraintsTransformationTemplate.initialize   s    (33D9r   c                     t        d      rh   ri   rk   s      r   r\   z2_BoxConstraintsTransformationTemplate._transform_i   rl   r   c                     t        d      rh   ri   rn   s      r   r`   z0_BoxConstraintsTransformationTemplate._inverse_i   rl   r   )
r-   r.   r/   r0   r   rK   r\   r`   rG   __classcell__)rw   s   @r   rt   rt      s6    L:pp3;;gEDs   ) 0rt   c                 8    t        j                  |       dz   dz  S )z=return quadratic domain image width ``(1 + abs(bound)) / 20``r	      )r   absbounds    r   margin_width1r      s    FF5MA##r   c                 H    t        dt        j                  |       f      dz  S )z?return quadratic domain image width ``max(1, abs(bound)) / 20``r	   r~   )rQ   r   r   r   s    r   margin_width2r      s    266%=!"R''r   c                       e Zd ZdZddZddZej                  e_        eZd Z	d Z
d Z	 ddZej                  j                  ej                  z   e_        d	 Zd
 Zd Zy#  Y xY w)#BoxConstraintsLinQuadTransformationa  implement a periodic transformation that is bijective from

    ``[lb - al, ub + au]`` -> ``[lb, ub]``, where either
    ``al = min((ub-lb) / 2, 0.05 * (|lb| + 1))`` and
    ``ul = min((ub-lb) / 2, 0.05 * (|ub| + 1))`` or (default)
    ``al = min((ub-lb) / 2, 0.05 * max(|lb|, 1))`` and
    ``ul = min((ub-lb) / 2, 0.05 * max(|ub|, 1))``
    depending on the method `cma.transformations.linquad_margin_width`
    assigned as `margin_width1` or `margin_width2`.

    Generally speaking, this transformation aims to resemble ``sin`` to
    be a continuous differentiable (ie. C^1) transformation over R into
    a bounded interval; then, it also aims to improve over ``sin`` in
    the following two ways: (i) resemble the identity over an interval
    as large possible while keeping the second derivative in reasonable
    limits, and (ii) numerical stability in "pathological" corner cases
    of the boundary limit values.

    The transformation resembles the shape ``sin(2*pi * x / a - pi/2))``
    with a period length of ``a = 2 * ((ub + au) - (lb - al)) = 2 * (ub -
    lb + al + au)``.

    The transformation is the identity in ``[lb + al, ub - au]`` (typically
    about 90% of the interval) and it is quadratic to the left of
    ``lb + al`` down to ``lb - 3*al`` and to the right of ``ub - au`` up to
    ``ub + 3*au``.

    Details
    =======
    Partly due to numerical considerations depend the values ``al`` and
    ``au`` on ``abs(lb)`` and ``abs(ub)`` which makes the transformation
    non-translation invariant. When ``ub-lb`` is small compared to
    ``min(|lb|, |ub|)``, the linear proportion becomes zero.

    In contrast to ``sin(.)``, the transformation is robust to
    "arbitrary" large values for boundaries, e.g. a lower bound of
    ``-1e99`` or upper bound of ``np.inf`` or bound ``None``.

    Examples
    ========
    Example to use with cma:

    >>> import warnings
    >>> import cma
    >>> from cma.transformations import BoxConstraintsLinQuadTransformation
    >>> # only the first variable has an upper bound
    >>> tf = BoxConstraintsLinQuadTransformation([[1,2], [1,None]]) # second==last pair is re-cycled
    >>> with warnings.catch_warnings(record=True) as warns:
    ...     x, es = cma.fmin2(cma.ff.elli, 9 * [2], 1,
    ...                 {'transformation': [tf.transform, tf.inverse],
    ...                  'verb_disp':0, 'tolflatfitness': 1e9, 'verbose': -2})
    >>> not warns or str(warns[0].message).startswith(('in class GenoPheno: user defi',
    ...                                   'flat fitness'))
    True

    or:

    >>> es = cma.CMAEvolutionStrategy(4 * [2], 1, {'verbose':0, 'verb_log':0})  # doctest: +ELLIPSIS
    (4_w,8)-aCMA-ES (mu_w=...
    >>> if 1 < 3:  # with warnings.catch_warnings(record=True) as warns:  # flat fitness warning has become a termination condition
    ...     while not es.stop():
    ...         X = es.ask()
    ...         f = [cma.ff.elli(tf(x)) for x in X]  # tf(x)==tf.transform(x)
    ...         es.tell(X, f)
    >>> assert es.result.iterations < 220 and es.result.fbest <= 1010101 + 1e-6, es.result._asdict()

    Example of the internal workings:

    >>> import cma.transformations as ts
    >>> ts.linquad_margin_width = ts.margin_width1
    >>> tf = ts.BoxConstraintsLinQuadTransformation([[1,2], [1,11], [1,11]])
    >>> tf.bounds
    [[1, 2], [1, 11], [1, 11]]
    >>> tf([1.5, 1.5, 1.5])
    [1.5, 1.5, 1.5]
    >>> np.round(tf([1.52, -2.2, -0.2, 2, 4, 10.4]), 9).tolist()
    [1.52, 4.0, 2.0, 2.0, 4.0, 10.4]
    >>> res = np.round(tf._au, 2)
    >>> assert res[:4].tolist() == [ 0.15, 0.6, 0.6, 0.6], res[:4].tolist()
    >>> res = [round(x, 2) for x in tf.shift_or_mirror_into_invertible_domain([1.52, -12.2, -0.2, 2, 4, 10.4])]
    >>> assert res == [1.52, 9.2, 2.0, 2.0, 4.0, 10.4], res
    >>> tmp = tf([1])  # call with lower dimension

    >>> ts.linquad_margin_width = ts.margin_width2
    >>> tf = ts.BoxConstraintsLinQuadTransformation([[1,2], [1,11], [1,11]])
    >>> tf.bounds
    [[1, 2], [1, 11], [1, 11]]
    >>> tf([1.5, 1.5, 1.5])
    [1.5, 1.5, 1.5]
    >>> np.round(tf([1.52, -2.2, -0.2, 2, 4, 10.4]), 9).tolist()
    [1.52, 4.1, 2.1, 2.0, 4.0, 10.4]
    >>> res = np.round(tf._au, 2)
    >>> assert list(res[:4]) == [ 0.1, 0.55, 0.55, 0.55], list(res[:4])
    >>> res = [round(x, 2) for x in tf.shift_or_mirror_into_invertible_domain([1.52, -12.2, -0.2, 2, 4, 10.4])]
    >>> assert res == [1.52, 9.0, 2.1, 2.0, 4.0, 10.4], res
    >>> tmp = tf([1])  # call with lower dimension
    >>> for i in range(5):
    ...     lb = np.random.randn(4) - 1000 * i * np.random.rand()
    ...     ub = lb + (1e-7 + np.random.rand(4)) / (1e-9 + np.random.rand(4)) + 1001 * i * np.random.rand()
    ...     lb[-1], ub[-1] = lb[-2], ub[-2]
    ...     b = ts.BoxConstraintsLinQuadTransformation([[l, u] for (l, u) in zip(lb[:3], ub[:3])])
    ...     for x in [(ub - lb) * np.random.randn(4) / np.sqrt(np.random.rand(4)) for _ in range(11)]:
    ...         assert all(lb <= b.transform(x)), (lb, ub, b.transform(x), b.__dict__)
    ...         assert all(b.transform(x) <= ub), (lb, ub, b.transform(x), b.__dict__)
    ...         assert all(b.transform(lb - b._al) == lb), (lb, ub, b.transform(x), b.__dict__)
    ...         assert all(b.transform(ub + b._au) == ub), (lb, ub, b.transform(x), b.__dict__)

    Nc                    |t        | j                        }t        t        | j                        dz
  |dz
  f      }t        j                  t        |      D cg c]M  }| j                  t        ||f         d   | j                  t        ||f         d   nt        j                   O c}      | _        t        j                  t        |      D cg c]L  }| j                  t        ||f         d   | j                  t        ||f         d   nt        j                  N c}      | _        | j                  }| j                  }t        ||k\        r5t        dj                  t        j                  ||k\        d   ||            t        j                  t        |      D cg c]7  }t        ||         r%t        ||   ||   z
  dz  t        ||         g      nd9 c}      | _        t        j                  t        |      D cg c]7  }t        ||         r%t        ||   ||   z
  dz  t        ||         g      nd9 c}      | _        yc c}w c c}w c c}w c c}w )zsee ``__init__``Nr	   r   z`Lower bounds need to be smaller than upper bounds. They were not at idx={0} where lb={1}, ub={2}r7   )r   rJ   rR   r   r"   r   infrM   rN   anyrI   formatwherer
   r   linquad_margin_width_al_au)r   lengthmax_irB   lbubs         r   rK   z.BoxConstraintsLinQuadTransformation.initialize&  sd   >%FS%)6A:67:: $)=2 $1a "[[aZ9!<H  ${{35z?;A> "w ' $12 3 :: $)=2 $1a "[[aZ9!<H  ${{35z?;A>!vv & $12 3 XXXXrRx= I$fRXXbBh%7%:BCE E ::@Eb	K@I1A  #RURU]a$79MbQRe9T#UV56 7@IK L::@Eb	K@I1A  #RURU]a$79MbQRe9T#UV56 7@IK L#22KKs   AIAI(<I<I$c                 8   t        | j                        t        |      k7  r| j                  t        |             | j                  }| j                  }| j                  }| j
                  }t        |d   t              st        j                  |dt              }d}n|}||d|z  z
  ||z
  dz  z
  k  ||d|z  z   ||z
  dz  z   kD  z  }|j                         rkd||   ||   z
  ||   z   ||   z   z  }	||   d||   z  z
  ||   ||   z
  dz  z
  }
|rt        j                  |d      }d}||xx   |	||   |
z
  |	z  z  z  cc<   |||z   kD  }|j                         r:|rt        j                  |d      }d}||xx   d||   ||   z
  ||   z
  z  z  cc<   |||z
  k  }|j                         r:|rt        j                  |d      }d}||xx   d||   ||   z
  ||   z
  z  z  cc<   |||z   k  }|j                         rA|rt        j                  |d      }d}||   ||   ||   ||   z
  z
  dz  dz  ||   z  z   ||<   |||z
  kD  }|j                         rA|rt        j                  |d      }d}||   ||   ||   ||   z   z
  dz  dz  ||   z  z
  ||<   |S )	Nr   T)copydtypeFr7          @r      )r   rM   rK   rN   r   r   
isinstancefloatr   r   r   )r   rp   r   r   r   alaurd   idxrss              r   r'   z,BoxConstraintsLinQuadTransformation.__call__?  s    txx=C 122OOC 123XXXXXXXX+A.6*UCAD!A2B;"r'S00Qa"fRSV9V5VW779RWr#w&C02c7:;A3!bg+%C2c7):c(AAAHHQT*cFaAcFQJ1,--F"r'k779HHQT*cFa1S6BsG+bg566F"r'k779HHQT*cFa2c7RW,qv566F"r'k779HHQT*W#"S'BsG*; <q@1Dr#wNNAcF"r'k779HHQT*W#"S'BsG*; <q@1Dr#wNNAcFr   c                 p    t        |      D cg c]  \  }}| j                  ||      s| }}}|S c c}}w )zreturn indices of "infeasible" variables, that is,
        variables that do not directly map into the feasible domain such that
        ``tf.inverse(tf(x)) == x``.

        )r[   is_feasible_i)r   rp   rB   r#   r^   s        r   idx_infeasiblez2BoxConstraintsLinQuadTransformation.idx_infeasibley  sH     ''89 A9TQ'+'9'9!Q'? 9 A
As   2c                    | j                   | j                  |         }| j                  | j                  |         }| j                  | j                  |         }| j                  | j                  |         }||z
  |cxk  xr ||z   k  S c S )zZreturn True if value ``x`` is in the invertible domain of
        variable ``i``

        rM   rW   rN   r   r   r   r#   rB   r   r   r   r   s          r   r   z1BoxConstraintsLinQuadTransformation.is_feasible_i  sz    
 XXdkk!n%XXdkk!n%XXdkk!n%XXdkk!n%Bw$R"W$$$$r   c                 N   | j                   | j                  |         }| j                  | j                  |         }| j                  | j                  |         }| j                  | j                  |         }|d|z  z
  ||z
  dz  z
  |cxk  xr |d|z  z   ||z
  dz  z   k  S c S )z
never usedr7   r   r   r   s          r   is_loosely_feasible_iz9BoxConstraintsLinQuadTransformation.is_loosely_feasible_i  s    XXdkk!n%XXdkk!n%XXdkk!n%XXdkk!n%AF{b2g_,RR!b&[BGs?5RRRRRr   c                 0   |J |r|D cg c]  }| }}n|}t        |t        j                        r$t        |d   t              st	        |t              }t        |      D ]+  }| j                  | j                  |         }| j                  | j                  |         }| j                  | j                  |         }| j                  | j                  |         }	||   |d|z  z
  ||z
  dz  z
  k  s||   |d|	z  z   ||z
  dz  z   kD  r8d||z
  |z   |	z   z  }
|d|z  z
  ||z
  dz  z
  }||xx   |
||   |z
  |
z  z  z  cc<   ||   ||	z   kD  r||xx   d||   |z
  |	z
  z  z  cc<   ||   ||z
  k  s||xx   d||z
  ||   z
  z  z  cc<   . |S c c}w )zparameter ``solution_genotype`` is changed.

        The domain is
        ``[lb - al, ub + au]`` and in ``[lb - 2*al - (ub - lb) / 2, lb - al]``
        mirroring is applied.

        r   r   r7   r   )r   r   ndarrayr   r   r
   rM   rW   rN   r   r   )r   rp   r   valrd   rB   r   r   r   r   r   r   s               r   rq   zJBoxConstraintsLinQuadTransformation.shift_or_mirror_into_invertible_domain  s    !,,, 12 1 1A2!Aa$Z!e-Dau%AqA$++a.)B$++a.)B$++a.)B$++a.)Btb1r6kR"WO33qtb1r6kRRTWX[O>[7[b2*+RK27c/1!adQh1_--tb2g~!QqTBY^,,tb2g~!R"Wqt^,,  ' 3s   	Fc                     |J | j                   | j                  |         }| j                  | j                  |         }| j                  | j                  |         }| j                  | j                  |         }||d|z  z
  ||z
  dz  z
  k  s||d|z  z   ||z
  dz  z   kD  r-d||z
  |z   |z   z  }|d|z  z
  ||z
  dz  z
  }||||z
  |z  z  z  }|||z   kD  r|d||z
  |z
  z  z  }|||z
  k  r|d||z
  |z
  z  z  }|S )zshift into the invertible domain [lb - ab, ub + au], mirror close to
        boundaries in order to get a smooth transformation everywhere

        r7   r   r   )	r   r#   rB   r   r   r   r   r   r   s	            r   "_shift_or_mirror_into_invertible_izFBoxConstraintsLinQuadTransformation._shift_or_mirror_into_invertible_i  s0   
 }}XXdkk!n%XXdkk!n%XXdkk!n%XXdkk!n%rAF{b2g_,,BRK27c/4Q0QR"Wr\B&'AQVrBw#o-Aq1ul##ArBw;a"frk""ArBw;b2gk""Ar   c                    | j                  ||      }| j                  | j                  |         }| j                  | j                  |         }| j                  | j                  |         }| j
                  | j                  |         }|||z   k  r||||z
  z
  dz  dz  |z  z   S |||z
  k  r|S ||d|z  z   k  r||||z   z
  dz  dz  |z  z
  S J )z$return transform of x in component ir7   r   r,   )r   rM   rW   rN   r   r   r   s          r   r\   z0BoxConstraintsLinQuadTransformation._transform_i  s    33Aq9XXdkk!n%XXdkk!n%XXdkk!n%XXdkk!n%rBw;b2g*Q.333b[Ha"f_b2g*Q.3335r   c                 l   | j                   | j                  |         }| j                  | j                  |         }| j                  | j                  |         }| j                  | j                  |         }ddk  r"||cxk  r|k  sst        d       t        d      |d||z
  z  t        ||z
  d||z
  z  z        z  z  }||kD  r|d||z
  z  z  }||kD  r||k  r|d||z
  z  z  }||k  r||kD  r|||z
  z
  }|||z   k  r||z
  d|||z
  z  dz  z  z   S |||z
  k  r|S ||z   d|||z
  z  dz  z  z
  S )z"return inverse of y in component ir	   r,   z3argument of inverse must be within the given boundsr7   r8   )rM   rW   rN   r   r   rI   int)r   rd   rB   r   r   r   r   s          r   r`   z.BoxConstraintsLinQuadTransformation._inverse_i  sk   XXdkk!n%XXdkk!n%XXdkk!n%XXdkk!n%q5=b= !VWW ! !VWWb2ga"fb2g%?!@@@Ab&Q"r']" b&b&Q"r']" b&2v!b&MrBw;GqB!b&MC#7777b[HGqB"q&MC#7777r   rD   TrE   )r-   r.   r/   r0   rK   r'   rG   docrr   r   r   r   rq   r   r\   r`   r1   r   r   r   r      s    kZL27p 4;;HLI	%S 5:> ;[  ;B  ;B  ;J  ;J  Ms  M{  M{  ;{	/	7(- 8M Ds   (A" "A&r   c                   \    e Zd ZdZd Zd Zd Zd Zd Zd Z	dd	Z
ed
        Zed        Zy)AdaptiveDecodingzbase class for adaptive decoding.

    The adaptive decoding class is "dual" to the StasticalModel class,
    in that for linear transformations adapting either one or the other
    is equivalent.

    TODO: this is a stump

    c                     t         )z{``len(scaling)`` determines the dimension.

        The initial transformation is (typically) `np.diag(scaling)`.

        ri   r   scalings     r   r   zAdaptiveDecoding.__init__  s
     "!r   c                     t         )z5apply the transformation / decoding AKA geno-pheno tfri   r   r#   s     r   rr   zAdaptiveDecoding.transform  s    !!r   c                      y)z4inverse transformation (encoding), might return NoneNr1   r   s     r   transform_inversez"AdaptiveDecoding.transform_inverse      r   c                 $    | j                  |      S )z3A linear transformation expressed by multiplication)rr   r   s     r   __mul__zAdaptiveDecoding.__mul__  s    ~~a  r   c                     t         )a  AKA update.

        :param vectors: is a list of samples.
        :param weights: define a learning rate for each vector.

        ``vectors`` are "isotropic", e.g.::

            sm = StatisticalModel...()
            ad = AdaptiveDecoding...()
            z = sm.sample(1)[0]
            y = ad * z  # decoding applied
            x = m + y  # candidate solution
            ad.tell([sm.transform_inverse(z)], [0.1])
            sm.update([y / ad], [0.01]) # remark that y / ad != z

        where the symmetric transformation ``sm.transform_inverse(z)``
        makes ``z`` isotropic.

        TODO: what exactly does this mean, is this a generic
        construction, is this even the right construction?
        ri   )r   vectorsweightss      r   updatezAdaptiveDecoding.update  s
    , "!r   c                 B    t        | j                  |      dz        dz  S )z0return norm of ``x`` prior to the transformationr7   r8   )r<   r   r   s     r   normzAdaptiveDecoding.norm0  s"    4))!,a/0#55r   Nc                      y)z0update model here, if lazy update is implementedNr1   )r   lazy_update_gaps     r   
update_nowzAdaptiveDecoding.update_now4  r   r   c                      y)z!return correlation matrix or NoneNr1   ry   s    r   correlation_matrixz#AdaptiveDecoding.correlation_matrix8  s     	r   c                     t         )z<return condition number of the squared transformation matrixri   ry   s    r   condition_numberz!AdaptiveDecoding.condition_number=  s
     "!r   rD   )r-   r.   r/   r0   r   rr   r   r   r   r   r   propertyr   r   r1   r   r   r   r     sR    ""!"06    r   r   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd ZddZd Zd ZddZed        Zed        Zd Zy)DiagonalDecodinga  Diagonal linear transformation with exponential update.

    Supports ``self * a``, ``a * self``, ``a / self``, ``self *= a``,
    as if ``self`` is an np.array. Problem: ``np.array`` does
    broadcasting.

    >>> import cma
    >>> from cma.transformations import DiagonalDecoding as DD

    References: N. Hansen (2008). Adaptive Encoding: How to render search
    coordinate system invariant. In PPSN Parallel Problem Solving from
    Nature X, pp. 205-214.

c                    t        |t              r|dgz  }t        j                  |t              | _        t        j                  | j
                        | _        d| _        t        | j
                        rd| _        i | _
        y )N      ?r   FT)r   r   r   r   r   r   sizedimis_identityr   _parametersr   s     r   r   zDiagonalDecoding.__init__R  sa    gs#oGxxu5774<<( $,,#Dr   c                      | j                   |z  S rD   r   r   r   s     r   rr   zDiagonalDecoding.transform\  s    ||ar   c                      || j                   z  S rD   r   r   s     r   r   z"DiagonalDecoding.transform_inverse`  s    4<<r   c                 j    | j                   r|S | j                  |z  j                  | j                  z  S )z&return the covariance matrix D * C * D)r   r   r=   )r   Cs     r   transform_covariance_matrixz,DiagonalDecoding.transform_covariance_matrixd  s.    Hq ##dll22r   c                     | j                   S )zj``sigma * self`` tries to call ``self.__array__()`` if
        ``isinstance(sigma, np.float64)``.
        )r   ry   s    r   	__array__zDiagonalDecoding.__array__j  s     ||r   c                 2    t        | j                  |k(        S )z-return `True` if the diagonal equals to ``x``)allr   r   s     r   equalszDiagonalDecoding.equalsp  s    4<<1$%%r   c                    	 |dk(  r| S 	 	 t        j                  |      t        j                  | j                        k(  rt        |dk(        r| S | j                  rOt        j                  | j                        dk(  r-t        j
                  t        j                  |            | _        d| _        | xj                  |z  c_        t        j                  | j                        | _        | S #  Y xY w#  Y xY w)zkdefine ``self *= factor``.

        As a shortcut for::

            self = self.__imul__(factor)

        r	   F)r   r   r   r   r   onesr   )r   factors     r   __imul__zDiagonalDecoding.__imul__t  s    	{ 	2774<<#88!$ 5 :772776?3DL 774<<( 	
 	s   C- AC4 -C14C8c                 <    | j                   r|S | j                  |z  S )z#multiplication with array or scalarr   r   r   s     r   r   zDiagonalDecoding.__mul__        $$q:$,,*::r   c                 <    | j                   r|S | j                  |z  S )z,``x * self`` works (only) if `x` is a scalarr   r   s     r   __rmul__zDiagonalDecoding.__rmul__  r   r   c                     t        d      )NzMuse ``this**-1 * x`` or ``this.transform_inverse(x)`` instead of ``x / this``)rj   r   r   s     r   __rdiv__zDiagonalDecoding.__rdiv__  s    ! #D E 	Er   c                 B    | j                   r|S | j                  dz  |z  S )Nr   r   s     r   __rtruediv__zDiagonalDecoding.__rtruediv__  s#    $$q>$,,*:Q*>>r   c                 <    | j                   rdS | j                  |z  S rf   r   )r   powers     r   __pow__zDiagonalDecoding.__pow__  s    $$q=$,,*==r   c                    | j                   }||||f}| j                  |   S # t        $ r Y nw xY wdd|dz   dz  z  |dz  z   z  }ddd|z  z   |dz  z   z  }ddk  rd\  }}t        j                  j                  ||      }	t        |	d	d	d
f         |	d	d	d
f<   t        j                  |	d
      dz  }
t        |
d
   |z  |dz  z  t        j                  |
dd	 |z               t        t        |
      ||z  dz   z         t        d|z
  ||d|z  z   dz
  dz   z  f      }|d|z  z   dz
  dz   dd|z  z   |dz  z   z  }ddk  r|}|}t        j                  ||z        dz  }t        j                  ||z        dz  }||z  }||z  }t        |d|z
  f      }|||d| j                  |<   dd} || j                  |   |       | j                  |   S )zlearning rate parameter suggestions.

        TODO: either input popsize or input something like fac = 1 + (2...5) / popsize
              cmu has already 1/7 as popsize correction
    r	   r         ?r7         r,   )i'  d   Nr   g?gy):?g$I$I?r   )c1cmuccc                     d| d   cxk  rdk  r'n n$d| d   cxk  rdk  rn n| d   | d   cxk  rdk  s/n t        dj                  t        |      t        |                   y)	z `d` is the parameters dictionaryr   r   r   r   r	   r   zbOn input {0},
the values {1}
do not satisfy
  `0 <= c1 < 0.75 and 0 <= cmu <= 1 and c1 <= cc <= 1`N)rI   r   str)dinput_parameterss     r   check_valuesz1DiagonalDecoding.parameters.<locals>.check_values  si    4'4'A5,>Q,>dGqw+!+  "& '-fS1A-BCF&K	M M ,r   rD   )r   r   r   r   r   r   r   meanprintr<   rR   sqrt)r   mueff	c1_factor
cmu_factorr@   r   	c1dd_origr   muzz2
cmudd_origr   r   r   s                  r   
parameterszDiagonalDecoding.parameters  s%    HHeY
:$$%566 a!es^+eAg56	!a!e)eai'(6 EB		A&A1Q3[AacFA!B"Q%"*T	*BGGBqrFRK,@A#b'QVf_-. !i-#uqw':S'@AC D
r%x!#c)AE	EAI%' 6BC$q(BWWURZ 1$
iz3B- 46s"-M)*	M 	T%%&679IJ 011s   " 	..c                     | j                   r"t        j                  | j                        dk(  s| S t	        |      }t        j                  |      | _        | S # t
        $ r |}Y )w xY w)z%init scaling (only) when not yet doner	   )r   r   r   r   r   	TypeErrorr   )r   int_or_vectorint_s      r   _init_zDiagonalDecoding._init_  sS    rwwt||'<'AK&Twwt} .$.s   A A&%A&c                     t        j                  | j                        dk(  rt        d      d| _        || j                  |<   y)zset ``scaling[index] = value``.

        To guaranty initialization to non-identity, the use pattern::

            de = cma.transformations.DiagonalDecoding()
            de._init_(dimension).set_i(3, 4.4)

        is available.
        r	   z&not yet initialized (dimension needed)FN)r   r   r   rI   r   )r   indexvalues      r   set_izDiagonalDecoding.set_i  s;     774<< A%EFF #Ur   c           	         | j                  |d          d| _        t        j                  |      }t	        t        |            dkD  r/t        dt	        ||dkD           t	        ||dk            fz        t        j                  |      dz  }ddk  r6t        j                  |      dkD  rt        t        j                  |             t        j                  |dkD        rt        j                  t        j                  |dkD  d	            d   }d
}|r8d}|D ]1  }t        j                  ||   dkD        d   D ]
  }	|	|vsd
} n |s1 n |rzg }
|D ]O  }t        j                  ||   dkD        d   }	t        |	      s-|
j                  |t        |	      ||   |	   f       Q t        j                  dj!                  |
             t        j"                  ||      }t        j$                  |t	        |      z
  dz        }d	dk  rd	dk  r|d	kD  }t        |      rt        j                  t        j
                  |dd|f   d	z
        d      dz  d	z   }ddk  rOt        |d	k        rAt                t        |       t        |dd|f          t        |       t                d	dz   ||   |kD  }t        |      r)t'        dj!                  t        j(                  |      d   |   ||   |   ||                ||   ||   |<   n|dkD  }t	        t        ||               }t        j"                  ||   ||         |z  }||d	kD     }t        j*                  |      rd	dk  rZt        t        j,                  |      |d	z
  z        }||kD  rY|||z  z  }t        j                  dj!                  ||z  |             n(d	dk  rt/        d      ||kD  }t        |      r||   ||<   |t        |      dk(  r| xj0                  |z  c_        yt3        t        | j0                              D ]!  }	|	|vs| j0                  |	xx   ||	   z  cc<   # y)a)  exponential update of the scaling factors.

        `vectors` have shape popsize x dimension and are assumed to be
        standard normal before selection.

        `weights` may be negative and include the learning rate(s).

        Variables listed in `ignore_indices` are not updated.
        r   Fr,   z#sum of weights %f + %f is too larger7   r   2   7   r	   Tz<elements of z2[k] are larger than 55: [(k, idx, values)]={0}N)axiszJclipped exponential update in indices {0}
from {1} to max(|z^2-1| + 1)={2}z,corrected exponential update by {0} from {1}zthis was never tested)r  r   r   r"   r<   r   rI   rQ   r   r   nonzeror   appendlist	_warningswarnr   r;   expr   r   r   r   rj   r   r   )r   r   r   ignore_indicesinteger_indicesr  r   r  krB   r   
z2_averagefacsmax_z2idx2etaz2_pos_averagez2_large_poseta_max
corrections                       r   r   zDiagonalDecoding.update  s    	GAJ **W%s7|q B #GGAI$6 7!$WWQY%7!8 8 :: ; ; ZZ !#6bffRj2o"&&*66"r'?**RVVBGQ/03CDAZZ1
3A6O3#'D! 7   A

2a52:.q1A1v!T!WbeAh!78    88>q	C VVGR(
 vvzCL0A56 q51uQhs8VVBFF2ae9q=$9BQFJFAv#fqj/fb3i(b	!9v-D4y% 'GGMv(*a(8(>S	$QWX\Q]H_` +1,S	$ k#gcl+,!#bg!>!D-nq.@A77<(1u"%bff\&:)5)9'; #<= gm4D%NN+Y+`+`ahilalnq+rsQ12IJJ #^3s8(6s(;DI!S%8A%=LLD L3t||,-N*LLOtAw.O .r   c                 ^    t        | j                        t        | j                        z  dz  S )Nr7   )rQ   r   rR   ry   s    r   r   z!DiagonalDecoding.condition_numberx  s$    DLL!C$5599r   c                 @    t        j                  | j                        S rD   )r   eyer   ry   s    r   r   z#DiagonalDecoding.correlation_matrix|  s    vvdhhr   c                 6    | j                   j                         S rD   )r   tolistry   s    r   r-  zDiagonalDecoding.tolist  s    ||""$$r   N)r	   r	   )r1   r1   )r-   r.   r/   r0   r   rr   r   r   r   r   r   r   r   r   r   r   r	  r  r  r   r   r   r   r-  r1   r   r   r   r   C  s    ;;3&0;
;
 
?>E2N$o/d : :    %r   r   c                   6    e Zd ZdZ	 	 ddZ	 	 ddZ	 	 	 ddZy)	GenoPhenoae  Genotype-phenotype transformation.

    Method `pheno` provides the transformation from geno- to phenotype,
    that is from the internal representation to the representation used
    in the objective function. Method `geno` provides the "inverse" pheno-
    to genotype transformation. The geno-phenotype transformation comprises,
    in this order:

       - insert fixed variables (with the phenotypic values)
       - affine linear transformation (first scaling then shift)
       - user-defined transformation
       - repair (e.g. into feasible domain due to boundaries)
       - re-assign fixed variables their original phenotypic value

    By default all transformations are the identity. The repair is only
    applied, if the transformation is given as argument to the method
    `pheno`.

    `geno` is only necessary, if solutions have been injected.

    Nc           	         || _         || _        t               | _        |"|d   | _        |d   | _        t        dd       nd| _        d| _        |rt        |t              s#t        dt        t        |            d|      t        |j                               |k\  r@t        dt        t        |j                                     z   d	z   t        |      z   d
z         t        |j                               D ]  }|dk  s	|j                  |        dd}|t!        |      nd| _         || j"                  d      rd| _        n~| j"                  j$                  dk7  ret'        | j"                        | j                   k7  rCt        dt        t'        | j"                              z   dz   t        | j                         z         |t!        |      nd| _         || j(                  d      rd| _        n~| j(                  j$                  dk7  ret'        | j(                        | j                   k7  rCt        dt        t'        | j(                              z   dz   t        | j                         z         t+        | j"                        r?t-        j.                  | j(                        s | j                  | j                  d| _        nd| _        | j                  d| _        yd| _        y)a  return `GenoPheno` instance with phenotypic dimension `dim`.

        Keyword Arguments
        -----------------
            `scaling`
                the diagonal of a scaling transformation matrix, multipliers
                in the genotyp-phenotyp transformation, see `typical_x`
            `typical_x`
                ``pheno = scaling*geno + typical_x``
            `fixed_values`
                a dictionary of variable indices and values, like ``{0:2.0, 2:1.1}``,
                that are not subject to change, negative indices are ignored
                (they act like incommenting the index), values are phenotypic
                values.
            `tf`
                list of two user-defined transformation functions, or `None`.

                ``tf[0]`` is a function that transforms the internal representation
                as used by the optimizer into a solution as used by the
                objective function. ``tf[1]`` does the back-transformation.
                For example::

                    tf_0 = lambda x: [xi**2 for xi in x]
                    tf_1 = lambda x: [abs(xi)**0.5 fox xi in x]

                or "equivalently" without the `lambda` construct::

                    def tf_0(x):
                        return [xi**2 for xi in x]
                    def tf_1(x):
                        return [abs(xi)**0.5 fox xi in x]

                ``tf=[tf_0, tf_1]`` is a reasonable way to guaranty that only positive
                values are used in the objective function.

        Details
        -------
        If ``tf_0`` is not the identity and ``tf_1`` is ommitted,
        the genotype of ``x0`` cannot be computed consistently and
        "injection" of phenotypic solutions is likely to lead to
        unexpected results.

        Nr   r	   zPin class GenoPheno: user defined transformations have not been tested thoroughly)maxwarnsz<fixed_values must be a dictionary {index:value,...}, found: z, zmax(fixed_values.keys()) = z
 >= dim=N=z is not a feasible indexc                     	 t        |       dk(  r| d   } | t        | |k(        ryt        | D cg c]  }|du xs ||k(   c}      ryy# t        $ r Y @w xY wc c}w )zyreturn True if `vec` has the value `default_val`,
            None or [None] are also recognized as default

            r	   r   NTF)r   r  r   )vecdefault_valr   s      r   vec_is_defaultz*GenoPheno.__init__.<locals>.vec_is_default  sx    s8q=a&C {c#"45E#C4K53+#55EF   Fs   A
 A
	AAr1   zlen(scales) == z does not match dimension N == zlen(typical_x) == TF)r   )r@   fixed_values_SolutionDictrepaired_solutionstf_phenotf_genor   r   dictrI   r   typerQ   keysr  popr   scalesr9   r   	typical_xr   r   r   
isidentityislinear)r   r   r   r@  r6  tfr  r5  s           r   r   zGenoPheno.__init__  s   Z ("//>qEDMa5DL
 lwxyDL DMlD1 $'\(:$;\"K L L<$$&'3. !>SIZIZI\E]A^!^ "!#&s8",.H"I J J ,++-.q5 $$Q' /	* )0(;eGn$++q)DK[["$T[[)9TVV)C.S5E1FF:;=@[I J J .7-By)$..!,DN^^!!R'C,?466,I1CDNN8K4LL:;=@[I J J 4;;FF4>>*!!)%"DO#DO==  DM!DMr   c                 b   t        |      }|dd}| j                  r
 ||      }nJ| j                  t        ||      }ngt	        |      }t        | j                  j                               D ]!  }|j                  || j                  |          # t        j                  |      }d}t        | j                        s|| j                  z  }t        j                  | j                        r|| j                  z  }| j                  $t        j                  | j                  |            } |||      }| j                  0t	        | j                  j                               D ]
  \  }}	|	||<    |t        j                   u rt        j                  |      }||j                  |||       |S )zmaps the genotypic input argument into the phenotypic space,
        see help for class `GenoPheno`

        Details
        -------
        If ``copy``, values from ``x`` are copied if changed under the
        transformation.

        Fc                 8    |s| S t        j                  | d      S )NTr   )r   r   r#   r   s     r   into_boundsz$GenoPheno.pheno.<locals>.into_bounds  s     $q@"((14*@@r   r   )geno	iterationrE   )r<  rA  r6  r   r  sortedr=  insertr   r"   r   r?  r   r@  r9  itemsr   )
r   r#   rG  r   archiverI  
input_typerd   rB   r  s
             r   phenozGenoPheno.pheno  sg    !W
A??AA  (!$'G 1 1 6 6 89AHHQ 1 1! 45 :JJqMD$++&T[[ vvdnn%T^^#}}(JJt}}Q/0At$A  , !2!2!8!8!:;DAqAaD < #

1ANN11	N:r   c                 l   d }|d
d}|,	 ||   }|d   }|d   |j                  k  r || |||      }|S t        |      }	|} |||      }| j                  r || |||      }|S |rt        |d      }d}| j                  %t        j                  | j                  |            }n| j                  t        d	      t        j                  | j                        r|| j                  z  }t        | j                        s|| j                  z  }| j                  Gt        j                  t!        t#        |            D 
cg c]  }
|
| j                  vs||
    c}
      } || |||      }|	t        j$                  u rt        j                  |      }|S # t         t        f$ r d}Y w xY wc c}
w )a  maps the phenotypic input argument into the genotypic space,
        that is, computes essentially the inverse of ``pheno``.

        By default a copy is made only to prevent to modify ``y``.

        The inverse of the user-defined transformation (if any)
        is only needed if external solutions are injected, it is not
        applied to the initial solution x0.

        Details
        =======
        ``geno`` searches first in ``archive`` for the genotype of
        ``y`` and returns the found value, typically unrepaired.
        Otherwise, first ``from_bounds`` is applied, to revert a
        projection into the bound domain (if necessary) and ``pheno``
        is reverted. ``repair`` is applied last, and is usually the
        method ``CMAEvolutionStrategy.repair_genotype`` that limits the
        Mahalanobis norm of ``geno(y) - mean``. `repair` is only applied to
        an unknown solution for which no genotype solution was found in the
        archive!
    c                     ||S  |||      }ddk  rOt        j                  t        j                  |      |k(        s$dt        | j                        i| j                  |<   |S )N)copy_if_changedr   r,   count)r   r   r"   r   r8  )r   repairr#   r   x2s        r   repair_and_flag_changez.GenoPheno.geno.<locals>.repair_and_flag_changeX  s\    ~40BAvbffRZZ]b%89/6D<S<S8T.U''+Ir   NFc                     | S rD   r1   rF  s     r   from_boundsz#GenoPheno.geno.<locals>.from_boundsa  s    r   rH  rI  Tr   zUt1 of options transformation was not defined but is needed as being the inverse of t0rE   )r   r  last_iterationr<  rA  r   r:  r   r"   r9  rI   r   r@  r   r?  r6  r   r   r   )r   rd   rX  r   rT  rM  rV  	archive_yr#   rN  rB   s              r   rH  zGenoPheno.geno@  s   0	  #AJ	f% }[)G,B,BB.tVQEA!W
4 ??&tVQ=AHad#AD <<#

4<<?+A]]&tuu 66$..!Adkk"A (

%A-V-Q1DDUDU;UAaD-VWA #4D9#

1AU i( H Ws   
F F1F1F.-F.)NNNN)NTNN)r-   r.   r/   r0   r   rO  rH  r1   r   r   r/  r/    s5    * 59'+u"n /3&*.` #'"&Rr   r/  c                   F    e Zd ZdZd Zed        Zd	dZd Z	 d
dZ	ddZ
y)RoundIntegerVariablesaE  Round integer variables of solutions at the end of `ask` via

    the `round_population` method and provide an archive to retrieve the
    unrounded solutions with `unrounded_population` at the beginning of `tell`.

    Also catch possibly changed solutions, depending on the parameters
    passed to `unrounded_population`.
c                     t               j                         D ci c]  \  }}|dk7  s|| c}}| _        t               | _        d| j                  _        d| _        yc c}}w )zH`CMAOptions`, `bool`, `bool` passed from `cma.evolution_strategy` moduler   Tr   N)localsrL  paramsr7  rM  behave_as_queuerS  )r   optionsround_integer_variablesr  vs        r   r   zRoundIntegerVariables.__init__  sS    (.(8H(81AKq!t(8H$'+$
 Is
   A A c                 X    | j                   d   syt        | j                   d   d         S )a*  check `'round_integer_variables'` parameter and

        `'integer_variables'` option. Return number of active integer
        variables or `False`.

        Details: `'_pheno_integer_variables'` don't include indices of
        fixed variables either, hence the don't need to be checked here.
    rb  Fra  integer_variables)r_  r   ry   s    r   _activezRoundIntegerVariables._active  s.     {{454;;y)*=>??r   c                    | j                   s|S | j                  d   j                  d| j                  d   d         }t        |      s|S |rt	        j
                  |d      }	 t	        j                  |      }t	        j                  ||         ||<   |S # t        $ r& |D ]  }t	        j                  ||         ||<    Y |S w xY w)zround integer variables in `solution` if ``self._active``.
   
        See also `CMAEvolutionStrategy._round_int_variables`.
    ra  _pheno_integer_variablesre  Tr   )	rf  r_  r+   r   r   r   r"   roundr  )r   solutioncopy_when_changedr   rB   s        r   _round_int_variablesz*RoundIntegerVariables._round_int_variables  s    
 ||Okk)$(()C)-Y)?@S)TV3xOxxt4H	4**S/CHHXc]3HSM
 	  	4 hhx{3 		4s   %0B +CCc           	         | j                   sy| j                  d   }|j                  d|d         }t        |      r{t	        j
                  |      }t        t        |            D ]N  }t	        j                  ||   d      }t	        j                  ||         ||<   ||   | j                  |<   |||<   P yt        j                  dj                  |d   |j                  dd            t               y)a  round integer variables of solutions in `pop_pheno` and store

        the original solutions in `self.archive`. `pop_pheno` should be a
        `list` of arrays. When `pop_pheno` is an array, it is overwritten
        and its original values may be lost.

        By design, fixed variables are never changed (they were removed
        from the _pheno_integer_variables index list too). Hence they are
        not rounded either.
    Nra  rh  re  Tr   zy
ask: len(integer_variables) > len(idx) = 0 which looks like a bug. 
 integer_variables={0}
 _pheno_integer_variables={1})rf  r_  r+   r   r   r"   r   r   ri  rM  r  r  r   RuntimeWarning)r   	pop_phenooptsr   r  rd   s         r   round_populationz&RoundIntegerVariables.round_population  s     ||{{9%hh148K3LMs8**S/C3y>*HHYq\5!C&)#"+A,Q 	!	 + NN > $VD)<$=$(HH-G$NP*,r   c           
         | j                   rt        | j                        dk(  r|S | xj                  dz  c_        t        | j                        t        |      k  rt        | j                  j                        dk(  rjt        j                  dj                  t        |      t        | j                        | j                  t        | j                  j                                     |D cg c]  }| j                  j                  ||        }}|s|r| j                  ||||       | j                  j                  |       |S c c}w )aJ  revert `round_population` of `solutions` and return a new `list`

        when integer variables and archived solutions are present,
        otherwise return `solutions` as is.

        If `revert_modfied`, try to retrieve the nonrounded versions of
        solutions even when they were modified between `ask` and `tell`.
        This means that the modification is ignored in `tell`, while it
        might have been used to compute the fitness.

        Truncate the archive if necessary.

        Details: this method is entirely ignorant about whether or how
        solutions were rounded or transformed. However, it calls
        `_catch_modified` which uses `round_integer_variables` and
        `_round_int_variables` to compute a delta of an unexpected
        modification to avoid unnecessary warnings when the delta is zero.
    r   r	   z
 unrounded_population(iteration={2}): solutions passed to `tell` = {0} > {1} = solutions phenotype-archived by `ask` (len(.data_with_same_key) = {3}).
  Consider using the ``.inject`` method for outside solution proposals.)revertr  )rf  r   rM  rS  data_with_same_keyr  r  r   r>  _catch_modifiedtruncate_to)r   	solutionsrevert_modifiedr  	final_lenr   u_solutionss          r   unrounded_populationz*RoundIntegerVariables.unrounded_population  s
   * ||s4<<0A5

a
t||s9~-#dll6U6U2VZ[2[ NN :
 IDLL(94::DLL;;<>? 8AAy!t||''1-yAd  i(7d ! D  + Bs   -#Ec           
      8   t        | j                        rt        | j                  j                  j	                               D ]  \  }}t        j                  |      }t        |      D ]  \  }}	||	u st        j                  ||	k(        s#| j                  j                  |      }
|r|
||<   d}nd}| j                  d   r(t        j                  |	      | j                  |
      z
  }nd}|r2t        |      r't        j                  dj                  ||	||                t        | j                        rYt        j                  dj                  t        | j                        t        | j                  j!                                            t        | j                  j"                        rht        j                  dj                  t        | j                  j"                        | j                  j"                               i | j                  _        yy)	ar  catch modified `solutions` to revert their rounding too and/or

        warn of inconcistencies. This should normally do nothing as the
        archive should be empty. Elements of `popped_solutions` are the
        nonrounded versions of `solutions` and may be reassigned (which
        changes the reference when it is a `list`, but the content when it
        is an ndarray).

        Modifications between storing and retrieving a solution are found
        by comparing to the unhashed key which only reflects inplace
        modifications.

        Uses `round_integer_variables` which is an argument of the class
        instance constructor and then `._round_int_variables` to compute a
        delta to warn only when the delta is nonzero.

        TODO: instead of using `._round_int_variables` pass an optional
        `transformation` making this much more generic.
    zh
 Because ``cma.evolution_strategy.round_integer_revert_changes is True``,
 the modification is ignored. rb  z`unkown`z
_catch_modified<-unrounded_population<-tell: solution with index {0} = 
    {1}
 was modified by 
    {2}
 between calling `ask` and `tell`.
 Modifications often lead to unexpected and/or undesired results.{3}z
tell: {0} solution(s) of round int archive have not been consumed.
 These have been delivered by ask but not been passed to tell: {1}z
tell, _catch_modified: {0} keys with seemingly identical solutions were found (as delivered in `ask`) which is highly unusual. Namely
  {1}
(shown are only the second and further identical solutions).N)r   rM  r  _unhashed_keysrL  r   r"   r[   r   r>  r_  rl  r   r  r  r   valuesrt  )r   popped_solutionsrw  rs  r  keyr   avalr  r   
s_archiveds3s_deltas                r   ru  z%RoundIntegerVariables._catch_modified  s   * t|| !<!<!B!B!DESzz#%i0DAqax266$!)#4 &*\\%5%5c%:
!2<,Q/#FB "$B;;'@A&(jjmd6O6OPZ6[&[G&0GCL%NN ,@ "(1gr!:< 1 1 F8 t||NN aDLL)T\\002356 t||../NN Y "6#dll&E&E"F"&,,"A"AC	D /1DLL+ 0r   Nr   )TTr   )TT)r-   r.   r/   r0   r   r   rf  rl  rq  r{  ru  r1   r   r   r\  r\    s>     @ @,,> IJ-^>1r   r\  )!r0   
__future__r   r   r   numpyr   r   r   r   warningsr  utilities.utilsr
   r   r   r   r7  utilities.python3for2r   objectr   r3   rG   rt   r   r   r   r   r   r   r/  r\  r1   r   r   <module>r     s    ? @ @  & &  X X (X~(2f (2T-2v -2^7pv 7pr,L $( %  <x8*J x8t	Ov Ob~%' ~%@
O Ob1F 1r   