Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
1576 views


�r'Xyu�
@s�ddlZddlZddlZddlZddlZddlmZddlZ	ddl
Z
ddlmZddl
jZdZGdd�de�ZGdd�de�ZGd	d
�d
e�ZGdd�de�Zd
dddd�Zddd�Zddddddddddddd�Zddd�Zdd�Zdd�Zdd�Zd d!�Zddd"d#�Zd$d%�Zd&d'�Z d(d)�Z!d*d+�Z"d,d-�Z#d.d/�Z$dS)0�N)�linalg)�OrderedDictg333333�?c@s�eZdZdZddd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#S)$�Fillersz
    TcCsed}tj|�|_|j�|rD||_|jj|�n	d|_|j�|j�dS)N�_)	�grammar�Grammar�g�_get_filler_names�null�names�append�_construct_treelets�_construct_pairs)�self�cfg�add_null�null_filler�r�5/projects/18c77389-a5c3-49de-946a-7593b53d3fb2/gsc.py�__init__s
		
zFillers.__init__cCs{|jj}g}x=|D]5}|j|�x||D]}|j|�q7WqWtt|��}|j�||_dS)N)r�hnfRulesr�extend�list�set�sortr)r�	hnf_rules�fillers�key�itemrrrr	!s


zFillers._get_filler_namesc	Cs�|jj}g}x�|j�D]�}||}x||D]t}t|�dkr6|j|d�r6||dg}||d}x|D]}|j|�q�W|j|�q6WqW||_dS)N�r)rr�keys�len�is_bracketedrr�treelets)	rrZtreelet_fillers�lhs�rhs�sym�curr_treeletZrhs_newZsym_newrrrr
.s

%
zFillers._construct_treeletscCs�g|_x�|jD]�}|jj|d|dgdg�t|�d}xJt|�D]<}|jj|d||dgd|d|fg�qZWqWdS)Nrr�1_of_1�z%d_of_%d)�pairsr#rr!�range)r�treelet�n_daughters�iirrrrCs	$zFillers._construct_pairscCsdS)Nrr)r�fillerrrr�findOszFillers.findcCsdS)Nrr)rr/rrr�find_mothersRszFillers.find_motherscCsdS)Nrr)rr/rrr�find_daughtersUszFillers.find_daughterscCsOtjd�}g}x3|jD](}|j|�dk	r|j|�qW|S)z)Return a list of bracketed filler symbolsz
.*\[[0-9]+\]$N)�re�compiler�matchr)r�pattern�fillers_bracketedr/rrr�subset_bracketedXszFillers.subset_bracketedcs �fdd��jD�}|S)z)Return a list of bracketed filler symbolscs(g|]}|�j�kr|�qSr)r8)�.0r/)rrr�
<listcomp>cs	z.Fillers.subset_unbracketed.<locals>.<listcomp>)r)rZfillers_unbracketedr)rr�subset_unbracketedaszFillers.subset_unbracketedcCs|jj|jj�S)N)r�getRootNoder)rrrr�subset_rootgszFillers.subset_rootcCs|jj|jj�S)N)r�getTerminalNodesr)rrrr�subset_terminalsjszFillers.subset_terminalscCs||j�kS)N)r?)rr/rrr�is_terminalmszFillers.is_terminalcCs||j�kS)N)r8)rr/rrrr"pszFillers.is_bracketedcCs||j�kS)N)r;)rr/rrr�is_unbracketedsszFillers.is_unbracketedcCs||j�kS)N)r=)rr/rrr�is_rootvszFillers.is_rootcCscx\t|j�D]K\}}|dd|dddj|dd��d}t|�qWdS)Nrz ( r� r)z ) ))�	enumerater#�join�print)rr.r,�temprrr�
read_treeletsys5zFillers.read_treeletsN)�__name__�
__module__�__qualname__�__doc__rr	r
rr0r1r2r8r;r=r?r@r"rArBrHrrrrrs"
	rc@seZdZddd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*S)+�	SpanRolesr)cCse||_||_d|_|j�|j�|j�|j�|j�|j�|j	�dS)zConstruct a SpanRole object.FN)
�max_sent_len�max_num_branch�use_terminal�	_generate�_sort�_name�_graph�_check_overlapr
r)rrNrOrrrr�s			





zSpanRoles.__init__cCs�g}xDt|j�D]3}|ttjt|jd�|d��7}qW|jr�g}xE|D]=}|j|�dkrc|j|d|d|df�qcW||}||_	t
|�|_dS)Nrr)r)r+rOr�	itertools�combinationsrNrP�	get_widthr�rolesr!�	num_roles)rrY�
num_branchZroles_terminal�rolerrrrQ�s%	
&
	zSpanRoles._generatecCsug}x=|D]5}|j||j|�|j|�|df�q
Wt|ddd��}dd�|D�}|S)NrrcSs|d|d|dfS)Nrr)�r)�xrrr�<lambda>sz&SpanRoles.sort_roles.<locals>.<lambda>cSsg|]}|d�qS)rr)r9Zrole_augmentedrrrr:s	z(SpanRoles.sort_roles.<locals>.<listcomp>)rrX�get_num_branch�sorted)rZroles_tupleZroles_augmentedr\Zroles_tuple_sortedrrr�
sort_roles
s
	
