#!../src/tops -s ../sys  -u ../usr

CATMSG push no catmsg
"ranint" missing
IF
    "math.v" source
THEN

define: bit_is_set (a n --- f ) # {{{1
    # returns true (-1) if the bit represented by 2^n is 1 
    over over              ( a n a n )
    1 + 2 swap ^ mod       ( a n mod[a,2^n+1] )
    swap rot swap          ( mod[a,2^n+1] a n)
    2 swap ^ mod           ( mod[a,2^n+1] mod[a,2^[n]] )
    -                      ( mod[a,2^n+1]-mod[a,2^[n]] )
    0 >
    ;
# 1}}}
define: load_save ( n --- ) # {{{1
    # Words tested:  loadop4, saveop4
    (n)             is Size
    5               is max_mat_per_file
    'j.op4'         is filename
    7               is min_Digits
    26 min_Digits - is max_Digits 

    1.0e-08 is TOLERANCE

    max_mat_per_file rand * integer 1 + into nMat

    flip IF
        # binary  matrix
        flip is Digits   # convenient:  -1 or 0!
    ELSE
        # text    matrix
        max_Digits rand * integer min_Digits + is Digits
    THEN

    0 is sparse_bitmap        # Ith bit is 1 if Ith matrix is sparse

    list:

    nMat 1 DO

        Size rand * integer 1 + into C       # columns 
        Size rand * integer 1 + into R       # rows

        Digits 0 > IF
            # text files can have matrices with different precisions
            max_Digits rand * integer min_Digits + is Digits
        THEN

        flip IF
            # real    matrix
            0 is complex_m
            ' real   ' is complex_s
        ELSE
            # complex matrix
           -1 is complex_m
            ' complex' is complex_s
        THEN

        flip IF
            # dense   matrix
            0 is sparse_m
            1 is rhoR    # density for real part
            1 is rhoI    # density for imag part
            flip IF
                #  a truly dense matrix
                0  is dense_from_sparse_m
            ELSE
                #  a dense matrix created by expanding a sparse matrix
                -1 is dense_from_sparse_m
                -1 is sparse_m
                rand is rhoR    # density for real part
                rand is rhoI    # density for imag part
                2 nMat I - ^ sparse_bitmap + is sparse_bitmap
            THEN
        ELSE
            # sparse  matrix
            0    is dense_from_sparse_m
           -1    is sparse_m
            rand is rhoR    # density for real part
            rand is rhoI    # density for imag part
            2 nMat I - ^ sparse_bitmap + is sparse_bitmap
        THEN

#       I "        %1.0f/" format . nMat "%1.0f " format . R "%3.0f x " format . C "%3.0f " format . rhoR " rho=%4.2f" format . rhoI ",%4.2f " format . Digits " D=% 3.0f " format . complex_s . nl

        sparse_m IF
            complex_m IF
                R C rhoR sprand dense
                R C rhoI sprand dense
                complex sparse
            ELSE
                R C rhoR sprand
            THEN
            dense_from_sparse_m IF
               dense
            THEN
        ELSE
            complex_m IF
                R C random
                R C random
                complex
            ELSE
                R C random
            THEN
        THEN

    LOOP

    ; is Original_matrices

    # now save them all to an op4 file
    filename
    nMat 1 DO
        Original_matrices I pry exe
    LOOP
    Digits saveop4

    xx

    # read them back into new variables and compare
    list:
    filename nMat 0 loadop4
    ; is Recovered_matrices

    nMat 1 DO
        Original_matrices             I pry exe
        Recovered_matrices nMat I - 1 + pry exe  # appear in reverse order
        dup is_sparse IF
            -1.0 spscale
            spadd
            dense
        ELSE
            -
        THEN
        abs maxfetch drop drop dup . 
        TOLERANCE > IF
            I " ERROR loadop4/saveop4 matrix %3.f " format . " file " . filename . nl
            halt
        THEN
    LOOP
    cr

    ; # 1}}}
define: n_load_save_tests ( nIter nSize  --- ) # {{{1
    # Invokes load_save nIter times for a random sized systems (up to nSize)
    into nSize
    1 DO I nSize 
        I "%5.0f.  " format .
        load_save 
        nl
        xx
    LOOP
    ; # 1}}}

time seedset

# Iter Size
  20  100 n_load_save_tests           nl
 'j.op4' deleteif
