Returns a string version of a value *val* matching the significant digits as given in *ref*.
    *val* might also be a numpy array. All remaining *args* and *kwargs* are forwarded to
    ``Decimal.quantize``. Example:

    .. code-block:: python

        match_precision(1.234, ".1") # -> "1.2"
        match_precision(1.234, "1.") # -> "1"
        match_precision(1.234, ".1", decimal.ROUND_UP) # -> "1.3"

        a = np.array([1.234, 5.678, -9.101])
        match_precision(a, ".1") # -> ["1.2", "5.7", "-9.1"]

def match_precision(val, ref, *args, **kwargs):
    """
    Returns a string version of a value *val* matching the significant digits as given in *ref*.
    *val* might also be a numpy array. All remaining *args* and *kwargs* are forwarded to
    ``Decimal.quantize``. Example:

    .. code-block:: python

        match_precision(1.234, ".1") # -> "1.2"
        match_precision(1.234, "1.") # -> "1"
        match_precision(1.234, ".1", decimal.ROUND_UP) # -> "1.3"

        a = np.array([1.234, 5.678, -9.101])
        match_precision(a, ".1") # -> ["1.2", "5.7", "-9.1"]
    """
    val = ensure_nominal(val)

    if not is_numpy(val):
        ret = _match_precision(val, ref, *args, **kwargs)

    else:
        # strategy: map into a flat list, create chararray with max itemsize, reshape
        strings = [_match_precision(v, r, *args, **kwargs) for v, r in np.nditer([val, ref])]
        ret = np.chararray(len(strings), itemsize=max(len(s) for s in strings))
        ret[:] = strings
        ret = ret.reshape(val.shape)

    return ret