zSpanRoles.sort_rolescCs|j|j�|_dS)N)rbrY)rrrrrRszSpanRoles._sortcCs=g}x'|jD]}|j|j|��qW||_dS)N)rYr�	tuple2strr)r�
role_namesr\rrrrS!szSpanRoles._namec
s�i}t|�}x7�jD],}i||<g||d<g||d<qWxU�jD]J}�j|�}�j|�r:�j|�}�j|�}�j|�}�fdd�|D�}||dj|g�||dj|g�||dj|�x2t|�D]$\}}	||	dj|g�qW�j	rV�j
|�rV�j|�}�j|�}||dj|g�||dj|g�qVW|�_dS)N�m�dcs4g|]*}�j|�dkr�j|��qS)r)rXrc)r9rf)rrrr:7s	z$SpanRoles._graph.<locals>.<listcomp>)rrrYrcr"�_find_mother�_find_daughterrrDrPr@�G)
rri�role_str�
role_tupleZmother_tupleZ
mother_strZdaughter_tupleZdaughter_strr.rfr)rrrT's0
zSpanRoles._graphcs�g}x��jD]�}�j�j|��s�j|d}t|�dkr��fdd�|D�}t|�dkr�|j|�|j|g�qWt|d�fdd��}|�_dS)Nrfrcs6g|],}�j�j|d��s|d�qS)r)r@�	str2tuple)r9rf)rrrr:Us	z,SpanRoles._check_overlap.<locals>.<listcomp>rcsK�j�j|d���j�j|d���j|d�dfS)Nr)rXrlr`)r^)rrrr_^sz*SpanRoles._check_overlap.<locals>.<lambda>)rir"rlr!rra�
quant_list)rrm�	role_nameZ	daughters�dsr)rrrUGs
zSpanRoles._check_overlapcCs�g}x�|jD]�}|j|�}|j|�rg}|j|d}t|�dkrjtjd�|j|d�|j|�|j|d}|j|d�|j|�qW||_dS)NrerzCHECK!!!rrf)	rirlr"r!�sys�exitrrr#)rZ
treelet_rolesrjrkr'ZmlistZdlistrrrr
ds

	zSpanRoles._construct_treeletscCs�g|_x�|jD]�}|jj|d|dgdg�t|�d}xJt|�D]<}|jj|d||dgd|d|fg�qZWqWdS)Nrrr(r)z%d_of_%d)r*r#rr!r+)rr,r-r.rrrr~s	$zSpanRoles._construct_pairscCsO|j|�r!|d|dfS|jrK|j|�rK|d|dfSdS)Nrr�����rr)r"rPr@)r�role_tuple_bracketedrrrrg�szSpanRoles._find_mothercs:|j��r6�fdd�tt��d�D�SdS)Ncs(g|]}�|�|df�qS)rr)r9r.)rsrrr:�s	z,SpanRoles._find_daughter.<locals>.<listcomp>r)r"r+r!)rrsr)rsrrh�szSpanRoles._find_daughtercCs*tdd�|dd�jd�D��S)NcSsg|]}t|��qSr)�int)r9�posrrrr:�s	z'SpanRoles.str2tuple.<locals>.<listcomp>r�,rr)�tuple�split)rrjrrrrl�szSpanRoles.str2tuplecCst|�jdd�S)NrC�)�str�replace)rrkrrrrc�szSpanRoles.tuple2strcCs|d|dS)Nrrrrr)rrkrrrrX�szSpanRoles.get_widthcCst|�dS)Nr)r!)rrkrrrr`�szSpanRoles.get_num_branchcCs(|j|�dko'|j|�dkS)Nr)r`rX)rrkrrrr"�szSpanRoles.is_bracketedcCs]|jr1|j|�dko0|j|�dkS|j|�dkoX|j|�dkSdS)Nrr))rPrXr`)rrkrrrr@�s
	zSpanRoles.is_terminalcs�fdd��jD�S)z'Return a list of terminal roles (tuple)cs%g|]}�j|�r|�qSr)r@)r9�r)rrrr:�s	z.SpanRoles.subset_terminals.<locals>.<listcomp>)rY)rr)rrr?�szSpanRoles.subset_terminalscs�fdd��jD�S)z'Return a list of terminal roles (tuple)cs%g|]}�j|�r|�qSr)r")r9r|)rrrr:�s	z.SpanRoles.subset_bracketed.<locals>.<listcomp>)rY)rr)rrr8�szSpanRoles.subset_bracketedcCscx\t|j�D]K\}}|dd|dddj|dd��d}t|�qWdS)Nrz ( rrCr)z ) ))rDr#rErF)rr.r,rGrrrrH�s5zSpanRoles.read_treeletsN)rIrJrKrrQrbrRrSrTrUr
