o
    i;L                     @   s   d Z ddlZddlZddlmZmZ ddlmZm	Z	m
Z
 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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_array
csc_matrix   )FortranFormatParser	IntFormat	ExpFormathb_readhb_writec                   @      e Zd ZdS )MalformedHeaderN__name__
__module____qualname__ r   r   U/home/kim/smarthome/.venv/lib/python3.10/site-packages/scipy/io/_harwell_boeing/hb.pyr          r   c                   @   r
   )LineOverflowNr   r   r   r   r   r   "   r   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                   @   s:   e Zd ZedddZedd Z	dd	d
Zdd ZdS )HBInfoDefault title0Nc                 C   s  |j dd}|j}|j}|j}|j\}	}
|j}|du rgtt	|d }tt	|d }|j
jtjd v rEtt	t| }n&|j
jtjd v r[tt	t| }nd|j
j d}t|td	|du rt|sxtd
|j
jtjd v rd}n|j
jtjd v rd}n	td|j
 d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 array or 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 z not implemented yetzfmt argument not supported yet.z Complex values not supported yetintegerrealz 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
ValueErrorHBMatrixTyper"   fortran_format)clsmtitlekeymxtyper   Zpointerr&   valuesnrowsncols
nnon_zerosZpointer_fmtZindices_fmtZ
values_fmtmessagetpr#   pointer_nlinesindices_nlinesvalues_nlinestotal_nlinesr   r   r   	from_data-   sN   

zHBInfo.from_datac                 C   sR  |  d}t|dkstd| |dd }|dd }|  d}t| dks6td| t|dd }t|dd }t|dd	 }t|d	d }|dd  }	|	d
kred}	nt|	}	|	dksqtd|  d}t|dkstd| |dd  }
t|
dkstdt|
}|j	dvrtd| d|j
dkstd| d|jdkstd|dd dkstd| t|dd }t|dd	 }t|d	d }t|dd }|dkst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   z6Expected at least 72 characters for first line, got: 
N8   z7Expected at least 56 characters for second line, got: 
      *    r   z5Only files without right hand side supported for now.F   z4Expected at least 72 character for third line, got:
   z'mxtype expected to be 3 characters long)r   r   z:Only real or integer matrices supported for now (detected )r    z6Only unsymmetric matrices supported for now (detected r!   z)Only assembled matrices supported for nowz           zMalformed data for third line: z4Unexpected value %d for nltvl (last entry of line 3)zExpected 3 formats, got r      )readlinestriplenr0   rstrip_expect_intupperr1   from_fortran
value_type	structurestoragesplit)r3   fidliner5   r6   rA   r>   r?   r@   Z
rhs_nlinesZmxtype_sr7   r9   r:   r;   nelementalsctr   r   r   	from_file{   sz   





zHBInfo.from_filer   c                 C   s  |du rd}t |dkrtd|du rd}t |dkr(tjd| dtd	d
 || _|| _|| _|| _|| _	|| _
t }||}t|tsNtd| ||}t|ts_td| ||}t|tr||jdvrxtd| d| tj}nt|tr|jdvrtd| d| t}ntd||| _|| _|| _tj| _tj| _|| _|| _t||| _|| _	t||| _|| _
t||| _|| _|	| _ |
| _!|| _"|| _#dS )z@Do not use this directly, but the class ctrs (from_* functions).NzNo TitlerD   ztitle cannot be > 72 charactersz|No Key   zkey is > 8 characters (key is rL   rK   )
stacklevelz,Expected int format for pointer format, got z,Expected int format for indices format, got )r   complexz"Inconsistency between matrix type z and value type )r   zUnsupported format for values )$rP   r0   warningswarnr   r5   r6   rA   r>   r?   r@   r   parse
isinstancer   r   rU   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_fullr9   r:   r;   r[   r7   )selfr5   r6   rA   r>   r?   r@   r7   r9   r:   r;   Zpointer_format_strZindices_format_strZvalues_format_strZright_hand_sides_nlinesr[   parserrf   rg   rh   ri   r   r   r   __init__   st   











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.rD   r^   z%14d%14d%14d%14dz%14s%14d%14d%14d%14drF   r   z%16s%16s%20s      rC   )r5   ljustr6   appendrA   r>   r?   r@   r7   r2   r9   r:   r;   rf   rg   rh   join)rm   headerZpffmtZiffmtZvffmtr   r   r   dump  s$   

zHBInfo.dump)r   r   NN)r   r   )r   r   r   classmethodrB   r]   ro   rv   r   r   r   r   r   ,   s    M
X
Ir   c              
   C   s>   zt | W S  ty } z|d u rd}t||  |d }~ww )NzExpected an int, got %s)re   r0   )valuemsger   r   r   rR   ,  s   
