o
    wZŽh¸F  ã                   @   sd   d dl mZmZ d dlZd dlmZ ddlmZmZ dgZddd„Z		ddd„Z
G dd„ deƒZdS )é    )ÚOptionalÚUnionN)ÚTensoré   )Ú	OptimizerÚParamsTÚLBFGSc                 C   sà   |d ur	|\}}n| |kr| |fn|| f\}}|| d||  | |   }	|	d ||  }
|
dkrj|
  ¡ }| |krN|||  || |	 || d|     }n| | | || |	 || d|     }tt||ƒ|ƒS || d S )Né   é   r   g       @)ÚsqrtÚminÚmax)Úx1Úf1Úg1Zx2Úf2Úg2ÚboundsZ
xmin_boundZ
xmax_boundZd1Z	d2_squareZd2Zmin_pos© r   ú@/var/www/auris/lib/python3.10/site-packages/torch/optim/lbfgs.pyÚ_cubic_interpolate   s   
	*(r   ç-Cëâ6?çÍÌÌÌÌÌì?ç•Ö&è.>é   c           !   	   C   s   |  ¡  ¡ }|jtjd}| |||ƒ\}}d}| |¡}d|||f\}}}}d}d}||
k rÆ|||| |  ks@|dkrV||krV||g}||g}||jtjdg}||g}npt |ƒ| | krk|g}|g}|g}d}n[|dkr…||g}||g}||jtjdg}||g}nA|d||   }|d }|}t||||||||fd}|}|}|jtjd}|}| |||ƒ\}}|d7 }| |¡}|d7 }||
k s.||
krÖd|g}||g}||g}d}|d |d	 krâd
nd\}}|sþ||
k rþt |d |d  ƒ| |	k rþn t|d |d |d |d |d |d ƒ}dt|ƒt|ƒ  } tt|ƒ| |t|ƒ ƒ| k rb|s>|t|ƒks>|t|ƒkr_t |t|ƒ ƒt |t|ƒ ƒk rVt|ƒ|  }nt|ƒ|  }d}nd}nd}| |||ƒ\}}|d7 }| |¡}|d7 }|||| |  ks‹||| kr°|||< |||< |jtjd||< |||< |d |d kr«d
nd\}}nGt |ƒ| | kr½d}n%||| ||   dkrâ|| ||< || ||< || ||< || ||< |||< |||< |jtjd||< |||< |sþ||
k sî|| }|| }|| }||||fS )N©Zmemory_formatr   r   FTg{®Gáz„?é
   )r   éÿÿÿÿ)r   r   )r   r   gš™™™™™¹?)Úabsr   ÚcloneÚtorchÚcontiguous_formatÚdotr   r   )!Úobj_funcÚxÚtÚdÚfÚgÚgtdÚc1Úc2Útolerance_changeZmax_lsZd_normZf_newZg_newÚls_func_evalsZgtd_newZt_prevZf_prevZg_prevZgtd_prevÚdoneZls_iterZbracketZ	bracket_fZ	bracket_gZbracket_gtdZmin_stepZmax_stepÚtmpZinsuf_progressZlow_posZhigh_posZepsr   r   r   Ú_strong_wolfe)   s¼   