rrgrhrlrcrXr`r"r@r?r8rHrrrrrM�s( 	rMc	@seZdZdZdddddddd	d
�Zddd
�Zddd�Zdd�Zdd�Zdd�Z	ddd�Z
ddd�Zdd�Zdd�Z
dd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/S)0�HarmonicGrammara�Construct an object implementing a Harmonic Grammar

    [ [['S[1]/(0,1,2)', 'A/(0,1)'], 2.],    # H(S[1]/(0,1,2), A/(0,1)) = 2
      [['S/(0,2)', 'S[1]/(0,1,2)'], 2.],
      [['A/(0,1)'], -1.],                   # H(A/(0,1)) = -1
      ...
      ...                  # For parsimony,
      [['A'], -1.],        # H(A/r) = -1 for all r in R, a set of roles
      [['(0,1,2)'], -3.]   # H(f/(0,1,2)) = -3 for all f in F, a set of fillers
      ...]
    �	span_roleT�pair�
impossiblegFr/c

Cs+||_||_g|_d|_d|_d|_d|_d|_d|_||_	t
j|�|_
t|d|�|_
|j
j|_|dkr�td|d|j�|_|jj|_|j�|j|�|j�|j�|jd|�|jd	|	�|r'|jd
|�dS)
Nr)g$@�
rr~rNrOr5�which�penalizeg$�i����)�	role_type�size�rules�filler_namesrd�
binding_namesr[�bias_constraint�unused_binding_harmony�	null_biasrrrrrrMrY�_set_binding_namesr
r�_convert_tuple_to_str�_add_rules_binary�_add_rules_unary�_add_constraints)
rrr�r�rr5r�r��add_constraintZ
unary_baserrrr�s2										



zHarmonicGrammar.__init__�unusedcs4|dkr�g�x(|jD]}�fdd�|D�qWx�|jD]G}|�krG|jd�ddkrG|jj|g|jg�qGWn�|dkr0x�|jD]�}|jd�\}}|jj|�}||jj	k	r�||jj
�kr3||jj
�kr,|jj|g|jg�q�|jj|�r�||jj
�kso||jj
�kr,|jj|g|jg�q�||j�kr�||jj
�ks�||jj
�kr,|jj|g|jg�q�||j�kr�||jj
�kr�|jj|g|jg�q�WdS)Nr�csg|]}�j|��qSr)r)r9�binding)�
bindings_usedrrr:s	z4HarmonicGrammar._add_constraints.<locals>.<listcomp>�/rrr�)r#r�rxr�rr�rYrlrr
r?r�rBr8�get_bracketed_fillers)rr�r,r��b�fr|Zr_tupler)r�rr�s8	z HarmonicGrammar._add_constraintsr�cs)��fdd��jjD��_dS)Ncs1g|]'}�jjD]}|�|�qqSr)rr)r9r|r�)r�seprrr:Es	z6HarmonicGrammar._set_binding_names.<locals>.<listcomp>)rYrr�)rr�r)rr�rr�Csz"HarmonicGrammar._set_binding_namescCsk|j�}|j�}|jjdk	r9|jj}nd}g}x|jjD]}x�|jjD]�}t|�t|�krett||��}|rId}	x�t	t|��D]l}
||
d|k}||
d|k}||
d|k}
|r|s|r|s|
r�|	d7}	q�W|	t|�krV|j
|�qe|j
|�qeWqRW||_dS)Nrr)�get_terminal_fillers�get_terminal_rolesrr
r#rYr!r�zipr+r)rr��terminal_fillersZterminal_rolesrZtreelet_bindingsZ	treelet_fZ	treelet_rZ	treelet_b�countZ
binding_indexZ
is_terminal_fZ
is_terminal_rZ	is_null_frrrr
Hs4			z#HarmonicGrammar._construct_treeletscCsyg}xc|jjD]U}xL|jjD]>}|d|dkr&|jtt|d|d���q&WqW||_dS)Nrr)rr*rYrrr�)rZ
pair_bindingsZpair_fZpair_rrrrrks,z HarmonicGrammar._construct_pairscCs�x[t|j�D]J\}}x;t|�D]-\}}|dd|d|j||<q)WqWx[t|j�D]J\}}x;t|�D]-\}}|dd|d|j||<q�WqnWdS)Nrr�r)rDr#r*)rr.r,�jjr�rrrrr�us)z%HarmonicGrammar._convert_tuple_to_strcCs�|dkr�x�|jD]s}|jj|d|dgdg�xFtt|�d�D].}|jj|d||dgdg�qWWqWnD|dkr�x5|jD]*}|jj|d|dgdg�q�WdS)zAdd binary HG rulesr,rrg@r)rN)r#r�rr+r!r*)rr5r,r.rrrrr�s$3z!HarmonicGrammar._add_rules_binarycCsxt|jj�D]�\}}||jj�krW|jj|gd|jg�q||jj�kr�|jj|gdg�q||jj�kr�|jj|gdg�q||jj	kr�|jj|g|j
g�q|jj|gdg�qWdS)zAdd unary HG rulesg�?g@Ng�g�g�g�)rDrrr8r�rr[r?r=r
r�)rr�r.r/rrrr��s#z HarmonicGrammar._add_rules_unarycCs\td�xY|jD]N}t|d�dkrtd|ddd|ddd|d�qWtd�x�|jD]�}t|d�dkrz|dd|jjkr�td|ddd	|d�qz|dd|jjkrtd
|ddd|d�qz|dd|jkrPtd|ddd|d�qzdSqzWdS)NzBinary rules:
rr)zH(z, rz) = %.1fz
Unary rules:
z
/*) = %.1fzH(*/)rFr�r!rrrYr�)r�rulerrr�
read_rules6s
6
%%%zHarmonicGrammar.read_rulescCs^|jj|jj�}t|t�s0|g}x'|D]}|jj|gdg�q7WdS)Ng�?rg�)rr<r�
isinstancerr�r)rZroot_fillersr/rrr�_add_rules_rootKs	
zHarmonicGrammar._add_rules_rootcCs|jjdk	r7|jj|kr7|j|jj�t|jj�t|�krd||j_n
tjd�|j�dS)NzgThe set of filler names constructued ffrom grammar is not same as the set of filler names you provided.)rr
rrrrprqr�)rZfillers_orderedrrr�reorder_fillers�s
zHarmonicGrammar.reorder_fillerscCsdS)Nrr)rrrr�
get_binary�szHarmonicGrammar.get_binarycCsdS)Nrr)rrrr�	get_unary�szHarmonicGrammar.get_unarycCsdS)Nrr)rrrrr�szHarmonicGrammar.sortcCs&|jj|jj�}|j�|S)N)rr>rr)rr�rrrr��s
z$HarmonicGrammar.get_terminal_fillerscCsXtjd�}g}x<|jjj�D](}|j|�dk	r(|j|�q(W|S)z)Return a list of bracketed filler symbolsz
.*\[[0-9]+\]$N)r3r4rrr r5r)rr6r7rrrrr��sz%HarmonicGrammar.get_bracketed_fillerscCsdd�|jj�D�S)NcSs(g|]}t|�jdd��qS)rCry)rzr{)r9r\rrrr:�s	z6HarmonicGrammar.get_terminal_roles.<locals>.<listcomp>)rYr?)rrrrr��sz"HarmonicGrammar.get_terminal_rolescCsdd�|jj�D�S)NcSs(g|]}t|�jdd��qS)rCry)rzr{)r9r\rrrr:�s	z7HarmonicGrammar.get_bracketed_roles.<locals>.<listcomp>)rYr8)rrrr�get_bracketed_roles�sz#HarmonicGrammar.get_bracketed_rolesN)rIrJrKrLrr�r�r
rr�r�r�r�r�r�r�r�rr�r�r�r�rrrrr}�s*	K/#


�t
r}c@s�eZdZdddddd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zddd�Zdd �Zdd!d"�Zdd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zdd1d2�Zdd3d4�Zdd5d6�Zd7d8d9�Zd:dd;d<�Zdd=d>�Zdddd?d@�Z dAdBdC�Z!dDdE�Z"ddFdG�Z#ddHdI�Z$ddJdK�Z%ddLdM�Z&ddNdO�Z'ddPdQ�Z(ddRdS�Z)ddTdU�Z*ddVdW�Z+dddXdY�Z,dddZd[�Z-dd\d]�Z.dd^d_�Z/dd`da�Z0ddbdc�Z1dddde�Z2ddfdg�Z3ddhdi�Z4ddjdk�Z5ddldm�Z6dddndo�Z7dddpdq�Z8drds�Z9dtdu�Z:dvdw�Z;dxdy�Z<dzd{d|d}�Z=d~d�Z>dd�d��Z?d{d�d��Z@d�d��ZAd�d��ZBdzd�d��ZCd�d�d�d��ZDd�d�d�d��ZEdddd�d{dd�d{dd�d��	ZFddd�d��ZGd�d��ZHd�d��ZId�d��ZJd�d��ZKd�d��ZLd�d�d��ZMddd�dddd�d��ZNd�d��ZOdS)��GscNetNcCs�|j�|jd|�|j�|jd|�|dk	rM|j|�||_||_|j�|j�|j	�t
j|j|jf�|_
t
j|j�|_|dk	r�|j|�|j�|j�|j�t
j|j�|_t
j|j�|_|j�|_|jd|j�|_t
j|j�|_t
j|j�|_|jd|j�|_|jd|j�|_t|jdtj�r�|jdt
j |j�|_!n|jd|_!|jddkr|j"�|jd|jd<n
|j#�|jd|_$|jd|j!�|_%d|_&d|_'d|_(d|_)|jd	|_*|jd
|_+|jd|_,|j-�dS)N�opts�	encodings�actC�bowl_center�
bowl_strength�beta_min_offsetrF�q_init�T_init�dt).�	_set_opts�_update_opts�_set_encodings�_update_encodings�set_seed�seed�hg�
_add_names�_generate_encodings�_compute_TPmat�np�zeros�num_bindings�WC�bC�_build_model�_set_weights�_set_biases�_set_quant_listr��	actC_prev�C2N�act�act_prev�extC�	extC_prev�ext�ext_prevr�r��numbers�Number�onesr��"_compute_recommended_bowl_strength�check_bowl_strengthr��zeta�t�speed�	ema_speed�clamped�q�Tr��reset)rr�r�r�r�rrrr�sX


		







	
				zGscNet.__init__cCs=g}x'|jD]}|j|j|��qW||_dS)N)rdr�
find_rolesrm)rrmrnrrrr�;szGscNet._set_quant_listc	Cs]i|_ddddddddd	g	|jd
<tj|jd<d|jd
<d|jd<d,tj|jd�|jd<d|jd<d|jd<d|jd<d|jd<d|jd<d|jd<d|jd<d|jd<d|jd<d |jd!<d|jd"<d#|jd$<d#|jd%<d#|jd&<d'|jd(<d)|jd*<d|jd+<dS)-z'Set option variables to default values.r��H�H0�Qr�r�r�r�r��trace_varnames�norm_ord�N�coordg����MbP?�
ema_factorr�ema_taur�g�T_min�T_decay_rater�gi@�q_maxg$@�q_rateg�?�cr�Nr�g�������?r�r�T�H0_on�H1_on�Hq_ong{�G�z�?�max_dtg����Mb@?�min_dt�q_policyrr)r�r��inf�log)rrrrr�As.	(

!















zGscNet._set_optscCs�|dk	r�x�|D]�}||jkr�|||j|<|dkrfdtj|j|�|jd<|dkr�tjd|j|�|jd<qtjd�qWdS)zUpdate option variable valuesNr�rr�zCheck [opts]rrrr)r�r�r��exprprq)rr�rrrrr�]s
!$zGscNet._update_optscCs�i|_d|jd<d|jd<d|jd<d|jd<d|jd<d|jd	<d|jd
<d|jd<d|jd<d|jd
<d|jd<dS)z)Set encoding variables to default values.g�dp_f�dp_r�dist�coord_f�coord_rN�dim_f�dim_rr�rd�F�R�
similarity)r�)rrrrr�ks	









