<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def conj(self, out=None):
 """Return the complex conjugate of ``self``. Parameters out : `NumpyTensor`, optional Element to which the complex conjugate is written. Must be an element of ``self.space``. Returns ------- out : `NumpyTensor` The complex conjugate element. If ``out`` was provided, the returned object is a reference to it. Examples -------- cn(3).element([ 1.-1.j, 2.-0.j, 3.+3.j]) cn(3).element([ 1.-1.j, 2.-0.j, 3.+3.j]) True In-place conjugation: cn(3).element([ 1.-1.j, 2.-0.j, 3.+3.j]) True """

        if self.space.is_real:
            if out is None:
                return self
            else:
                out[:] = self
                return out

        if not is_numeric_dtype(self.space.dtype):
            raise NotImplementedError('`conj` not defined for non-numeric '
                                      'dtype {}'.format(self.dtype))

        if out is None:
            return self.space.element(self.data.conj())
        else:
            if out not in self.space:
                raise LinearSpaceTypeError('`out` {!r} not in space {!r}'
                                           ''.format(out, self.space))
            self.data.conj(out.data)
            return out