#563 - Make the generation of correlated noise more efficient using Hermitian symmetry

Hi all,

This pull request was to make the generation of noise by the `BaseCorrelatedNoise` and derived classes more efficient, using the fact that we only desire real valued noise fields in the output.  It took me longer than I hoped to get right! (There is a script, part of this PR, in `devel/external/test_cf/` that I used as a sandbox to get this right.)

The main change then is this improvement, which happens almost exclusively within the `_generate_noise_from_rootps()` function in `galsim/correlatednoise.py`.  Since the cached variable `rootps` is now only ~half the size, this improvement also helps memory use and setup costs too.

Another, more minor change is that I no longer multiply the `rootps` values by the product of the original array shape when storing them internally within the `BaseCorrelatedNoise`.  This is necessary to do somewhere because of the asymmetry in the the `numpy.fft` convention for the DFT, and the fact that the power spectrum (PS) has the units of the square of a DFT of a noise field.  I opted to move this accounting into the `_generate_noise_from_rootps` function, simplifying `_get_update_rootps()` and `_get_update_rootps_whitening()` slightly, while on the downsise adding an additional instruction (do divide by an array dimension product) to the `CorrelatedNoise.__init__()` method.  It was a marginal call, but from working with the code this way of doing things seemed more natural, and less hidden.

I don't have a great deal to add to the discussion on #563 .  The current state of the noise realization generation code is described in the following comment: https://github.com/GalSim-developers/GalSim/issues/563#issuecomment-48053798 .
> (ps_array = (ft_array * ft_array.conj()).real) I'm just thinking that for someone reading the code rather than the diff, which will be the case for future developers working on the code, this comment is a bit vague / unclear.

I was kind of working on the assumption that in code there are clearly multiple ways of calculating |z|^2 for complex z, and that this choice is the only thing I can conceivably be referring to here.  In fact I tried a few other options, other than the example cited.  I think that referring to the same discussion in optics.py is probably good, will do and ping.