U
    »mœdßJ  ã                   @   sÆ   d Z ddlZddlZddlmZ ddlmZmZm	Z	 dddd	d
dgZ
G dd„ deƒZG dd„ deƒZdd„ ZG dd	„ d	ƒZddd„Zdd„ Zdd„ ZG dd„ dƒZG dd
„ d
ƒZdd„ Zddd„ZdS )a  
Implementation of Harwell-Boeing read/write.

At the moment not the full Harwell-Boeing format is supported. Supported
features are:

    - assembled, non-symmetric, real matrices
    - integer for pointer/indices
    - exponential format for float values, and int format

é    N)Ú
csc_matrixé   )ÚFortranFormatParserÚ	IntFormatÚ	ExpFormatÚMalformedHeaderÚhb_readÚhb_writeÚHBInfoÚHBFileÚHBMatrixTypec                   @   s   e Zd ZdS )r   N©Ú__name__Ú
__module__Ú__qualname__© r   r   úT/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/scipy/io/_harwell_boeing/hb.pyr      s   c                   @   s   e Zd ZdS )ÚLineOverflowNr   r   r   r   r   r   #   s   r   c                 C   s   | j | j d |d  S )zcReturn the number of bytes to read to get every full lines for the
    given parsed fortran format.r   )ÚrepeatÚwidth)ÚfmtÚnlinesr   r   r   Ú_nbytes_full'   s    r   c                   @   s8   e Zd Zeddd„ƒZedd„ ƒZdd	d
„Zdd„ ZdS )r
   úDefault titleÚ0Nc                 C   s¢  |j dd�}|j}|j}|j}|j\}	}
|j}|dkrÈt t 	|d ¡¡}t t 	|d ¡¡}|j
jtjd krŠt t 	t |¡¡ ¡}qÐ|j
jtjd kr¶t t 	t |¡¡ ¡}qÐtd|j
j ƒ‚ntdƒ‚|dk�r<t |¡sìtd	ƒ‚|j
jtjd k�rd
}n(|j
jtjd k�r d}ntd|j
 ƒ‚t|ddƒ}ntdƒ‚dd„ }|||jƒ}|||jƒ}|||jƒ}|| | }| ||||||||	|
||j|j|jƒS )aÙ  Create a HBInfo instance from an existing sparse matrix.

        Parameters
        ----------
        m : sparse matrix
            the HBInfo instance will derive its parameters from m
        title : str
            Title to put in the HB header
        key : str
            Key
        mxtype : HBMatrixType
            type of the input matrix
        fmt : dict
            not implemented

        Returns
        -------
        hb_info : HBInfo instance
        F©ÚcopyNr   ZAllFloatZ
AllIntegerztype %s not implemented yetzfmt argument not supported yet.z Complex values not supported yetÚintegerÚrealz"type %s for values not implementedÚunsymmetricÚ	assembledz mxtype argument not handled yet.c                 S   s$   || j  }|| j  |kr |d7 }|S )Nr   )r   )r   Úsizer   r   r   r   Ú_nlinesi   s    
z!HBInfo.from_data.<locals>._nlines)ÚtocscÚindptrÚindicesÚdataÚshapeZnnzr   Zfrom_numberÚnpÚmaxÚdtypeÚkindÚ	typecodesr   ÚabsÚNotImplementedErrorZ	isrealobjÚ
ValueErrorr   r!   Úfortran_format)ÚclsÚmÚtitleÚkeyÚmxtyper   Zpointerr%   ÚvaluesÚnrowsÚncolsÚ
nnon_zerosZpointer_fmtZindices_fmtZ
values_fmtÚtpr"   Úpointer_nlinesÚindices_nlinesÚvalues_nlinesÚtotal_nlinesr   r   r   Ú	from_data.   sZ    


ÿ       üzHBInfo.from_datac                 C   sN  |  ¡  d¡}t|ƒdks&td| ƒ‚|dd… }|dd… }|  ¡  d¡}t| ¡ ƒdkshtd| ƒ‚t|dd… ƒ}t|dd… ƒ}t|dd	… ƒ}t|d	d… ƒ}|dd…  ¡ }	|	d
krÆd}	nt|	ƒ}	|	dksÞtdƒ‚|  ¡  d¡}t|ƒdk�std| ƒ‚|dd…  ¡ }
t|
ƒdk�s,tdƒ‚t |
¡}|j	dk�rNtd| ƒ‚|j
dk�sftd| ƒ‚|jdk�sztdƒ‚|dd… dk�s˜td| ƒ‚t|dd… ƒ}t|dd	… ƒ}t|d	d… ƒ}t|dd… ƒ}|dk�sîtd| ƒ‚|  ¡  d¡}| ¡ }t|ƒdk�std| ƒ‚| |||||||||||d |d |d |	|ƒS )a6  Create a HBInfo instance from a file object containing a matrix in the
        HB format.

        Parameters
        ----------
        fid : file-like matrix
            File or file-like object containing a matrix in the HB format.

        Returns
        -------
        hb_info : HBInfo instance
        Ú