zGscNet._set_encodingscCsA|dk	r=x.|D]&}||jkr|||j|<qWdS)zUpdate encoding variablesN)r�)rr�rrrrr�{s
zGscNet._update_encodingscs �jdkr��jddkr/tjd��jddkrOtjd��jd�_�jd�_�fdd��jD��_nUt�jt�r��jj	j
�_�jjj
�_�jj�_n
tjd�t�j��_
t�j��_t�j��_dS)	z8Add filler, role, and binding names to the GscNet objectNr�z&Please provide a list of filler names.rdz$Please provide a list of role names.cs.g|]$}�jD]}|d|�qqS)r�)r�)r9r|r�)rrrr:�s	z%GscNet._add_names.<locals>.<listcomp>z1[hg] is not an instance of HarmonicGrammar class.)r�r�rprqr�rdr�r�r}rrrYr!�num_fillersrZr�)rr)rrr��s 

"
zGscNet._add_namesc	s��jddk	r�tjtj�j��}tjtj�j��}x^�jdD]O}t�fdd�|dD��r�|d|�jj|dd��jj|dd�f<|d|�jj|dd��jj|dd�f<qWt�fdd�|dD��r�|d|�j	j|dd��j	j|dd�f<|d|�j	j|dd��j	j|dd�f<qWt
jd�qWW|�jd	<|�jd
<t�jd�jdd
�jd	d�jd��_
t�jd�jdd
�jd
d�jd��_�jddk	rY�jd�_
�jddk	r|�jd�_�j
jd�_�jjd�_�j�j�_tt�j����fdd�tt�j��D��_dS)z?Generate vector encodings of fillers, roles, and their bindingsr�Nc3s|]}|�jkVqdS)N)r�)r9r&)rrr�	<genexpr>�sz-GscNet._generate_encodings.<locals>.<genexpr>rrc3s|]}|�jkVqdS)N)rd)r9r&)rrrr��sz6Cannot find some f/r bindings in your similarity list.r�r�r�r��dp�dimr�r�r�r�r�cs-g|]#}dt|d�j���qS)�Ur)rz�zfill)r9r.)�ndigitsrrr:�s	z.GscNet._generate_encodings.<locals>.<listcomp>)r�r��diagr�r�rZ�allr��indexrdrprq�encode_symbolsr�r��shaper�r��	num_unitsr!rzrr+�
unit_names)rr�r�r�r)rrrr��s@#<?#<?

	

	

zGscNet._generate_encodingscCsnt|t�r/x*|jD]}t|d�dkr_|j|dd|dd|d�qt|d�dkr|dd|jkr�|j|dd|d�q(|dd|jkr�|j|dd|d�q(|dd|j	kr(|j
|dd|d�qtjd|�qWn
tjd�t
j|j|jj�dkrjtjd�dS)	zCSet the weight and bias values using a HarmonicGrammar object [hg].rr)rz(Check the rule in your Harmonic Grammar:zDThe given grammar as hg is not an instance of HarmonicGrammar class.Fz?The weight matrix (2D array) is not symmetric. Please check it.N)r�r}r�r!�
set_weightr��set_biasr��set_filler_biasrd�
set_role_biasrprqr��allclose�Wr�)rr�r�rrrr��s*
!zGscNet._build_modelcCs�tj|j|j�}|jd|jdkrDtj|�}ntj|�}||_||_	|j	j
j|j	�|_dS)zuCompute the matrices of change of basis from conceptual to neural and from neural to conceptual coordinates.
        rrN)
r��kronr�r�rr�inv�pinv�TP�TPinvr��dot�Gc)rrrrrrr��s		zGscNet._compute_TPmatcCs+|jjj|j�j|j�|_dS)zJCompute the weight values in the neural space (distributed representation)N)rr�rr�r)rrrrr��szGscNet._set_weightscCs|jjj|j�|_dS)zHCompute the bias values in the neural space (distributed representation)N)rr�rr�r�)rrrrr��szGscNet._set_biasescCs�tjj|j�\}}t|�}tjt|j��dkr�|jdkr�|j	|j
|j}|j	|j
|d|j}nCt|j	|j
|j�}t|j	|j
|d|j�}t|||�}n|}|S)z^Compute the recommended value of bowl strength. Note that the value depends on external input.rr)r�r�eighr��max�sum�absr�r�r�r��min)r�eigvalsZeigvecsZeig_maxZbeta1Zbeta2�valrrrr��s"%z)GscNet._compute_recommended_bowl_strengthTcCsU|j�}|jd|kr0tjd|�|rQtd|jd|f�dS)zaCompute and print the recommended beta value
        given the weights and biases in the C-space.r�z*Bowl strength should be greater than %.4f.zB(Current bowl strength: %.3f) must be greater than (minimum: %.3f)N)r�r�rprqrF)r�dispZbeta_minrrrr�s
zGscNet.check_bowl_strengthcCs�t|tj�p!t|tj�s1tjd�t|tj�rY|tj|j�}|j	d|jkr|tjd�||_
|jd|j
�|_dS)a�Update the bowl center

        Usage:

            >>> net.update_bowl_center(0.3)   # Set the bowl center to 0.3 * ec{1}
            >>>
            >>> import numpy as np
            >>> bowl_center = np.random.random(net.num_bindings)
            >>> net.update_bowl_center(bowl_center)

        : bowl_center: float or 1d NumPy array (size=number of bindings). the bowl center.
        z:You must provide a scalar or a NumPy array as bowl_center.rzvWhen you provide a NumPy array as bowl_center, it must have the same number of elements as the number of f/r bindings.r�N)
r�r��ndarrayr�r�rprqr�r�rr�r�r�)rr�rrr�update_bowl_centers$

	zGscNet.update_bowl_centercCsN|dkr-|j�|jd|jd<n
||jd<|jd|_dS)a0Replace the current bowl strength with
        the recommended bowl strength (+ offset)

        Usage:

            >>> net = gsc.GscNet(...)
            >>> net.set_weight('a/(0,1)', 'b/(1,2)', 2.0)
            >>> net.update_bowl_strength()

        : bowl_strength : float or None (=default)
        Nr�r�)r�r�r�)rr�rrr�update_bowl_strength0s

	
zGscNet.update_bowl_strengthcCsl|j|�}|j|�}|rK||j||f<|j||f<n||j||f<|j�dS)z�Set the weight of a connection between binding1 and binding2.
        When symmetric is set to True (default), the connection weight from
        binding2 to binding1 is set to the same value.N)�
