U
    •Ê¹jaC  ã                   @   sN   d dl Z d dlmZ ddlmZ dgZddd„Zddd„ZG dd„ deƒZdS )é    N)Úreduceé   )Ú	OptimizerÚLBFGSc                 C   sä   |d k	r|\}}n| |kr"| |fn|| f\}}|| d||  | |   }	|	d ||  }
|
dkrÔ|
  ¡ }| |krœ|||  || |	 || d|     }n(| | | || |	 || d|     }tt||ƒ|ƒS || d 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   úP/var/www/html/bwave/python/venv/lib/python3.8/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r°||kr°||g}||g}||jtjd�g}||g}�q�t |ƒ| | krÜ|g}|g}|g}d}�q�|dk�r||g}||g}||jtjd�g}||g}�q�|d||   }|d }|}t||||||||fd�}|}|}|jtjd�}|}| |||ƒ\}}|d7 }| |¡}|d7 }qT||
k�r²d|g}||g}||g}d}|d |d	 k�rÌd
nd\}}|�sü||
k �rüt |d |d  ƒ| |	k �r�qüt|d |d |d |d |d |d ƒ}dt|ƒt|ƒ  } tt|ƒ| |t|ƒ ƒ| k �rÎ|�s†|t|ƒk�s†|t|ƒk�rÈt |t|ƒ ƒt |t|ƒ ƒk �r¶t|ƒ|  }nt|ƒ|  }d}nd}nd}| |||ƒ\}}|d7 }| |¡}|d7 }|||| |  k�s ||| k�rj|||< |||< |jtjd�||< |||< |d |d k�r`d
nd\}}nŽt |ƒ| | k�r„d}nJ||| ||   dk�rÎ|| ||< || ||< || ||< || ||< |||< |||< |jtjd�||< |||< �qÔ|| }|| }|| }||||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_posÚepsr   r   r   Ú_strong_wolfe#   s¾    

$
ù



  ÿ
 ""
$ r.   c                       sb   e Zd ZdZd‡ 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:
        lr (float): learning rate (default: 1)
        max_iter (int): maximal number of iterations per optimization step
            (default: 20)
        max_eval (int): maximal number of function evaluations per optimization
            step (default: max_iter * 1.25).
        tolerance_grad (float): termination tolerance on first order optimality
            (default: 1e-7).
        tolerance_change (float): termination tolerance on function
            value/parameter changes (default: 1e-9).
        history_size (int): update history size (default: 100).
        line_search_fn (str): either 'strong_wolfe' or None (default: None).
    r   é   NçH¯¼šò×z>r   éd   c	           
   	      sh   |d kr|d d }t |||||||d�}	tƒ  ||	¡ t| jƒdkrNtdƒ‚| jd d | _d | _d S )Né   é   )ÚlrÚmax_iterÚmax_evalÚtolerance_gradr)   Úhistory_sizeÚline_search_fnr   z>LBFGS doesn't support per-parameter options (parameter groups)r   Úparams)ÚdictÚsuperÚ__init__ÚlenÚparam_groupsÚ
ValueErrorÚ_paramsÚ_numel_cache)
Úselfr:   r4   r5   r6   r7   r)   r8   r9   Údefaults©Ú	__class__r   r   r=   ×   s     	ùzLBFGS.__init__c                 C   s$   | j d krtdd„ | jdƒ| _ | j S )Nc                 S   s   | |  ¡  S ©N)Únumel)ÚtotalÚpr   r   r   Ú<lambda>õ   ó    zLBFGS._numel.<locals>.<lambda>r   )rB   r   rA   ©rC   r   r   r   Ú_numeló   s    
zLBFGS._numelc                 C   sj   g }| j D ]R}|jd kr,| | ¡ ¡ ¡ }n&|jjrF|j ¡  d¡}n|j d¡}| |¡ q
t	 
|d¡S )Nr   r   )rA   ZgradÚnewrH   Zzero_Z	is_sparseZto_denseÚviewÚappendr   Úcat)rC   ZviewsrJ   rP   r   r   r   Ú_gather_flat_gradø   s    

zLBFGS._gather_flat_gradc                 C   sT   d}| j D ]4}| ¡ }|j|||| …  |¡|d� ||7 }q
||  ¡ ksPt‚d S )Nr   ©Úalpha)rA   rH   Úadd_Zview_asrN   ÚAssertionError)rC   Z	step_sizeÚupdateÚoffsetrJ   rH   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   )Ú.0rJ   r   r   r   Ú
<listcomp>  s     z&LBFGS._clone_param.<locals>.<listcomp>)rA   rM   r   r   r   Ú_clone_param  s    zLBFGS._clone_paramc                 C   s$   t | j|ƒD ]\}}| |¡ qd S rG   )ÚziprA   Úcopy_)rC   Zparams_datarJ   Zpdatar   r   r   Ú
_set_param  s    zLBFGS._set_paramc                 C   s0   |   ||¡ t|ƒ ƒ}|  ¡ }|  |¡ ||fS rG   )rZ   ÚfloatrS   r`   )rC   Úclosurer!   r"   r#   ÚlossÚ	flat_gradr   r   r   Ú_directional_evaluate  s
    