éH   z8Expected at least 72 characters for first line, got: 
%sNé8   z9Expected at least 56 characters for second line, got: 
%sé   é   é*   Ú r   z5Only files without right hand side supported for now.éF   z6Expected at least 72 character for third line, got:
%sé   z'mxtype expected to be 3 characters long)r   r   z=Only real or integer matrices supported for now (detected %s)r   z9Only unsymmetric matrices supported for now (detected %s)r    z)Only assembled matrices supported for nowz           z!Malformed data for third line: %sz4Unexpected value %d for nltvl (last entry of line 3)zExpected 3 formats, got %sr   é   )ÚreadlineÚstripÚlenr/   ÚrstripÚ_expect_intÚupperr   Úfrom_fortranÚ
value_typeÚ	structureÚstorageÚsplit)r1   ÚfidÚliner3   r4   r>   r;   r<   r=   Z
rhs_nlinesZmxtype_sr5   r7   r8   r9   ÚnelementalsÚctr   r   r   Ú	from_file{   sŒ    ÿÿÿ
ÿÿ
ÿ         üzHBInfo.from_filer   c                 C   s¤  || _ || _|dkrd}t|ƒdkr,tdƒ‚|dkr8d}t|ƒdkrTt d| t¡ || _|| _|| _	|| _
tƒ }| |¡}t|tƒs’td| ƒ‚| |¡}t|tƒs²td	| ƒ‚| |¡}t|tƒrè|jd
kràtd||f ƒ‚tj}n<t|tƒ�r|jdk�rtd||f ƒ‚t}ntd|f ƒ‚|| _|| _|| _tj| _tj| _|| _|| _t||ƒ| _|| _	t||ƒ| _|| _
t||ƒ| _|| _|	| _ |
| _!|| _"|| _#dS )z@Do not use this directly, but the class ctrs (from_* functions).NzNo TitlerA   ztitle cannot be > 72 charactersz|No Keyé   z!key is > 8 characters (key is %s)z.Expected int format for pointer format, got %sz.Expected int format for indices format, got %s)r   Úcomplexz6Inconsistency between matrix type %s and value type %s)r   z Unsupported format for values %r)$r3   r4   rL   r/   ÚwarningsÚwarnr   r>   r;   r<   r=   r   ÚparseÚ
isinstancer   r   rQ   r(   Zfloat64ÚintÚpointer_formatÚindices_formatÚvalues_formatZint32Zpointer_dtypeZindices_dtypeÚvalues_dtyper   Úpointer_nbytes_fullÚindices_nbytes_fullÚvalues_nbytes_fullr7   r8   r9   rW   r5   )Úselfr3   r4   r>   r;   r<   r=   r5   r7   r8   r9   Zpointer_format_strZindices_format_strZvalues_format_strZright_hand_sides_nlinesrW   Úparserra   rb   rc   rd   r   r   r   Ú__init__Ð   sp    

ÿ

ÿ


ÿÿzHBInfo.__init__c                 C   s¨   | j  d¡| j d¡ g}| d| j| j| j| jf ¡ | d| jj	 d¡| j
| j| jdf ¡ | jj	}| jj	}| jj	}| d| d¡| d¡| d	¡f ¡ d
 |¡S )z<Gives the header corresponding to this instance as a string.rA   rZ   z%14d%14d%14d%14dz%14s%14d%14d%14d%14drC   r   z%16s%16s%20sé   é   r@   )r3   Úljustr4   Úappendr>   r;   r<   r=   r5   r0   r7   r8   r9   ra   rb   rc   Újoin)rh   ÚheaderZpffmtZiffmtZvffmtr   r   r   Údump  s*     ÿÿ  ÿÿÿzHBInfo.dump)r   r   NN)r   r   )r   r   r   Úclassmethodr?   rY   rj   rq   r   r   r   r   r
   -   s   L
X   ü
Hc              
   C   sL   z