find_bindingsr�r�)rZ
binding_name1Z
binding_name2�weight�	symmetric�idx1Zidx2rrrr
Es'zGscNet.set_weightcCs*|j|�}||j|<|j�dS)z+Set bias values of [binding_name] to [bias]N)r"r�r�)rZbinding_name�bias�idxrrrrRs
zGscNet.set_biascs�dd�|jD�}t|t�s.|g}xFt|�D]8\}��fdd�t|�D�}||j|<q;W|j�dS)zPSet the bias of bindings of all roles
        with particular fillers to [bias].cSs#g|]}|jd�d�qS)r�r)rx)r9�bbrrrr:]s	z*GscNet.set_filler_bias.<locals>.<listcomp>cs(g|]\}}�|kr|�qSrr)r9r.�ff)r/rrr:as	N)r�r�rrDr�r�)r�filler_namer&�filler_listr�r'r)r/rrYs	zGscNet.set_filler_biascs�dd�|jD�}t|t�s.|g}xFt|�D]8\}��fdd�t|�D�}||j|<q;W|j�dS)zPSet the bias of bindings of all fillers
        with particular roles to [bias].cSs#g|]}|jd�d�qS)r�r)rx)r9r(rrrr:js	z(GscNet.set_role_bias.<locals>.<listcomp>cs(g|]\}}�|kr|�qSrr)r9r.�rr)r\rrr:ns	N)r�r�rrDr�r�)rrnr&�	role_listr�r'r)r\rr
fs	zGscNet.set_role_biascs/t|t�s|g}�fdd�|D�S)z@Find the indices of the bindings from the list of binding names.cs"g|]}�jj|��qSr)r�r)r9r()rrrr:~s	z(GscNet.find_bindings.<locals>.<listcomp>)r�r)rr�r)rrr"ys	zGscNet.find_bindingscs~t|t�s|g}dd�|jD�}g}xCt|�D]5\}��fdd�t|�D�}||7}qAW|S)NcSs#g|]}|jd�d�qS)r�r)rx)r9r(rrrr:�s	z'GscNet.find_fillers.<locals>.<listcomp>cs(g|]\}}�|kr|�qSrr)r9r.r))r/rrr:�s	)r�rr�rD)rr*r+Z
filler_idxr�r'r)r/r�find_fillers�s	zGscNet.find_fillerscs~t|t�s|g}dd�|jD�}g}xCt|�D]5\}��fdd�t|�D�}||7}qAW|S)NcSs#g|]}|jd�d�qS)r�r)rx)r9r(rrrr:�s	z%GscNet.find_roles.<locals>.<listcomp>cs(g|]\}}�|kr|�qSrr)r9r.r,)r\rrr:�s	)r�rr�rD)rrnr-Zrole_idxr�r'r)r\rr��s	zGscNet.find_rolescCs4|dkr|j�}|j|j|jdd�S)z�Convert an activation state vector to a matrix form
        in which each row corresponds to a filler
        and each column corresponds to a role.N�orderr�)ZS2C�reshaper�rZ)rr�rrr�vec2mat�szGscNet.vec2matcCs%|dkr|j}|jj|�S)z6Change basis: from conceptual/pattern to neural space.N)r�rr)rr�rrrr��s	z
GscNet.C2NcCs%|dkr|j}|jj|�S)z6Change basis: from neural to conceptual/pattern space.N)r�rr)rr�rrr�N2C�s	z
GscNet.N2Cr�cCss|ddkrAttjt||�d|jd|j��n.ttjt||�d|jd|j��dS)zQPrint the weight matrix in a readable format
        (in the pattern coordinate).r�Cr�columnsNrr)rF�pd�	DataFrame�getattrr�r	)rr�rrr�read_weight�s		zGscNet.read_weightr�cCs|ddkr�|rVttjt||�j|jd�d|jddg��qttjt||�jd|j�ddgd|j��n�|r�ttjt||�j|jd�d|jddg��n=ttjt||�jd|j�ddgd|j��dS)z2Print the bias vector (in the pattern coordinate).rr3rr4r&Nrr)rFr5r6r7r0r�r�r	)rr�Zprint_verticalrrr�	read_bias�s				zGscNet.read_biascCsV|dkr|j}|j|j|��}ttj|d|jd|j��dS)z[Print the current state (C-SPACE) in a readable format.
        Pandas should be installed.Nrr4)r�r1r2rFr5r6r�rd)rr�r�rrr�
read_state�s
		zGscNet.read_statecs�d�|dkr�j}�j�j|���tj�dd�}�fdd�|D��dd�t��j�D��|r����fdd�t|�D�}�fd	d�|D��|r�t���S)
z�Print a grid point close to the current state. The grid point will be
        chosen by the snap-it method: a filler with the highest activation
        value in each role will be chosen.g�?N�axisrcsg|]}�j|�qSr)r�)r9r.)rrrr:�s	z*GscNet.read_grid_point.<locals>.<listcomp>cSsg|]}d|�qS)z%s/%sr)r9r(rrrr:�s	csNg|]D\}}�||f�kr�j|�jjjk	r|�qSr)r�r�rr
)r9Zrole_numZ
filler_num)r��act_minrrrr:�s		csg|]}�|�qSrr)r9r|)�winnersrrr:�s	)	r�r1r2r��argmaxr�rdrDrF)rr�r�skipZ
winner_idxrYr)r�r<rr=r�read_grid_point�s	%
zGscNet.read_grid_pointg�cAc
s/�j�jdkr1tjd�j�j��j�j|krW�j�j}dg�j}xCt�j�D]2\}}�fdd��j|�D�||<qwWg�tj|�}�j�jdkr�t	d�j�j�x�tt
j|��D]�\}}|dd	d
kr\t	d|ddd
�|ddd
kr\t	d
�t|�}�j
|��j�}||kr�|||<�j|�q|tj|�kr|�tj|�<||tj|�<qWtj|�ddd�}	�fdd�|	D��_||	�_dS)a�Get a list of the top [n] grid points with high harmony values
        and compute H_0 at every grid point. Regardless of the [n] value,
        the program will check every grid point. Note that the number of
        grid points is [num_fillers]^[num_roles] which increases explosively
        as [num_roles] increases. This method works only when the total
        number of grid points is reasonably small (currently set to 1e7).g�cAz?There are too many grid points (= %d) to check all grid points.Ncsg|]}�j|�qSr)r�)r9r.)rrrr:	s	z*GscNet.get_grid_points.<locals>.<listcomp>i'zOf %d grid points: rg��@rz[%06d]�endrygj�@csg|]}�|�qSrr)r9r.)�gpsetrrr:$s	rr)r�rZrprqrDrdr�r�r�rFrV�productr�	set_stater�rr�argmin�argsortrB�gpset_h)
r�nrmZrindr\rGr.�gpZhhr'r)rBrr�get_grid_points�s8*"


