Miscellaneous improvements to filter design functionality

- Perform prototype transformations directly on ZPKFilters. This avoids
  converting from ZPKFilter->TFFilter->ZPKFilter and the corresponding
  numerical error from root finding.
- Remove zeros and poles that exactly cancel when constructing
  ZPKFilters.
- Allow filter specifications to accept an optional `fs` keyword arg.
- More error checking when designing filters.
- Improve filter design documentation and add examples.
- Reorganize tests.