$ÿ
Ù*ú ""
$ ¿Dr0   c                       s¢   e Zd ZdZ							d ded	eeef d
ede	e dededede	e
 f‡ fdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Ze ¡ dd„ ƒZ‡  ZS )!r   a¢  Implements L-BFGS algorithm.

    Heavily inspired by `minFunc
    <https://www.cs.ubc.ca/~schmidtm/Software/minFunc.html>`_.

    .. warning::
        This optimizer doesn't support per-parameter options and parameter
        groups (there can be only one).

    .. warning::
        Right now all parameters have to be on a single device. This will be
        improved in the future.

    .. note::
        This is a very memory intensive optimizer (it requires additional
        ``param_bytes * (history_size + 1)`` bytes). If it doesn't fit in memory
        try reducing the history size, or use a different algorithm.

    Args:
        params (iterable): iterable of parameters to optimize. Parameters must be real.
        lr (float, optional): learning rate (default: 1)
        max_iter (int, optional): maximal number of iterations per optimization step
            (default: 20)
        max_eval (int, optional): maximal number of function evaluations per optimization
            step (default: max_iter * 1.25).
        tolerance_grad (float, optional): termination tolerance on first order optimality
            (default: 1e-7).
        tolerance_change (float, optional): termination tolerance on function
            value/parameter changes (default: 1e-9).
        history_size (int, optional): update history size (default: 100).
        line_search_fn (str, optional): either 'strong_wolfe' or None (default: None).
    r   é   NçH¯¼šò×z>r   éd   ÚparamsÚlrÚmax_iterÚmax_evalÚtolerance_gradr,   Úhistory_sizeÚline_search_fnc	           
   	      sœ   t |tƒr| ¡ dkrtdƒ‚d|kstd|› ƒ‚|d u r$|d d }t|||||||d}	tƒ  ||	¡ t| jƒdkrAtdƒ‚| jd	 d
 | _	d | _
d S )Nr   zTensor lr must be 1-elementg        zInvalid learning rate: é   é   )r5   r6   r7   r8   r,   r9   r:   z>LBFGS doesn't support per-parameter options (parameter groups)r   r4   )Ú
isinstancer   ÚnumelÚ
ValueErrorÚdictÚsuperÚ__init__ÚlenÚparam_groupsÚ_paramsÚ_numel_cache)
Úselfr4   r5   r6   r7   r8   r,   r9   r:   Údefaults©Ú	__class__r   r   rB   Ù   s,   ù	ÿ
zLBFGS.__init__c                 C   s&   | j d u rtdd„ | jD ƒƒ| _ | j S )Nc                 s   s.    | ]}t  |¡rd | ¡  n| ¡ V  qdS )r
   N)r    Ú
is_complexr>   ©Ú.0Úpr   r   r   Ú	<genexpr>ÿ   s
   € ÿ
ÿzLBFGS._numel.<locals>.<genexpr>)rF   ÚsumrE   ©rG   r   r   r   Ú_numelý   s
   

þzLBFGS._numelc                 C   s„   g }| j D ]6}|jd u r| | ¡ ¡ ¡ }n|jjr#|j ¡  d¡}n|j d¡}t 	|¡r6t 
|¡ d¡}| |¡ qt |d¡S )Nr   r   )rE   ZgradÚnewr>   Zzero_Z	is_sparseZto_denseÚviewr    rK   Úview_as_realÚappendÚcat)rG   ZviewsrN   rT   r   r   r   Ú_gather_flat_grad  s   


zLBFGS._gather_flat_gradc                 C   sh   d}| j D ]$}t |¡rt |¡}| ¡ }|j|||| …  |¡|d ||7 }q||  ¡ ks2J ‚d S )Nr   ©Úalpha)rE   r    rK   rU   r>   Úadd_Zview_asrR   )rG   Z	step_sizeÚupdateÚoffsetrN   r>   r   r   r   Ú	_add_grad  s   


 
zLBFGS._add_gradc                 C   s   dd„ | j D ƒS )Nc                 S   s   g | ]	}|j tjd ‘qS )r   )r   r    r!   rL   r   r   r   Ú
<listcomp>   s    z&LBFGS._clone_param.<locals>.<listcomp>)rE   rQ   r   r   r   Ú_clone_param  ó   zLBFGS._clone_paramc                 C   s$   t | j|ƒD ]	\}}| |¡ qd S ©N)ÚziprE   Úcopy_)rG   Zparams_datarN   Zpdatar   r   r   Ú
_set_param"  s   ÿzLBFGS._set_paramc                 C   s0   |   ||¡ t|ƒ ƒ}|  ¡ }|  |¡ ||fS rb   )r^   ÚfloatrX   re   )rG   Úclosurer$   r%   r&   ÚlossÚ	flat_gradr   r   r   Ú_directional_evaluate&  s
   