zGscNet.get_grid_pointscCstjj|�dS)zSet a random number seed.N)r��randomr�)r�numrrrr�'szGscNet.set_seedcCs2|j|�t|jd�|j|j|�S)zEvalutate total harmonyr�)�Hg�floatr�r��Qa)rr�rrrr�7szGscNet.HcCs<t|jd�|j|�t|jd�|j|�S)zEvalutate H_G (= H0 + H1)r�r�)rNr�r��H1)rr�rrrrM<sz	GscNet.HgcCsI|dkr|j}d|j|j�j|�|j|jj|�S)zEvaluate H0Ng�?)r�rrr�r�)rr�rrrr�Bs	z	GscNet.H0cCsJ|dkr|j}|jd||jjj|j�j||j�S)zEvalutate H1 (bowl harmony)Ng�?g�)r�r�r�r�rr)rr�rrrrPIs	z	GscNet.H1cCs4|jd|j|�d|jd|j|�S)z5Evaluate quantization harmony Q = c * Q0 + (1-c) * Q1r�r)r��Q0�Q1)rr�rrrr�QszGscNet.QcCs@|jd|j|�d|jd|jd|d|j�S)z5Evaluate quantization harmony Q = c * Q0 + (1-c) * Q1r�rr�rm)r�rQ�Q1arm)rr�rrrrOWsz	GscNet.QacCs@|jd|j|�d|jd|jd|d|j�S)z5Evaluate quantization harmony Q = c * Q0 + (1-c) * Q1r�rr�rm)r�rQ�Q1brm)rr�rrr�Qb\sz	GscNet.QbcCsB|dkr|j}|j|�}tj|dd|d�S)zEvaluate Q0Nr)r)r�r2r�r)rr�r�rrrrQas	z	GscNet.Q0cCsP|dkr|j}tjtj|j|j|��ddd�dd�S)zEvaluate Q1Nr)r;rr)r�r�rr1r2)rr�rrrrRis	z	GscNet.Q1cCs~|dkr|j}|dkr*|j}|j|�}d}x7|D]/}||j||�}||dd7}qFW|S)z Evaluate Q1 (sum of squared = 1)Nrrr))r�rmr2r)rr�rmr��q1�qlist�ssqrrrrSps		
z
GscNet.Q1acCs�|dkr|j}|dkr*|j}|j|�}d}x?|D]7}||j||�}||dd|d7}qFW|S)z%Evaluate Q1 (sum of squared = 0 or 1)Nrrr))r�rmr2r)rr�rmr�rVrWrXrrrrT�s		
z
GscNet.Q1bcCs2|j|�t|jd�|j|j|�S)z;Compute the harmony gradient evaluated at the current stater�)�HgGradrNr�r��QaGrad)rr�rrr�HGrad�szGscNet.HGradcCs<t|jd�|j|�t|jd�|j|�S)z+Compute the gradient of grammar harmony H_Gr�r�)rNr��H0Grad�H1Grad)rr�rrrrY�sz
GscNet.HgGradcCs3|dkr|j}|jj|�|j|jS)N)r�rrr�r�)rr�rrrr\�s	z
GscNet.H0GradcCs@|dkr|j}|j|jj|�|jj|j�S)N)r�r�rrr�)rr�rrrr]�s	z
GscNet.H1GradcCs4|jd|j|�d|jd|j|�S)Nr�r)r��Q0Grad�Q1Grad)rr�rrr�QGrad�szGscNet.QGradcCs@|jd|j|�d|jd|jd|d|j�S)Nr�rr�rm)r�r^�Q1aGradrm)rr�rrrrZ�sz
GscNet.QaGradcCs@|jd|j|�d|jd|jd|d|j�S)Nr�rr�rm)r�r^�Q1bGradrm)rr�rrr�QbGrad�sz
GscNet.QbGradcCsY|dkr|j}|j|�}d|d|dd|}tjd|j|�S)Nr)rzij,i)r�r2r��einsumr)rr�r�rrrrr^�s
	z
GscNet.Q0GradcCs�|dkr|j}|jj|j|j|jfdd�}|j|�}|j|�}tj	d|d�d}tj	d||�}d
tj	d	||�S)z1Compute the gradient of quantization harmony (Q1)Nr/r�zij->jr)rz
ij,ijk->jk�zj,jk�����)
r�rr0r�rZrr2r1r�rd)rr�ZTPinv_reshapedr��amat�term1�term2rrrr_�s		!z
GscNet.Q1Gradc
Cs�|dkr|j}|dkr*|j}|j|�}d}xh|D]`}||}|j|dd�f}|dj�d}tjd||�}	|||	7}qFWd|S)z1Compute the gradient of quantization harmony (Q1)Nrr)rzi,ij->jrerf)r�rmr2rrr�rd)
rr�rmr��q1gradrW�	curr_actC�
curr_TPinv�
curr_term1�
curr_term2rrrra�s		

zGscNet.Q1aGradcCs�|dkr|j}|dkr*|j}|j|�}d}x}|D]u}||}|j|dd�f}|j|�}||dd|d}	tjd||�}
||	|
7}qFWd|S)z1Compute the gradient of quantization harmony (Q1)Nrrr)zi,ij->jrerf)r�rmr2rrr�rd)rr�rmr�rjrWrkrlrXrmrnrrrrb�s		

zGscNet.Q1bGradcs�|dkr�jd}n_t|t�s8tjd��fdd�|D�}t|�dkr{tjd�jd�t�d�r�x\|D] }t�j|��j|<q�Wn1i�_x|D]}g�j|<q�W�j�d	S)
zCreate storage for traces.rr�z�Check [trace_list] that should be a list object. 
If you want to log a single variable (e.g., H), 
you must provide ["H"], not "H", as the value of [trace_list].cs)g|]}|�jdkr|�qS)r�)r�)r9�var)rrrr:s	z,GscNet.initialize_traces.<locals>.<listcomp>rz�Check [trace_list]. You provided variable name(s) that are not availalbe in the software.
Currently, the following variables are available:
�tracesN)	r�r�rrprqr!�hasattrrp�
update_traces)r�
trace_listZvar_not_in_varnamesrr)rr�initialize_tracess
	
!	
zGscNet.initialize_tracescCsid|jkr,|jdjt|j��d|jkrU|jdj|j��d|jkr~|jdj|j��d|jkr�|jdj|j��d|jkr�|jdj|j�d|jkr�|jdj|j�d|jkr|jdj|j	�d|jkr?|jdj|j
�d	|jkre|jd	j|j�d
S)z
Log tracesr�r�r�r�r�r�r�r�r�N)rprrr�r�r�r�r�r�r�r�r�)rrrrrr*s$zGscNet.update_tracescCs5x.|jD]#}tj|j|�|j|<q
WdS)z6Convert list objects of traces to NumPy array objects.N)rpr��array)rrrrr�finalize_traces@szGscNet.finalize_tracescCs.|jtj|jj|���j|j�S)z�Compute a projection matrix of a given matrix A. A is an n x m
        matrix of basis (column) vectors of the subspace. This function
        works only when the rank of A is equal to the nunmber of columns of A.
        )rrrr�)r�Arrr�_compute_projmatLszGscNet._compute_projmatg�?Fc	s�t|t�s|g}t|t�s0|g}t|�dkrgt|�t|�krgtjd�d|_||_tj|j	�}|r�dd�|D�}|j
|�}d||<|j|��||�<||_|r��|7��j
��fdd�tj|j	�D�}|jdd�|f}t|�d	kr^|j|�|_ntj|j|jf�|_|j|�|_|j|j�|_|j�|_dS)
z"Clamp f/r bindings to [clamp_vals]rzMThe number of bindings clamped is not equal to the number of values provided.TcSs#g|]}|jd�d�qS)r�r)rx)r9r�rrrr:gs	z GscNet.clamp.<locals>.<listcomp>gcs"g|]}|�kr|�qSrr)r9r()r'rrr:ts	Nr)r�rr!rprqr��binding_names_clampedr�r�r�r�r"�	clampvecCr�arangerrx�projmatrr��clampvec�act_clampedr�r2r�)	rr�Z
clamp_valsZ
clamp_comprzrdr%Zidx0rwr)r'r�clampTs8		
		

	

%zGscNet.clampcCs4|jdkr0|`|`|`|`d|_dS)ZUnclampTFN)r�r}rzr|ry)rrrr�unclamp~szGscNet.unclampcCs,|dkr|j}|jj|�|jS)zXGet a new activation vector after projecting an activation vector
        to a subspace.N)r�r|rr})rr�rrrr~�s	zGscNet.act_clampedcCs�t|t�s|g}t|t�s0|g}t|�dkrgt|�t|�krgtjd�|j�|j|�}||j|<|j|j�|_	dS)zSet external input.rz2binding_names and ext_vals have different lengths.N)
r�rr!rprq�clear_inputr"r�r�r�)rr�Zext_valsZ
inhib_compr'rrr�	set_input�s		


zGscNet.set_inputcCs.tj|j�|_|j|j�|_dS)zRemove external inputN)r�r�r�r�r�r�)rrrrr��szGscNet.clear_inputcCs�|jd|_|jd|_d|_|j�|j�|_tj|j	�|_
|jj|j
�|_
|j�|j�t|d�r�|`dS)z<Reset the model. q and T will be set to their initial valuesr�r�rrpN)r�r�r�r��randomize_stater2r�r�r�r�r�rrr�r�r�rqrp)rrrrr��s	


