B
    \\A                 @   s   d dl Z d dlZd dlmZ d dlZd dlZd dlm	Z
 d dlZd dl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	d
Zd&ddZd'ddZd(ddZd)ddZd*ddZd+ddZd,d d!Zd-d#d$ZdS ).    N)OrderedDict   )__version__util)	Empirical)Graph)TraceTc             C   s  i }i }|d k	r"|d }|d }ni }i }xlt | jD ]\}| |}t| |}	x<|jD ]0}
|
j}|
j}|rz|n|}||kr|| d  d7  < || d  |	7  < q`||kr|| }n|r|dr|dd  }ndt	t
|d  }n||dr(|dd  d	 |
jrd
nt	|
j }nH||krNdt	t
|d  }|||< || d	 |
jrdd
nt	|
j }|||< d|	||
d||< |
||< q`W q8W tt| dd d}t }t|d< tj|d< t
| |d< t
||d< t
dd t| D |d< t
dd t| D |d< t
dd t| D |d< t
dd t| D |d< t
dd t| D |d< |||||dS )Naddress_idsaddress_base_idscountr   weightZ__A   A__replaced)r   r   
address_idvariablec             S   s   t | d d S )Nr   r   )r   address_id_to_int)v r   U/global/project/projectdirs/dasrepo/etalumis/pyprob_distributed/pyprob/diagnostics.py<lambda>7   s    z _address_stats.<locals>.<lambda>)keypyprob_versiontorch_versionZnum_distribution_elements	addressesc             S   s   g | ]}|d  j rdqS )r   r   )control).0valuer   r   r   
<listcomp>=   s    z"_address_stats.<locals>.<listcomp>Zaddresses_controlledc             S   s   g | ]}|d  j rdqS )r   r   )replace)r   r   r   r   r   r   >   s    Zaddresses_replacedc             S   s   g | ]}|d  j rdqS )r   r   )
observable)r   r   r   r   r   r   ?   s    Zaddresses_observablec             S   s   g | ]}|d  j rdqS )r   r   )observed)r   r   r   r   r   r   @   s    Zaddresses_observedc             S   s   g | ]}|d  j rdqS )r   r   )tagged)r   r   r   r   r   r   A   s    Zaddresses_tagged)r   addresses_extrar
   r	   address_id_to_variable)rangelength
_get_valuefloat_get_weight	variablesaddress_baseaddress
startswithstrlenr    instancer   sorteditemsr   torchlistvalues)
trace_distuse_address_basereuse_ids_from_address_statsr   r%   r	   r
   itracetrace_weightr   r,   r-   r   r   Zaddress_base_idr$   r   r   r   _address_stats   sX    



(
"
r=   c          
      s  t | |d}|d  i }|d k	r,|d }ni }xt| jD ]}| |}t| |}	dfdd|jD }
|
|kr|
|kr||
 }ndtt	|d  }|||
< d	g fd
d|jD  dg }d|	|||d||
< q<||
 d  d7  < ||
 d  |	7  < q<W t
t| dd dd}dd tt	 D }g }x$  D ]\}}||d  qJW t||dd}dd tt	|D }g }x$| D ]\}}||d  qW t||dd}| dd  d}| dd  d}| dd  d}t
 }t	||d< t|j|d< t|j|d < t|j|d!< t|j|d"< t|j|d#< t|j|d$< t|j|d%< t|j|d&< t|j|d'< t|j|d(< t|j|d)< t|j|d*< |||||||||d+	S ),N)r8   r9   r   	trace_ids c                s   g | ]} r|j n|jqS r   )r,   r-   )r   r   )r8   r   r   r   P   s    z _trace_stats.<locals>.<listcomp>Tr   ZSTARTc                s$   g | ]} r|j n|j d  qS )r   )r,   r-   )r   r   )r   r8   r   r   r   W   s    END)r   r   trace_idr;   address_id_sequencer   r   c             S   s   | d d S )Nr   r   r   )r   r   r   r   r   \   s    z_trace_stats.<locals>.<lambda>T)r   reversec             S   s   g | ]}|qS r   r   )r   r:   r   r   r   r   ]   s    z