rR   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}t
||d |d f|j|jfdS )NrI    )r+   sepr   )r(   )rt   readrj   rN   r)   Z
fromstringre   rk   rl   ri   r   r9   r:   )contentru   Z
ptr_stringZptrZ
ind_stringindZ
val_stringvalr   r   r   _read_hb_data5  s&   "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rK| || t||j| d   d  d S d S )Nr   rC   r   )Zpython_formatr   Zreshapewritetupler"   )	farr   r   ZpyfmtZ
pyfmt_fullfullrowZnremainr   r   r   write_arrayL  s   
,z _write_data.<locals>.write_arrayrC   r   )r$   r   rv   r%   r>   rf   r&   r?   rg   r'   r@   rh   )r4   rY   ru   r   r   r   r   _write_dataI  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dd e D Zdd e D Z	dd e D Z
edd ZdddZedd Zdd ZdS )r1   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      i | ]\}}||qS r   r   .0ijr   r   r   
<dictcomp>{      zHBMatrixType.<dictcomp>c                 C   r   r   r   r   r   r   r   r   |  r   c                 C   r   r   r   r   r   r   r   r   }  r   c              
   C   sv   t |dks
tdz| j|d  }| j|d  }| j|d  }| |||W S  ty: } ztd| |d }~ww )NrK   z:Fortran format for matrix type should be 3 characters longr   r   rM   zUnrecognized format )rP   r0   	_f2q_type_f2q_structure_f2q_storageKeyError)r3   r   rU   rV   rW   rz   r   r   r   rT     s   zHBMatrixType.from_fortranr!   c                 C   s^   || _ || _|| _|| jvrtd| || jvr!td| || jvr-td| d S )NzUnrecognized type zUnrecognized structure zUnrecognized storage )rU   rV   rW   	_q2f_typer0   _q2f_structure_q2f_storage)rm   rU   rV   rW   r   r   r   ro     s   


zHBMatrixType.__init__c                 C   s$   | j | j | j| j  | j| j  S N)r   rU   r   rV   r   rW   rm   r   r   r   r2     s
   


zHBMatrixType.fortran_formatc                 C   s   d| j  d| j d| j dS )NzHBMatrixType(z, rL   )rU   rV   rW   r   r   r   r   __repr__  s   zHBMatrixType.__repr__N)r!   )r   r   r   __doc__r   r   r   itemsr   r   r   rw   rT   ro   propertyr2   r   r   r   r   r   r1   f  s2    


r1   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 )HBFileNc                 C   s(   || _ |du rt|| _dS || _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   r]   _hb_info)rm   filehb_infor   r   r   ro     s   
zHBFile.__init__c                 C      | j jS r   )r   r5   r   r   r   r   r5        zHBFile.titlec                 C   r   r   )r   r6   r   r   r   r   r6     r   z
HBFile.keyc                 C   
   | j jjS r   )r   r7   rU   r   r   r   r   type     
zHBFile.typec                 C   r   r   )r   r7   rV   r   r   r   r   rV     r   zHBFile.structurec                 C   r   r   )r   r7   rW   r   r   r   r   rW     r   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   )rm   r4   r   r   r   write_matrix  s   zHBFile.write_matrixr   )r   r   r   ro   r   r5   r6   r   rV   rW   r   r   r   r   r   r   r     s    





r   T)spmatrixc                C   s\   dd }t | dr|| }nt| }||}W d   n1 s!w   Y  |r,t|S |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.
    spmatrix : bool, optional (default: True)
        If ``True``, return sparse ``coo_matrix``. Otherwise return ``coo_array``.

    Returns
    -------
    data : csc_array or csc_matrix
        The data read from the HB file as a sparse array.

    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_array, eye
    >>> data = csr_array(eye(3))  # create a sparse array
    >>> hb_write("data.hb", data)  # write a hb file
    >>> print(hb_read("data.hb", spmatrix=False))  # read a hb file
    <Compressed Sparse Column sparse array of dtype 'float64'
        with 3 stored elements and shape (3, 3)>
        Coords	Values
        (0, 0)	1.0
        (1, 1)	1.0
        (2, 2)	1.0
    c                 S   s   t | }| S r   )r   r   rY   Zhbr   r   r   _get_matrix  s   zhb_read.<locals>._get_matrixr}   N)hasattropenr   )path_or_open_filer   r   r'   r   r   r   r   r     s   )



c                    st   j dd du rt  fdd}t| dr|| S t| d}||W  d   S 1 s3w   Y  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 array or matrix
        the sparse array 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_array, eye
    >>> data = csr_array(eye(3))  # create a sparse array
    >>> hb_write("data.hb", data)  # write a hb file
    >>> print(hb_read("data.hb", spmatrix=False))  # read a hb file
    <Compressed Sparse Column sparse array of dtype 'float64'
        with 3 stored elements and shape (3, 3)>
        Coords	Values
        (0, 0)	1.0
        (1, 1)	1.0
        (2, 2)	1.0
    Fr   Nc                    s   t |  }|S r   )r   r   r   r   r4   r   r   _set_matrix7  s   

zhb_write.<locals>._set_matrixr   w)r$   r   rB   r   r   )r   r4   r   r   r   r   r   r   r	     s   *

$r   )r   ra   numpyr)   Zscipy.sparser   r   Z_fortran_format_parserr   r   r   __all__	Exceptionr   Warningr   r   r   rR   r   r   r1   r   r   r	   r   r   r   r   <module>   s&      
	</7