zGscNet.resetcCsD|j|�}tj|j�|_||j|<|j�|_dS)z�Set state to a particular vector at which the activation values
        of the given bindings are set to [vals] (default=1.0)
        and the activation values of the other bindings are set to 0.N)r"r�r�r�r�r�r�)rr��valsr'rrrrD�s
zGscNet.set_stateg�?g�������?cCs:tjjd|d|d|j�|_|j�|_dS)zSet initial state�loc�scaler�N)r�rK�normalr�r�r�r�)r�mu�sdrrr�set_init_state�s'zGscNet.set_init_staterrcCs7tjj|||j�|_|j|j�|_dS)zgSet the activation state to a random vector
        inside a hypercube of [minact, maxact]^num_bindingsN)r�rK�uniformr�r�r�r�)rZminactZmaxactrrrr��szGscNet.randomize_staterr�cCs�d|_|j|}d|_|r2|j|�xe|j|kr�|jd|d|�|rj|j�|dk	r5|jd|d|�|jr5Pq5W|j|_|j|j	dd�<|j
j|j	�|jdd�<|r�|j
�|r�|r�|j|jdj�j}|jd	}
tj|
d|
d|
jd�}g}xGt|jd
�D]2}|jtj||
|dd�|f��qaWtj|�j}t|jddd
dddd|jd|	d|
ddd
g�dS)z2Run simulations for a given amount of time [time].Fr�update_T�update_qN�tol�testvarr�r�r�xlabel�Time�xtick�ylabelZBindings�yticklabels�	grayscale�colorbar�	val_rangerr)�	convergedr��steprt�updaterr�check_convergence�rtr�r�rrr�rvr2rpr�r��linspacerr+r�interpru�heatmapr�)rZdurationr�r�Z	log_tracers�plotr�r�r�r�Zt_maxZ
actC_trace�timesZ	times_newZactC_trace_new�b_indrrr�run�s@
	
	

	"

$*	z
GscNet.runcCsw|j|jdd�<|j|jdd�<|j�|j�|rc|jddkrc|j�|rs|j�dS)z8Update state, speed, ema_speed (and optionally T, q, dt)Nr�r)	r�r�r�r��update_state�update_speedr�r�r�)rr�r�rrrr�s


z
GscNet.updatecCs�|j�}tj|j|��}|dkrpt|jd|jd|�|_t|jd|j�|_|j|j7_|j	|j|7_	|j
�|jr�|j�|_	|j
�|_dS)zUpdate state (with noise)rr�r�N)r[r��sqrtrrr�r�rr�r��	add_noiser�r~r2r�)rZgradZgrad_magrrrr�(s$
	zGscNet.update_statecCs=|jtjd|j|j�tjj|j�7_dS)z)Add noise to state in neural coordinates.r)N)r�r�r�r�r�rK�randnr)rrrrr�8s!zGscNet.add_noisecCsBtj|jd|j�|j|jd|jd|_dS)zUpdate temperaturer�r�N)r�r�r�r�r�)rrrrr�>szGscNet.update_TcCs�|jddk	r_tj|j|jddd�df|jddd�df�|_n7tt|j|jd|j|jd�d�|_dS)zUpdate quantization strengthr�Nrrr�r�)r�r�r�r�r�rrr�)rrrrr�Ds
FzGscNet.update_qcCs�|jddkr&|j|j}n#|jddkrI|j|j}tj|d|jd�t|j�|_	|j
dkr�|j	|_
n9|jdt|j�}||j
d||j	|_
dS)	zUpdate speed and ema_speedr�r�r3�ordr�Nr�r)r�r�r�r�r�r�normrr�r�r�)r�diffZ
ema_weightrrrr�Os&
zGscNet.update_speedcCsO|dkr$|j|kr$d|_|dkrK|j�|krKd|_dS)zOCheck if the convergence criterion (distance vs. ema_speed) has been satisfied.r�Tr�N)r�r�r�)rr�r�rrrr�ds	zGscNet.check_convergencer3c
Csq|dkr-|dkr-|j}|j}na|dkrW|dk	rW|j|�}n7|dk	r�|dkr�|j|�}n
tjd�|dkr�t|j|�d|jd|j	d|d|d|d	d
dg�n�|dkrm|j
|j|jfd
d�}dd�t
|j�D�}dd�t
|j�D�}	t|d|	d|d|d|d|�dS)z?Plot the activation state (conceptual coordinate) in a heatmap.NzEError. You must pass either act or actC but not both to the function.r3�xticklabelsr�r�r�rr�rrr�r/r�cSs g|]}dt|��qS)r�)rz)r9r.rrrr:�s	z%GscNet.plot_state.<locals>.<listcomp>cSs g|]}dt|��qS)r|)rz)r9r.rrrr:�s	)r�r�r�r2rprqr�r1rdr�r0r�r�r+)
rr�r�r�r�rr�Zact_matr�r�rrr�
plot_statess(	
!zGscNet.plot_statecCs�|jd}|dkrB|j|j|dd	�j�j}n
|j|}tj||�tjddd�tj|dd�tjd�tj�dS)
z"Plot the trace of a given variabler�r�Nrr��fontsize�Trr)	rpr2r��pltr�r�r��grid�show)r�varnamer^�yrrr�
plot_trace�s
)

zGscNet.plot_trace)PrIrJrKrr�r�r�r�r�r�r�r�r�r�r�r�r�r r!r
rrr
r"r.r�r1r�r2r8r9r:r@rJr�r�rMr�rPr�rOrUrQrRrSrTr[rYr\r]r`rZrcr^r_rarbrtrrrvrxrr�r~r�r�r�rDr�r�r�r�r�r�r�r�r�r�r�r�rrrrr��s�L.



	

.	)


	8	r�r�gcCs�|dkrtj|�}n�|dkr3|}n||krLtjd�t|tj�r�|tj||f�d|tj||�}t|||�}|S)a�Generate the vector encodings of [num_symbols] symbols assuming a given similarity structure.
    Each column vector will represent a unique symbol.

    Usage:

        >>> gsc.encode_symbols(2)
        >>> gsc.encode_symbols(3, coord='dist', dp=0.3, dim=5)

    : num_symbols : int, number of symbols to encode
    : coord       : string, 'dist' (distributed representation, default) or 'local' (local representation)
    : dp          : float (0 [default] <= dp <= 1) or 2D-numpy array of pairwise similarity (dot product)
    : dim         : int, number of dimensions to encode a symbol. must not be smaller than [num_symbols]
    :
    : [dp] and [dim] values are ignored if coord is set to 'local'.
    �localNzHThe [dim] value must be same as or greater than the [num_symbols] value.r)	r��eyerprqr�r�r�r��dot_products)�num_symbolsr�r�r��sym_matrrrr�s	