Address ID)weightsnamec             S   s   g | ]}|qS r   r   )r   r:   r   r   r   r   b   s    zUnique trace IDc             S   s   | j S )N)r'   )r;   r   r   r   r   g   s    zTrace length (all)c             S   s   | j S )N)length_controlled)r;   r   r   r   r   h   s    zTrace length (controlled)c             S   s   | j S )N)execution_time_sec)r;   r   r   r   r   i   s    zTrace execution time (s)Ztrace_typesZtrace_length_minZtrace_length_maxZtrace_length_meanZtrace_length_stddevZtrace_length_controlled_minZtrace_length_controlled_maxZtrace_length_controlled_meanZtrace_length_controlled_stddevZtrace_execution_time_minZtrace_execution_time_maxZtrace_execution_time_meanZtrace_execution_time_stddev)	tracestraces_extrar>   address_statstrace_id_disttrace_length_disttrace_length_controlled_disttrace_execution_time_distaddress_id_dist)r=   r&   r'   r(   r)   r*   joinr+   r/   r0   r   r2   r3   appendr   map
unweightedrenameminmaxmeanstddev)r7   r8   r9   Zreuse_ids_from_trace_statsrK   rI   r>   r:   r;   r<   Z	trace_strrB   rC   r	   Zaddress_weightsr   r   rP   Zunique_trace_idsZtrace_weights_rL   rM   rN   rO   rJ   r   )r   r8   r   _trace_statsE   s`    


"r[   
         Fc             C   s"  t | |d}|d }|d }	|r|s:dtjd< td tjdd|d\}
}|d	  }|d	  }|d	 j}|d
 j	||d|d |d
 
| |d
 d |d
 jddd |d  }|d  }|d j}|d j	||d|d |d 
| |d jddd |d  }|d  }|d j}|d j	||dt|d |d 
| |d d |d jddd |d  }|d  }|d j}|d j	||d|d |d 
| |d jddd tj| jdddddd tjddddgd  |d k	r|d! }td"| t| |d# }td$| t|d%:}|d& x(|	 D ]\}}|d'|| qZW W d Q R X |d( }td)| t|d%f}|d* xT| D ]H\}}|d+|d, |d- t|d. jt|d. jd/|d0  qW W d Q R X |rt  d S )1N)r8   rI   rJ   Fzaxes.unicode_minusaggr   )figsizerM   )r   r   r   )rE   densitybins	Frequencylogclip)nonposyrN   )r   r   rP   )r   r   rO   )r   r   g        gGz?lefttopr]   )xyhorizontalalignmentverticalalignmentfontsizer   gQ?gffffff?)rectz.pdfzPlotting to file: {}z.txtzSaving trace report to file: {}wzpyprob diagnostics
z{}: {}
z.csvzSaving traces to file: {}z@trace_id, count, length, length_controlled, address_id_sequence
z{}, {}, {}, {}, {}
rB   r   r;    rC   )r[   mplrcParamspltswitch_backendsubplotsvalues_numpyweights_numpyrF   hist
set_xlabel
set_ylabel
set_yscaler0   suptitletight_layoutprintformatsavefigopenwriter3   r+   variables_controlledrQ   show)r7   r8   ra   rc   plot	plot_show	file_nameZtrace_statsrI   rJ   figaxr6   rE   rF   plot_file_namereport_file_namefiler   r   Ztraces_file_namer   r   r   trace_histograms{   sl    








"
Nr         c       )         s  t | ts| g} i }d }	i }
x| D ]}td|j t|||	d}	|	d }x>| D ]2\}}||
kr|
| d  |d 7  < qZ||
|< qZW |d }d}tdt	|d x8| D ]*\}}t
| |d	7 }|d
 }|d }d}y|r.|j|fddfdddd dd }n:|j | fdd fdddd dd }||jd kr|d nd||j |jdkrd}W n tk
r   d}Y nX |r||kri ||< ||f|| |j< qW t  q$W |r|sdtjd< td dtjd< tt	|\}}tj|||d\}}| }d}ttddd d!d"d#d$d%d&d'd(d)g}i }td*t	|d+ x~| D ]p\}}t
| xP| D ]B\}}|d }|d	 }| }| }||krd } || }!n|} | }!|!||< t|jd,r6t |jj!t |jj"f}"nd }"|| j#||d	||!| d-|"d. || j$|jdd/d0 || j%d1d2d3 |d k	rd }#|r|j|j&krt |j& j'}#n"|j  |j(krt |j(  j'}#|#d k	r|| j)|#d4d5d6d7 qW |d	7 }qW t  |*  tj+d8d/d8d/d9d:d; |d k	r|d< }$td=|$ t,|$ |d> }%td?|% t-|%d@R}&|&.dA |&.|rdBnddC  x(| D ]\}}|&.dD|| qW W d Q R X |dE }'tdF|' t-|'d@}&|&.dG|r
dHndI xr|
 D ]f\}}|d jd kr8dn|d j}(|&.dJ|d
 |d |(|d j/|d j0|d j1|d j2| qW W d Q R X |rt3  d S )KNz&Collecting values for distribution: {})r8   r9   r   r   address_stats_extrar   zCollecting valuesZ	Addressesr   r   r   Tc                s
    | j kS )N)variables_dict_address_base)r;   )r,   r   r   r      s    z$address_histograms.<locals>.<lambda>c                s   t | j  jS )N)r   	to_tensorr   r   )r;   )r,   r   r   r      s    c             S   s
   t | S )N)r4   	is_tensor)r   r   r   r   r      s    c             S   s   |   dkS )Nr   )nelement)r   r   r   r   r      s    c                s
    | j kS )N)variables_dict_address)r;   )r-   r   r   r      s    c                s   t | j  jS )N)r   r   r   r   )r;   )r-   r   r   r      s    c             S   s
   t | S )N)r4   r   )r   r   r   r   r      s    c             S   s   |   dkS )Nr   )r   )r   r   r   r   r      s    r?   z{} ({})Fzaxes.unicode_minusr`      z	font.size)ra   z#1f77b4z#ff7f0ez#2ca02cz#d62728z#9467bdz#8c564bz#e377c2z#7f7f7fz#bcbd22z#17becfbkzPlotting histogramsZ
