Square root of a :class:`Scalar` or scalar value

    This always returns a :class:`Scalar`, and uses a symbolic square root if
    possible (i.e., for non-floats)::

        >>> sqrt(2)
        sqrt(2)

        >>> sqrt(2.0)
        1.414213...

    For a :class:`ScalarExpression` argument, it returns a
    :class:`ScalarPower` instance::

        >>> braket = KetSymbol('Psi', hs=0).dag() * KetSymbol('Phi', hs=0)
        >>> nrm = sqrt(braket * braket.dag())
        >>> print(srepr(nrm, indented=True))
        ScalarPower(
            ScalarTimes(
                BraKet(
                    KetSymbol(
                        'Phi',
                        hs=LocalSpace(
                            '0')),
                    KetSymbol(
                        'Psi',
                        hs=LocalSpace(
                            '0'))),
                BraKet(
                    KetSymbol(
                        'Psi',
                        hs=LocalSpace(
                            '0')),
                    KetSymbol(
                        'Phi',
                        hs=LocalSpace(
                            '0')))),
            ScalarValue(
                Rational(1, 2)))

def sqrt(scalar):
    """Square root of a :class:`Scalar` or scalar value

    This always returns a :class:`Scalar`, and uses a symbolic square root if
    possible (i.e., for non-floats)::

        >>> sqrt(2)
        sqrt(2)

        >>> sqrt(2.0)
        1.414213...

    For a :class:`ScalarExpression` argument, it returns a
    :class:`ScalarPower` instance::

        >>> braket = KetSymbol('Psi', hs=0).dag() * KetSymbol('Phi', hs=0)
        >>> nrm = sqrt(braket * braket.dag())
        >>> print(srepr(nrm, indented=True))
        ScalarPower(
            ScalarTimes(
                BraKet(
                    KetSymbol(
                        'Phi',
                        hs=LocalSpace(
                            '0')),
                    KetSymbol(
                        'Psi',
                        hs=LocalSpace(
                            '0'))),
                BraKet(
                    KetSymbol(
                        'Psi',
                        hs=LocalSpace(
                            '0')),
                    KetSymbol(
                        'Phi',
                        hs=LocalSpace(
                            '0')))),
            ScalarValue(
                Rational(1, 2)))
    """
    if isinstance(scalar, ScalarValue):
        scalar = scalar.val
    if scalar == 1:
        return One
    elif scalar == 0:
        return Zero
    elif isinstance(scalar, (float, complex, complex128, float64)):
        return ScalarValue.create(numpy.sqrt(scalar))
    elif isinstance(scalar, (int, sympy.Basic, int64)):
        return ScalarValue.create(sympy.sqrt(scalar))
    elif isinstance(scalar, Scalar):
        return scalar**(sympy.sympify(1) / 2)
    else:
        raise TypeError("Unknown type of scalar: %r" % type(scalar))