B
    ba                 @   s   d dl Zd dlmZ d dlm  mZ dd Zdd Z	dd Z
dd	 Zd
d Zdd Zdd ZdddZdd Zdd Zdd Zdd ZedkrdZedZee eeZeeZee dS )    Nc             C   s   t j| | ddS )z]
	:param As: np.array, of shape [k,n,n]
	:param X:  np.array, of shape [n,n]
	:return: A(X)
	)      )axis)npsum)AsX r	   4../../../JRCVX/jrcvx_sdp/search_directions/linalg.py
operator_A   s    r   c             C   s   t jt | d| ddS )z]
	:param As: np.array, of shape [k,n,n]
	:param v:  np.array, of shape [k]
	:return: A^T(v)
	)r   r   r   )r   )r   r   	transpose)r   vr	   r	   r
   operator_AT   s    r   c             C   s$   |dddf |  |dddf  S )z3
	:param n:
	:param idx: Of shape [k,2]
	:return:
	Nr   r   r	   )nidxr	   r	   r
   mat_index_to_vec_index_multi   s    r   c             C   s@   | |dddf  |  d |dddf  d |dddf  S )z
	Convert the index of a element in a matrix U to its index in svec(U)
	:param n:
	:param idx: Of shape [k,2], each row is a index of a lower-triangular element
	:return:
	Nr   r   r   r	   )r   r   r	   r	   r
   mat_index_to_svec_index_multi   s    r   c       	      C   s`  g }g }g }t | dd}t |}t dg|g}t d| }t j||gdd}t| |}|| || |t | g | | d  d }t j| dd}t |d |d gj	}t
| |}t ||g}t ||dddddf g}t| |}|| || |t |d gd t d  tj|||ff| | d  d | |  gd	}|S )
z
	Generate the matrix Q \in R^{(1+n) * n / 2, n*n} such that for a symmetric matrix U \in S^{n}
			svec(U) = Q vec(U)
	and
			vec(U) = Q^T svec(U)
	:return: Q, of type scipy.sparse.csr_matrix
	r   r   r   )r   r   )kNg      ?)shape)r   arangecumsumconcatenatestackr   extendonestril_indicesTr   sqrtSP
csr_matrix)	r   Z	row_indexZ	col_indexZelemsZr_indexindexZc_indexZnum_lower_triQr	   r	   r
   
generate_Q'   s0    




 


$*r#   c             C   s   t j| jdgdS )z
	Stack all columns of U
	r   )newshape)r   reshaper   )Ur	   r	   r
   vecS   s    r'   c             C   s$   t tt| }t| ||gjS )z-
	Compute the matrix U such that vec(U) = v
	)intr   r   lenr%   r   )r   r   r	   r	   r
   vec_invY   s    r*   Tc             C   s   | j \}}|sp| t| }tj|dd}t|d |d gj}t||}t|}td||< ||9 }|S t	|}|
t| S dS )zx
	For any symmetric U,
	compute the svec(U) = [U[1,1], sqrt(2)U[2,1], ..., sqrt(2)U[n,1], U[2,2], sqrt(2)U[3,2], ... ]
	r   )r   r   r   r   N)r   r   triu_indicesr   r   r   r   	ones_liker   r#   dotr'   )r&   Zmatmaulr   Z__vecr   Zsvec_idxmaskr"   r	   r	   r
   svec`   s    


r/   c             C   s0   t tdt|  }t|}t| | S )Nr   )r(   r   r   r)   r#   r*   r   r-   )r   r   r"   r	   r	   r
   svec_invs   s    r0   c             C   s,   g }x| D ]}| t| q
W t|jS )N)appendr/   r   r   r   )r   retAr	   r	   r
   
svec_multix   s    
r4   c             C   s   | j d | j d kst|j d |j d ks0t| j d |j d ksHt| j d }t| |}t|| }t|}d||| |   S )z~
	Compute the symmetric kronecker product of two square matrix
	:param A: Of shape [n,n]
	:param B: Of shape [n,n]
	:return:
	r   r   g      ?)r   AssertionErrorr   kronr#   r-   r   toarray)r3   Br   ZABZBAr"   r	   r	   r
   symkro~   s    
r9   c             C   s(   t jjdd| | gd}d||j  }|S )Nr   	   )sizeg      ?)r   randomrandintr   )r   r&   r	   r	   r
   generate_sym   s    r>   __main__r      )T)numpyr   scipy.sparsesparser   scipy.sparse.linalglinalgSPLAr   r   r   r   r#   r'   r*   r/   r0   r4   r9   r>   __name__r   r&   printr   ZU_r	   r	   r	   r
   <module>   s*   		,