zLBFGS._directional_evaluatec           &   	      s¢  t ˆjƒdkst‚t ¡ ˆ ƒ‰ ˆjd }|d }|d }|d }|d }|d }|d }|d	 }	ˆjˆjd  }
|
 d
d¡ |
 dd¡ ˆ ƒ }t|ƒ}d}|
d
  d7  < ˆ 	¡ }| 
¡  ¡ |k}|rÊ|S |
 d¡}|
 d¡}|
 d¡}|
 d¡}|
 d¡}|
 d¡}|
 d¡}|
 d¡}d}||k �r^|d7 }|
d  d7  < |
d dk�rj| ¡ }g }g }g }d}�nN| |¡}| |¡}| |¡}|dk�rît |ƒ|	k�r¾| d¡ | d¡ | d¡ | |¡ | |¡ | d| ¡ || |¡ }t |ƒ}d|
k�rdg|	 |
d< |
d }| ¡ }t|d ddƒD ]8}||  |¡||  ||< |j|| ||  d� �q.t ||¡ }} t|ƒD ]6}||  | ¡||  }!| j|| || |! d� �q€|dk�rÒ|jtjd�}n
| |¡ |}|
d dk�r
tdd| 
¡  ¡  ƒ| }n|}| |¡}"|"| k�r(�q^d}#|dk	�rš|dk�rJtdƒ‚n2ˆ ¡ }$‡ ‡fdd„}%t|%|$|||||"ƒ\}}}}#ˆ ||¡ | 
¡  ¡ |k}nPˆ ||¡ ||k�rêt ¡ � tˆ ƒ ƒ}W 5 Q R X ˆ 	¡ }| 
¡  ¡ |k}d}#||#7 }|
d
  |#7  < ||k�r�q^||k�r�q^|�r(�q^| |¡ 
¡  ¡ |k�rD�q^t
|| ƒ|k �r�q^�q||
d< ||
d< ||
d< ||
d< ||
d< ||
d< ||
d< ||
d< |S )z§Performs a single optimization step.

        Args:
            closure (Callable): A closure that reevaluates the model
                and returns the loss.
        r   r   r4   r5   r6   r7   r)   r9   r8   Z
func_evalsÚn_iterr#   r"   Úold_dirsÚold_stpsÚroÚH_diagÚprev_flat_gradÚ	prev_lossg»½×Ùß|Û=g      ð?ÚalNr   rT   r   Zstrong_wolfez only 'strong_wolfe' is supportedc                    s   ˆ  ˆ | ||¡S rG   )re   )r!   r"   r#   ©rb   rC   r   r   r    §  s    zLBFGS.step.<locals>.obj_func)r>   r?   rW   r   Zenable_gradÚstaterA   Ú
setdefaultra   rS   r   r
   ÚgetÚnegÚsubÚmulr   ÚpoprQ   ÚrangerV   r   r   r_   r	   ÚsumÚRuntimeErrorr]   r.   rZ   )&rC   rb   Úgroupr4   r5   r6   r7   r)   r9   r8   ro   Z	orig_lossrc   Zcurrent_evalsrd   Zopt_condr#   r"   rg   rh   ri   rj   rk   rl   rf   ÚyÚsZysZnum_oldrm   ÚqÚiÚrZbe_ir&   r*   Zx_initr    r   rn   r   Ústep  sì    

























      ÿ



z
LBFGS.step)r   r/   Nr0   r   r1   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r=   rN   rS   rZ   r]   r`   re   r   Zno_gradr   Ú__classcell__r   r   rE   r   r   ¸   s"           ø	)N)r   r   r   r   )	r   Ú	functoolsr   Z	optimizerr   Ú__all__r   r.   r   r   r   r   r   Ú<module>   s   
#    ö
 