Histogramslowg?)rE   rb   rc   colorlabelalphar&   gffffff?)rn   rk   g        r   )padr'   dashedgrayg      ?)rj   	linestyler   	linewidthg?g      ?g333333?)rh   rightbottomri   hspacewspacez.pdfzPlotting to file: {}z.txtz!Saving address report to file: {}rp   zpyprob diagnostics
zaggregated zaddress report
z{}: {}
z.csvzSaving addresses to file: {}zHaddress_id, count, name, controlled, replaced, observable, observed, {}
r,   r-   z{}, {}, {}, {}, {}, {}, {}, {}
)4
isinstancer5   r   r   rF   r=   r3   r   progress_bar_initr0   progress_bar_updater,   filterrS   r-   rU   r'   	Exceptionprogress_bar_endrr   rs   rt   ru   tile_rows_colsrv   flattenreversedrw   rx   pophasattrdistributionr)   r   highry   	set_titletick_paramsr   r   r   axvlinelegendsubplots_adjustr   r   r   r   r    r!   r"   r   ))trace_distsground_truth_tracera   rc   r8   r   r   r   distsrK   Zaddress_stats_combinedr7   r   r   valr   r:   r   r   r   Z
can_renderdistrowscolsr   r   Zhist_color_cycleZhist_colorsZtrace_dist_namer   r6   rE   r   r   r&   Zvline_xr   r   r   Zaddresses_file_namerF   r   )r-   r,   r   address_histograms   s    