t | ƒW S  tk
rF } z|d kr(d}t||  ƒ|‚W 5 d }~X Y nX d S )NzExpected an int, got %s)r`   r/   )ÚvalueÚmsgÚer   r   r   rN   +  s    
rN   c           	   
   C   sÐ   d  |  |j¡|  ¡ g¡}tj|tdd�}d  |  |j¡|  ¡ g¡}tj|tdd�}d  |  |j¡|  ¡ g¡}tj||j	dd�}z$t
||d |d f|j|jfd�W S  tk
rÊ } z|‚W 5 d }~X Y nX d S )NrF   ú )r*   Úsepr   )r'   )ro   Úreadre   rJ   r(   Ú
fromstringr`   rf   rg   rd   r   r7   r8   r/   )	Úcontentrp   Z
ptr_stringZptrZ
ind_stringÚindZ
val_stringÚvalru   r   r   r   Ú_read_hb_data4  s6    ÿ ÿÿ ÿÿ ÿ
ÿr}   c                 C   st   | j dd�} dd„ }| | ¡ ¡ | d¡ ||| jd |j|jƒ ||| jd |j|jƒ ||| j	|j
|jƒ d S )NFr   c           	      S   s–   |j }||j }|d |d |j … }| |d |jf¡D ]}|  |t|ƒ d ¡ q:|j|j }|dkr’|  || t||j| d … ƒ d ¡ d S )Nr   r@   r   )Zpython_formatr   ZreshapeÚwriteÚtupler!   )	ÚfÚarr   r   ZpyfmtZ
pyfmt_fullÚfullÚrowZnremainr   r   r   Úwrite_arrayO  s    
z _write_data.<locals>.write_arrayr@   r   )r#   r~   rq   r$   r;   ra   r%   r<   rb   r&   r=   rc   )r2   rU   rp   r„   r   r   r   Ú_write_dataL  s    
ÿÿÿr…   c                   @   s¤   e Zd ZdZdddddœZddd	d
ddœZdddœZedd„ e ¡ D ƒƒZ	edd„ e ¡ D ƒƒZ
edd„ e ¡ D ƒƒZedd„ ƒZddd„Zedd„ ƒZdd„ ZdS )r   zClass to hold the matrix type.ÚRÚCÚPÚI)r   r[   Úpatternr   ÚSÚUÚHÚZ)Z	symmetricr   Z	hermitianZskewsymmetricZrectangularÚAÚE)r    Z	elementalc                 C   s   g | ]\}}||f‘qS r   r   ©Ú.0ÚiÚjr   r   r   Ú
<listcomp>~  s     zHBMatrixType.<listcomp>c                 C   s   g | ]\}}||f‘qS r   r   r‘   r   r   r   r•     s     c                 C   s   g | ]\}}||f‘qS r   r   r‘   r   r   r   r•   €  s     c              
   C   s‚   t |ƒdkstdƒ‚z8| j|d  }| j|d  }| j|d  }| |||ƒW S  tk
r| } ztd| ƒ|‚W 5 d }~X Y nX d S )NrH   z:Fortran format for matrix type should be 3 characters longr   r   rI   zUnrecognized format %s)rL   r/   Ú	_f2q_typeÚ_f2q_structureÚ_f2q_storageÚKeyError)r1   r   rQ   rR   rS   ru   r   r   r   rP   ‚  s    zHBMatrixType.from_fortranr    c                 C   sX   || _ || _|| _|| jkr(td| ƒ‚|| jkr>td| ƒ‚|| jkrTtd| ƒ‚d S )NzUnrecognized type %szUnrecognized structure %szUnrecognized storage %s)rQ   rR   rS   Ú	_q2f_typer/   Ú_q2f_structureÚ_q2f_storage)rh   rQ   rR   rS   r   r   r   rj   �  s    


zHBMatrixType.__init__c                 C   s$   | j | j | j| j  | j| j  S ©N)rš   rQ   r›   rR   rœ   rS   ©rh   r   r   r   r0   ›  s
    

ÿ
þzHBMatrixType.fortran_formatc                 C   s   d| j | j| jf S )NzHBMatrixType(%s, %s, %s))rQ   rR   rS   rž   r   r   r   Ú__repr__¡  s    ÿzHBMatrixType.__repr__N)r    )r   r   r   Ú__doc__rš   r›   rœ   ÚdictÚitemsr–   r—   r˜   rr   rP   rj   Úpropertyr0   rŸ   r   r   r   r   r   i  s0   üûþ