ri��cCs>|j|kj�s"tjd�tj|�dkj�rJtjd�tjjd||�j	||dd�}d}d}d	}x�t
d|d�D]�}|j|jj|�|�}	t|d
t
|	�j��}
||
|	}t
|jj|�|�j�}||kr�d}Pq�W|s:td|�|S)
a�Generate a 2D numpy array of random numbers such that the pairwise dot
    products of column vectors are close to the numbers specified in [dp_mat].

    Don Matthias wrote the original script in MATLAB for the LDNet program.
    He explains how this program works as follows:

    Given square matrix dpMatrix of dimension N-by-N, find N
    dim-dimensional unit vectors whose pairwise dot products match
    dpMatrix. Results are returned in the columns of M. itns is the
    number of iterations of search required, and may be ignored.

    Algorithm: Find a matrix M such that M'*M = dpMatrix. This is done
    via gradient descent on a cost function that is the square of the
    frobenius norm of (M'*M-dpMatrix).

    NOTE: It has trouble finding more than about 16 vectors, possibly for
    dumb numerical reasons (like stepsize and tolerance), which might be
    fixable if necessary.
    z&dot_products: dp_mat must be symmetricrz<dot_products: dp_mat must have all ones on the main diagonalr�r/r�g�������?g�����ư>Fg{�G�z�?Tz#Didn't converge after %d iterations)r�rrprqr�r�anyrKr�r0r+rrrrrF)r�r�Zdp_matZmax_iterr�Zmin_stepr�r�Ziter_num�incr��max_diffrrrr��s(

"r�FTc
Cs�|rtjjd�}ntjjd�}|dk	rotj|d|d|dd|ddd	d
d�ntj|d|dd	d
d�|dk	r�tj|dd
�|dk	r�tj|dd
�|dk	r%|rtjtjt	|��|dd�ntjtjt	|��|�|dk	rPtj
tjt	|��|�|dkr�tjdddddddddd�|	dkr�tjdddddddddd�|r�tj�|
r�tj
�dS)NZgray_r�Reds�cmap�vminr�vmaxr�
interpolation�nearest�aspect�autor�r��rotation�verticalFr;r^r��both�bottom�off�top�labelbottomr��left�right�	labelleft)r��cm�get_cmap�imshowr�r��xticksr�r{r!�yticks�tick_paramsr�r�)
�datar�r�r�r�r�r�Zrotate_xticklabelsr��ytickrr�r�rrrr�	sJ&
		
r�c
Cs�|jd}|jd}d}tj|d|df�}tj||�|dd�dd�f<||ddd�f<||dd�df<|dkr�tj�\}}ntjd|�\}}x�t|d�D]�}	x�t|d�D]�}
|	dkr|
dkrq�|	dks+|
dkr4d}nd}||	|
fdkr�tj|
|	f|dtjj	dt
||	|
f��d|�}|j|�tj|
|	f|ddd	d
�}|j|�q�tj|
|	f|ddd	d
�}|j|�tj|
|	f|ddtjj	dt
||	|
f��d|�}|j|�tj|
|	f|dddd	d
�}|j|�q�Wq�W|jd|d||d||dd|dg�|j
d
dd�|jd�dS)zECompute the outer product of two vectors and present it in a diagram.rg�������?rN�figsize�color�alpha�k�fillFg�������?g333333�?�equal�
adjustable�boxr�)rr�r��outerr��subplotsr+�Circler��grayr�
add_artistr;�
set_aspect)
Zvec1Zvec2r��nrow�ncol�radius�arr�fig�axr.r�r�Z	curr_unitrrr�plot_TPC	sZ

(	&	

&	
r�cCs|||jS)zGet a binding index.)r�)r�r|�netrrrr��	sr�cCs|||jS)zGet a unit index.)r�)�phi�rhor�rrr�u_ind�	sr�cCs)|jt|||�t|||�fS)N)rr�r�)r�r|r�r�r�rrr�w�	sr�c	Csnd}xat|j�D]P}xGt|j�D]6}|t|||||�|t|||�7}q,WqW|S)z,Check the activation value of a f/r binding.r)r+r�r�r�r�)rHr�r�r|r�r�r�rrr�get_a�	s
8r�cCs`|dkr�|dkr�tj|j�}xVt|j�D]E}x<t|j�D]+}t||||�|t|||�<qPWq:W|S|dkr�|dk	r�tj|j�}x0t|j�D]}t||||�||<q�W|S|dk	rI|dkrItj|j�}x0t|j�D]}t||||�||<q"W|St||||�SdS)N)r�r�r�r+r�rZr�r�)rHr�r�r|Zavecrrr�n2a�	s"-r�cCs�d}xut|j�D]d}x[t|j�D]J}|t||d|d|�ddt||d|d|�d7}q,WqW|S)Ngr�r|r)r)r+r�rZr�)r�rHZq0r�r|rrr�Q0E�	s
Lr�c	
Cs�tj|j�}x�t|j�D]�}x�t|j�D]�}d|t|||�<x�t|j�D]�}xzt|j�D]i}t	||||�}d|d|dd|}|t|||�t
|||||�|7<qzWqdWq8Wq"W|S)Ngr)r)r�r�rr+r�r�r�r�rZr�r�)	r�rH�q0gradr�r�r�r|Za_frZg_frrrr�Q0GradE�	s)r�cCs�d}xEt|j�D]4}|tjt||d|�d�dd7}qWtjtj|jt||��ddd�dd�S)Ngr|r)rr;r)r+rZr�rr�r1)r�rHrVr|rrr�Q1E�	s2r�c
Cstj|j�}x�t|j�D]�}x�t|j�D]�}d}x�t|j�D]�}tjt||d|�d�d}d}xFt|j	�D]5}	|t|||	|�t
|	||||�7}q�W|d||7}qTW||t|||�<q8Wq"W|S)Ngr|r)rre)r�r�rr+r�r�rZrr�r�r�r�)
r�rHrjr�r�Z	unit_gradr|Zvar1Zvar2r�rrr�Q1GradE�	s&3r�cCsl|j|�}d|d|dd|}tj||jdf�j}tj|j|dd�}|S)Nr)rr;r)r2r��tilerr�rr)r�rH�arZgmatr�rrr�Q0GradV�	s
r�c
Cs�|j|�}d}x�t|j�D]�\}}|j|�}tj|||jdf�j}tj|j	|dd�f|dd�}tj||d�d}	||	|7}q%Wd|}|S)Ngrr;rr)re)
r2rDrdr�r�r�rr�rr)
r�rHr�rjZr_indr,Zcurr_binding_indrgrirhrrr�Q1GradV�	s",
r�)%rV�numpyr�r3r�rp�scipyr�pandasr5r�collectionsr�matplotlib.pyplot�pyplotr��ver�objectrrMr}r�rr�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr�<module>sJ����5�����#/	3E