64(




$







"Nr   c          	   C   s  | j | j }| j| j }| j| j  }| jd }| jd }|| }|| j }|| j  }	|| j }
t| jdkr| jd }| jd }|| }|| j }|| j  }|| j }t }t|d< tj|d< | j	|d< | j
d |d< | j|d< | j|d< | j|d	< t| j|d
< | jd k	|d< | j|d< | j|d< t| j|d< | j|d< | j|d< | j|d< | j|d< | j|d< | j |d< ||d< ||d< ||d< ||d< ||d< ||d< |	|d< |
|d< t| jdkr||d< ||d< ||d< ||d < ||d!< |d k	rtj|std"| t| tj|d#}td$| t|d%Z}|d& x(| D ]\}}|d'|| qRW |d( |tt | !  W d Q R X d)t"j#d*< t$%d+ tj|d,}tj|d-}tj|d.}td/| t$j&d0d1}t$'d2}|j(| j)| jd3d4 |j(| j*| jd5d4 |+  t$,d6 t$-d7 t$.  |/  t$0| t12|t13| j t12|t13| j* |S )8Nr   zpyprob versionztorch versionznetwork typeznumber of parameterszpre-generated layersmodifiedZupdatesztrained on devicezdistributed trainingzdistributed backendzdistributed world size	optimizerzlearning ratemomentumz
batch sizeztotal train. secondsztotal train. tracesztotal train. iterationsztrain. iter. per secondztrain. traces per secondztrain. traces per iter.ztrain. loss initialztrain. loss finalztrain. loss change per secondztrain. loss change per iter.ztrain. loss change per tracezvalid. loss initialzvalid. loss finalzvalid. loss change per secondzvalid. loss change per iter.zvalid. loss change per tracez&Directory does not exist, creating: {}zinference_network_stats.txtz(Saving diagnostics information to {} ...rp   zpyprob diagnostics report
z{}: {}
zarchitecture:
Fzaxes.unicode_minusr`   zloss.pdfzvalid_loss.npyzvalid_loss_trace.npyzPlotting loss to file: {} ...)r]      )ra   o   ZTraining)r   Z
ValidationzTraining tracesZLoss)4_total_train_iterations_total_train_seconds_total_train_traces_history_train_lossr0   _history_valid_lossr   r   r4   _network_type_history_num_params_layers_pre_generated	_modified_updatesr/   _device_distributed_backend_distributed_world_size_optimizer_type_learning_rate	_momentum_batch_sizeospathexistsr   r   makedirsrQ   r   r   r3   nextmodulesrr   rs   rt   ru   figuresubplotr   _history_train_loss_trace_history_valid_loss_tracer   xlabelylabelgridr~   r   npsaveasarray)inference_networkZsave_dirZtrain_iter_per_secZtrain_traces_per_secZtrain_traces_per_iterZtrain_loss_initialZtrain_loss_finalZtrain_loss_changeZtrain_loss_change_per_secZtrain_loss_change_per_iterZtrain_loss_change_per_traceZvalid_loss_initialZvalid_loss_finalZvalid_loss_changeZvalid_loss_change_per_secZvalid_loss_change_per_iterZvalid_loss_change_per_tracestatsZfile_name_statsr   r   r   Zfile_name_lossZfile_name_valid_loss_npyZfile_name_valid_loss_trace_npyr   r   r   r   r   network/  s    


























 





r   c             C   sb   t | |||d}|d k	r^|j||d x6| D ]*\}}|jd|||d krR|n|d q0W |S )N)r7   r8   n_most_frequent
base_graph)Zbackground_graphz{}_{})r   Zrender_to_fileZtrace_graphsr   )r7   r8   r   r   r   graphrB   Ztrace_graphr   r   r   r     s    &r     	IterationLog probabilityc                s  t  tkrtd|d kr d}g }g }xtt D ]t}t  | d tkrZtd|d krn | j}nt | j|}|| }|tt||t	dt
||  t }d}tt|}td tdd|d d  g }x|| D ]}| | |j t | }|| tjks6||d kr|}|d | }tdt|t|| | t|d |t|d |||d	d
 tj  qW t  || q8W |
r|sdtjd< td tj|d}|d kr fddtt|D }x>tt|D ].}tj|| || f||d|| i qW |rRt d |	rftj!ddd |d k	rzt"| |d k	rt"| t#| t$| tj%dd |&  |d k	rtd| t'| |rt(  t)*|t)*|fS )NzbExpecting a list of posterior trace distributions, each from a call to a Model's posterior_traces.r   r   z,Loading trace log-probabilities to memory...zBTime spent  | Time remain.| Progress             | {} | Traces/secr   r   z%{} | {} | {} | {}/{} | {:,.2f}       )endFzaxes.unicode_minusr`   )ra   c                s   g | ]}d   | jqS )z{})r   rF   )r   r:   )r   r   r   r     s    zlog_prob.<locals>.<listcomp>r   re   rf   )rg   best)loczPlotting to file {} ...)+typer5   	TypeErrorr&   r0   r   r'   rV   rR   rW   inttimer/   r   r   ljustr(   log_probr   _print_refresh_ratedays_hours_mins_secs_strprogress_barrjustsysstdoutflushrr   rs   rt   ru   r   r   xscaleyscalexticksr   r   r   r~   r   r   r   array)r   
resolutionnamesra   r   r   r  yticks
log_xscale
log_yscaler   r   r   	min_index	max_indexargskwargsmin_iiters	log_probsjmax_i
num_traces
time_startprev_durationlen_str_num_tracesvalsr:   durationtraces_per_secondr   r   )r   r   r     sr    $J


.