c                   @   sb   e Zd Zddd„Zedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZedd„ ƒZ	dd„ Z
dd„ ZdS )r   Nc                 C   s&   || _ |dkrt |¡| _n|| _dS )a  Create a HBFile instance.

        Parameters
        ----------
        file : file-object
            StringIO work as well
        hb_info : HBInfo, optional
            Should be given as an argument for writing, in which case the file
            should be writable.
        N)Ú_fidr
   rY   Ú_hb_info)rh   ÚfileÚhb_infor   r   r   rj   §  s    zHBFile.__init__c                 C   s   | j jS r�   )r¥   r3   rž   r   r   r   r3   º  s    zHBFile.titlec                 C   s   | j jS r�   )r¥   r4   rž   r   r   r   r4   ¾  s    z
HBFile.keyc                 C   s
   | j jjS r�   )r¥   r5   rQ   rž   r   r   r   ÚtypeÂ  s    zHBFile.typec                 C   s
   | j jjS r�   )r¥   r5   rR   rž   r   r   r   rR   Æ  s    zHBFile.structurec                 C   s
   | j jjS r�   )r¥   r5   rS   rž   r   r   r   rS   Ê  s    zHBFile.storagec                 C   s   t | j| jƒS r�   )r}   r¤   r¥   rž   r   r   r   Úread_matrixÎ  s    zHBFile.read_matrixc                 C   s   t || j| jƒS r�   )r…   r¤   r¥   )rh   r2   r   r   r   Úwrite_matrixÑ  s    zHBFile.write_matrix)N)r   r   r   rj   r£   r3   r4   r¨   rR   rS   r©   rª   r   r   r   r   r   ¦  s   





c              
   C   sB   dd„ }t | dƒr|| ƒS t| ƒ�}||ƒW  5 Q R £ S Q R X dS )aà  Read HB-format file.

    Parameters
    ----------
    path_or_open_file : path-like or file-like
        If a file-like object, it is used as-is. Otherwise, it is opened
        before reading.

    Returns
    -------
    data : scipy.sparse.csc_matrix instance
        The data read from the HB file as a sparse matrix.

    Notes
    -----
    At the moment not the full Harwell-Boeing format is supported. Supported
    features are:

        - assembled, non-symmetric, real matrices
        - integer for pointer/indices
        - exponential format for float values, and int format

    Examples
    --------
    We can read and write a harwell-boeing format file:

    >>> from scipy.io import hb_read, hb_write
    >>> from scipy.sparse import csr_matrix, eye
    >>> data = csr_matrix(eye(3))  # create a sparse matrix
    >>> hb_write("data.hb", data)  # write a hb file
    >>> print(hb_read("data.hb"))  # read a hb file
      (0, 0)	1.0
      (1, 1)	1.0
      (2, 2)	1.0

    c                 S   s   t | ƒ}| ¡ S r�   )r   r©   ©rU   Zhbr   r   r   Ú_get_matrixú  s    zhb_read.<locals>._get_matrixrx   N)ÚhasattrÚopen)Úpath_or_open_filer¬   r€   r   r   r   r   Õ  s
    %

c              
      sh   ˆj dd�‰ˆ dkrt ˆ¡‰ ‡ ‡fdd„}t| dƒr>|| ƒS t| dƒ�}||ƒW  5 Q R £ S Q R X dS )aú  Write HB-format file.

    Parameters
    ----------
    path_or_open_file : path-like or file-like
        If a file-like object, it is used as-is. Otherwise, it is opened
        before writing.
    m : sparse-matrix
        the sparse matrix to write
    hb_info : HBInfo
        contains the meta-data for write

    Returns
    -------
    None

    Notes
    -----
    At the moment not the full Harwell-Boeing format is supported. Supported
    features are:

        - assembled, non-symmetric, real matrices
        - integer for pointer/indices
        - exponential format for float values, and int format

    Examples
    --------
    We can read and write a harwell-boeing format file:

    >>> from scipy.io import hb_read, hb_write
    >>> from scipy.sparse import csr_matrix, eye
    >>> data = csr_matrix(eye(3))  # create a sparse matrix
    >>> hb_write("data.hb", data)  # write a hb file
    >>> print(hb_read("data.hb"))  # read a hb file
      (0, 0)	1.0
      (1, 1)	1.0
      (2, 2)	1.0

    Fr   Nc                    s   t | ˆ ƒ}| ˆ¡S r�   )r   rª   r«   ©r§   r2   r   r   Ú_set_matrix2  s    
zhb_write.<locals>._set_matrixr~   Úw)r#   r
   r?   r­   r®   )r¯   r2   r§   r±   r€   r   r°   r   r	     s    (

)N)N)r    r\   Únumpyr(   Zscipy.sparser   Z_fortran_format_parserr   r   r   Ú__all__Ú	Exceptionr   ÚWarningr   r   r
   rN   r}   r…   r   r   r   r	   r   r   r   r   Ú<module>   s(   
ÿ   
	=/0