Ready for merge: Streamline dot & tensordot / Allow dot products of n-dimensional variables

Update 3: Think we're all set here.

Update 2:
As described here (https://groups.google.com/forum/?fromgroups=#!topic/theano-dev/VL_VTKTeHjw), the most streamlined version of this now has a Dot op supported by two functions, tensor.tensordot and tensor.dot. These two functions handle high dimensional inputs in ways that allow the dot products to be optimized and accelerated.


Update 1:
As described here (https://groups.google.com/forum/?fromgroups=#!topic/theano-dev/hSKQaZZOutw), I'm working on streamlining dot/tensordot beyond simply allowing high dimensional dot products. Essentially, all dot/tensordot operations will be expressed as 2D matrix products (unless inputs are both < 2D). This has significant performance gains, unifies gradients/r-ops, and can be run transparently on the gpu without the current tensordot optimization.



Original:
This pull request updates the dot op to allow "numpy semantics": passing variables with ndim other than 1 or 2 (including 0-dim scalars).

Note that the perform method is actually unchanged, as it always called numpy.dot -- this pr updates:
- make_node, which previously blocked variables with ndim other than 1 or 2
- grad, which previously only supported vectors and matrices
- infer_shape, which previously only supported vectors and matrices

Additionally, this restores the unit tests for dot products of scalars and tensors, and gradients thereof.

Things to consider:
1. R-ops are still unsupported for ndim > 2 because my implementation of higher dimension gradients uses tensordot, and tensordot does not support R-ops.
2. The gradient is only being tested via "verify_grad" -- are there more robust tests to implement?