'Perfoms the elementary row operation `op`.
`op` may be one of
* "n->kn" (row n goes to k*n)
* "n<->m" (swap row n and row m)
* "n->n+km" (row n goes to row n + k*row m)
Parameters
op : string; the elementary row operation
row : the row to apply the row operation
k : the multiple to apply in the row operation
row1 : one row of a row swap
row2 : second row of a row swap or row "m" in the row operation
"n->n+km"'

def elementary_row_op(self, op='n->kn', row=None, k=None, row1=None, row2=None):

    (op, row, k, row1, row2) = self._normalize_op_args(op, row, k, row1, row2, 'row')
    if (op == 'n->kn'):
        return self._eval_row_op_multiply_row_by_const(row, k)
    if (op == 'n<->m'):
        return self._eval_row_op_swap(row1, row2)
    if (op == 'n->n+km'):
        return self._eval_row_op_add_multiple_to_other_row(row, k, row2)
