def scalogram(M, circ=False):
<EOL>if not type(M) is np.ndarray:<EOL><INDENT>M = np.array(M)<EOL><DEDENT>if M.shape[<NUM_LIT:0>] != M.shape[<NUM_LIT:1>]:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>try:<EOL><INDENT>n = min(M.shape)<EOL><DEDENT>except AttributeError:<EOL><INDENT>n = M.size<EOL><DEDENT>N = np.zeros(M.shape)<EOL>for i in range(n):<EOL><INDENT>for j in range(n):<EOL><INDENT>if i + j < n and i >= j:<EOL><INDENT>N[i, j] = M[i, i - j:i + j + <NUM_LIT:1>].sum()<EOL><DEDENT>elif circ and i + j < n and i < j:<EOL><INDENT>N[i, j] = M[i, i - j:].sum() + M[i, :i + j + <NUM_LIT:1>].sum()<EOL><DEDENT>elif circ and i >= j and i + j >= n:<EOL><INDENT>N[i, j] = M[i, i - j:].sum() + M[i, :i + j - n + <NUM_LIT:1>].sum()<EOL><DEDENT>elif circ and i < j and i + j >= n:<EOL><INDENT>N[i, j] = (M[i, i - j:].sum() +<EOL>M[i, :].sum() +<EOL>M[i, :i + j - n + <NUM_LIT:1>].sum())<EOL><DEDENT><DEDENT><DEDENT>return N<EOL>
Computes so-called 'scalograms' used to easily
    visualize contacts at different distance scales.
    Edge cases have been painstakingly taken
    care of.