zLBFGS._directional_evaluatec           &         s¦  t ˆjƒdks	J ‚t ¡ ˆ ƒ‰ ˆjd }|d }|d }|d }|d }|d }|d }|d	 }	ˆjˆjd  }
|
 d
d¡ |
 dd¡ ˆ ƒ }t|ƒ}d}|
d
  d7  < ˆ ¡ }| 	¡  
¡ |k}|re|S |
 d¡}|
 d¡}|
 d¡}|
 d¡}|
 d¡}|
 d¡}|
 d¡}|
 d¡}d}||k r1|d7 }|
d  d7  < |
d dkr³| ¡ }g }g }g }d}n¥| |¡}| |¡}| |¡}|dkrót |ƒ|	krÛ| d¡ | d¡ | d¡ | |¡ | |¡ | d| ¡ || |¡ }t |ƒ}d|
vrdg|	 |
d< |
d }| ¡ }t|d ddƒD ]}||  |¡||  ||< |j|| ||  d qt ||¡ }} t|ƒD ]}||  | ¡||  }!| j|| || |! d q<|du re|jtjd}n| |¡ |}|
d dkrtdd| 	¡  ¡  ƒ| }n|}| |¡}"|"| krn¢d}#|durÇ|dkrŸtdƒ‚ˆ ¡ }$‡ ‡fdd„}%t|%|$|||||"ƒ\}}}}#ˆ ||¡ | 	¡  
¡ |k}n3ˆ ||¡ ||krút ¡  tˆ ƒ ƒ}W d  ƒ n	1 sçw   Y  ˆ ¡ }| 	¡  
¡ |k}d}#||#7 }|
d
  |#7  < ||krn%||krn|rn| |¡ 	¡  
¡ |kr#nt	|| ƒ|k r-n||k s”||
d< ||
d< ||
d< ||
d< ||
d< ||
d< ||
d< ||
d< |S )z¦Perform a single optimization step.

        Args:
            closure (Callable): A closure that reevaluates the model
                and returns the loss.
        r   r   r5   r6   r7   r8   r,   r:   r9   Z
func_evalsÚn_iterr&   r%   Úold_dirsÚold_stpsÚroÚH_diagÚprev_flat_gradÚ	prev_lossg»½×Ùß|Û=g      ð?ÚalNr   rY   r   Zstrong_wolfez only 'strong_wolfe' is supportedc                    s   ˆ  ˆ | ||¡S rb   )rj   )r$   r%   r&   ©rg   rG   r   r   r#   ¹  ra   zLBFGS.step.<locals>.obj_func)rC   rD   r    Zenable_gradÚstaterE   Ú
setdefaultrf   rX   r   r   ÚgetÚnegÚsubÚmulr"   ÚpoprV   Úranger[   r   r!   rd   r   rP   ÚRuntimeErrorr`   r0   r^   )&rG   rg   Úgroupr5   r6   r7   r8   r,   r:   r9   rt   Z	orig_lossrh   Zcurrent_evalsri   Zopt_condr&   r%   rl   rm   rn   ro   rp   rq   rk   ÚyÚsZysZnum_oldrr   ÚqÚiÚrZbe_ir)   r-   Zx_initr#   r   rs   r   Ústep-  sè   























ÿ

ÿ

 ý z
LBFGS.step)r   r1   Nr2   r   r3   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   rf   r   Úintr   ÚstrrB   rR   rX   r^   r`   re   rj   r    Zno_gradrƒ   Ú__classcell__r   r   rI   r   r   ·   sD    $÷þ
ýüûúùø	÷$	rb   )r   r   r   r   )Útypingr   r   r    r   Z	optimizerr   r   Ú__all__r   r0   r   r   r   r   r   Ú<module>   s   

ÿ 