Enhance piecewise to allow functions to have arbitrary number of input arguments

Made piecewise function simpler and more general. The new piecewise function allows functions of the type
f(x0, x1,.. ,xn) i.e. to have arbitrary number of input arguments that are evaluated conditionally.
However, the new piecewise function does not allow condlist to be a single bool list/array or a single int array as the previous version allowed. 
(That feature was not documented in the docstring of the function, but there were tests testing this functionality) 

A new keyword "fill_value" opens up the possibility to specify "out of bounds values" to other values than 0 eg. Np.nan.

## Examples

### Examples that work both in previous and current version
>>> x = np.linspace(-2,2,5)
>>> np.piecewise(x, [x<1], [1]) 
array([ 1.,  1.,  1.,  0.,  0.])

>>> np.piecewise((x,), [x < 0, x >= 0], [lambda x: -x, lambda x: x])
array([ 2.,  1.,  0.,  1.,  2.])

can be written as
>>> np.piecewise(x,[x < 0, x >= 0], [lambda x: -x, lambda x: x])
array([ 2.,  1.,  0.,  1.,  2.])

or
>>> np.piecewise(x, [x < 0,], [lambda x: -x, lambda x: x])
array([ 2.,  1.,  0.,  1.,  2.])

### Example that does not work anymore:
>>> np.piecewise(x, x < 0, [lambda x: -x, lambda x: x])
TypeError

### Examples demonstrating the new functionality
>>> X,Y = np.meshgrid(x,x)
>>> np.piecewise((X,Y), [X*Y<0,], [lambda x,y: -x*y, lambda x,y: x*y])
array([[ 4.,  2., -0.,  2.,  4.],
       [ 2.,  1., -0.,  1.,  2.],
       [-0., -0.,  0.,  0.,  0.],
       [ 2.,  1.,  0.,  1.,  2.],
       [ 4.,  2.,  0.,  2.,  4.]])

>>> np.piecewise((X,Y),[X*Y<-0.5, X*Y>0.5], [lambda x,y: -x*y, lambda x,y: x*y],   fill_value=np.nan)
array([[  4.,   2.,  nan,   2.,   4.],
       [  2.,   1.,  nan,   1.,   2.],
       [ nan,  nan,  nan,  nan,  nan],
       [  2.,   1.,  nan,   1.,   2.],
       [  4.,   2.,  nan,   2.,   4.]])