r   LagAutocorrelationc          	      s@  t | tkrtdt | d tkr,tddd }|d kr`ttdt| jd 	t
}t }|d krxx| d j D ]2\}}|js~|j dkr~t| j||j|f< q~W n2x0|D ](}| d j| j}t| j|||f< qW |d k	ri }| j td  xrt D ]f}t| | |}xJ|jD ]@}|j dkr2|j}||kr`d||< n||  d7  < q2W qW  fd	d
| D }tt| dd dd}d}x>| D ]2\}}t| j||d f< |d7 }||krP qW t  t|dkrtdtt| dd}| j td  xVt D ]J}| |}x.| D ]"\\}}}t|j| j||< qTW t| q<W t  i }d}xF| D ]:\\}}}|d7 }td||t| |||||< qW |
r8|s dt j!d< t"#d t"j$|d}t"j%dddd d}x| D ]z\\}}}|d krd }|s\dt|}d}t"j&||| f||dd|d n t"j&||| f||d|i q*W |	rt"'d |d k	rt"(| |d k	rt"(| t")| t"*| t"j+dd |,  |d k	r*td | t"-| |r8t".  ||fS )!NzTExpecting a posterior trace distribution, from a call to a Model's posterior_traces.r   c                s   t  fdd|D }|S )Nc                s>   g | ]6}|d krdn$t  |d  d|  d  d qS )r   g      ?Nr   )r   corrcoef)r   lag)r6   r   r   r     s    z=autocorrelations.<locals>.autocorrelation.<locals>.<listcomp>)r   r  )r6   lagsretr   )r6   r   autocorrelation  s    z)autocorrelations.<locals>.autocorrelationr   r   r   z%Collecting most frequent addresses...c                s   i | ]\}}| kr||qS r   r   )r   r   r   )r  r   r   
<dictcomp>  s    z$autocorrelations.<locals>.<dictcomp>c             S   s   | d S )Nr   r   )rj   r   r   r   r     s    z"autocorrelations.<locals>.<lambda>T)r   rD   z2No variables with scalar value have been selected.)rD   z'Loading selected variables to memory...z=Computing autocorrelation for variable name: {} ({} of {})...Fzaxes.unicode_minusr`   )ra   black)rk   r   r   z{} most frequent addressesr   )r   r   r   r   re   r   )r   zPlotting to file {} ...)/r   r   r   r   r   uniquelogspacelog10r'   astyper   r   named_variablesr3   r"   r   r   zerosr-   r   r   r&   r   r(   r   r2   r   r0   RuntimeErrorr)   r   r   rr   rs   rt   ru   r   axhliner   r  r  r   r   r   r~   r   r   )r7   r  r   r   ra   r   r   r  r	  r
  r   r   r   r  r  r"  variable_valuesrF   r   r-   address_countsr:   r;   all_variables_countr   r6   Zvariable_autocorrelationsr   other_legend_addedr   r   )r  r   autocorrelations  s    $










&&








r1  R-hatc       $         s~  dd }d#ddfdd}fdd}i }d	d
 D }t |t|kr`td xD ]}||||}qfW ttdtt	}fdd|
 D }x |
 D ]\\}}}tt| }|\  fdd
t|jd D }|rt|n|jd d }|dkrJ|d d |d f }||||f< xhttD ]X}||df }xDt|jd D ]2}t|||f r||||f< |||f }qxW qXW qW i }d}xH|
 D ]<\\}}} |d7 }td||t| || |||< qW |
rv|s*dtjd< td tj|d}!tjdddd d}"x|
 D ]z\\}}} |d krd }#|"sdt|}#d}"tj||| f||dd|#d n tj||| f||d|i qTW |rtd |	rtjddd |d k	r
t| |d k	rt| t| t| tjd d! |!  |d k	rhtd"| t| |rvt  ||fS )$Nc             S   sB   x<|  D ]0\}}|| kr2t| | |f| |< q
|| |< q
W | S )N)r3   r   vstack)d1d2r   r   r   r   r   merge_dicts6  s
    z!gelman_rubin.<locals>.merge_dictsc             S   s   | j d | j d  }}|dk r&tdtj| dd}tj| ddd}|rL|ntj|dd}t|t|d  t|| d  }dt| tj|dd }t|d t| | |t|  }	t|	| }
|
S )u5  
        Notes
        -----
        The diagnostic is computed by:  math:: \hat{R} = rac{\hat{V}}{W}

        where :math:`W` is the within-chain variance and :math:`\hat{V}` is
        the posterior variance estimate for the pooled traces.

        :param x: samples
        :param mu, var: true posterior mean and variance; if None, Monte Carlo estimates
        :param logger: None
        :return: r_hat

        References
        ----------
        Gelman et. al. (2012). ‘Bayesian Data Analysis, Third Edition’
        Brooks and Gelman (1998)
        r   r   r   zDGelman-Rubin diagnostic requires multiple chains of the same length.)axis)r7  ddofg      ?)shape
ValueErrorr   rX   varr)   sumsqrt)rj   mumnthetasigmaZtheta_mr   rp   Zv_hatZr_hatr   r   r   gelman_rubin_diagnostic>  s    &$z-gelman_rubin.<locals>.gelman_rubin_diagnosticc                sd   t j|td}|| jd  }xBt|D ]6\}}||kr<t jn | d d d || f ||< q&W |S )N)dtyper   )r   
zeros_liker)   r9  	enumeratenan)r6   r  r  r!  Znum_missing_samplesr:   t)rC  r   r   rhate  s
    2zgelman_rubin.<locals>.rhatc                s  t | tkrtdt | d tkr,tdi }td  xt D ]}| |}d krf|j	 n}x||D ]t}||jkrqp|j| }|j
sp|j dkrp|j}||f|krt tj |||f< t|j| j|||f |< qpW t| qFW t  d k	rzi }	td  xrt D ]f}t| | |}xJ|jD ]@}|j dkr@|j}||	krnd|	|< n|	|  d7  < q@W q W  fdd|	 D }	tt|	 dd	 d
d}	d}
xB|	 D ]6\}}t tj ||d f< |
d7 }
|
krP qW t  td  x^t D ]R}t| | |}x6| D ]*\\}}}t|j| j|||f |< q@W qW t  tt| d
d}|S )NznExpecting an MCMC posterior trace distribution, from a call to posterior_traces with an MCMC inference engine.r   z'Loading selected variables to memory...r   z%Collecting most frequent addresses...c                s   i | ]\}}| kr||qS r   r   )r   r   r   )r  r   r   r#    s    zBgelman_rubin.<locals>.single_trace_dist_values.<locals>.<dictcomp>c             S   s   | d S )Nr   r   )rj   r   r   r   r     s    z@gelman_rubin.<locals>.single_trace_dist_values.<locals>.<lambda>T)r   rD   )rD   )r   r   r   r   r   r   r&   r(   r)  keysr   r   r   r-   r   onesrG  r)   r   r   r   r3   r   r2   r   )r7   r  r-  r:   r;   	name_listrF   r   r-   r.  r/  r   r   )r   r  )r  r   single_trace_dist_valueso  sd    



 







(z.gelman_rubin.<locals>.single_trace_dist_valuesc             S   s   g | ]
}|j qS r   )r'   )r   r;   r   r   r   r     s    z gelman_rubin.<locals>.<listcomp>zDDistributions have unequal length, setting the length to minimum: {}r   c                s(   i | ] \}}|j  t kr||qS r   )sizer0   )r   r   r   )r  r   r   r   r#    s    z gelman_rubin.<locals>.<dictcomp>c                s&   g | ]}|krt  |k qS r   )r   rV   )r   r:   )crr   r   r     s    r   z3Computing R-hat for named variable {} ({} of {})...Fzaxes.unicode_minusr`   )ra   r$  )rk   r   r   z{} most frequent addressesTr   )r   r   r   r   re   rf   )rg   r   )r   zPlotting to file {} ...)N) rV   rW   r   r   r   r%  r&  r'  r(  r   r3   whereisnanr&   r9  r0   rr   rs   rt   ru   r   r,  r   r  r  r  r   r   r   r~   r   r   )$r   r  r   ra   r   r   r  r	  r
  r  r   r   r   r  r  r6  rI  rM  r-  Ztrace_lengthsr;   r  r-   rF   r   rj   Zfirst_non_nansZstarting_colZ	chain_idx
last_valuer:   Zvariable_rhatsr6   r   r0  r   r   )rO  rC  r   r  r  rP  r   r   gelman_rubin5  s    
'
<




&&








rT  )TN)TNN)Tr\   r_   FTN)Nr   r_   TFTN)N)TNNN)r   Nr\   r   r   NNFFFTNNN)NNNr\   r  r  NNTFTN)NNr\   r   r2  NNFTFTN)r4   r   collectionsr   numpyr   
matplotlibrr   matplotlib.pyplotpyplotrt   r   r   r?   r   r   distributionsr   r   r   r;   r   r=   r[   r   r   r   r   r1  rT  r   r   r   r   <module>   s(   
5
6
B
r
Y
	
?
e