AbstractFFTs.jl icon indicating copy to clipboard operation
AbstractFFTs.jl copied to clipboard

Compact show for Frequencies

Open jishnub opened this issue 4 years ago • 6 comments

This PR specializes show for Frequencies. It's a workaround for https://github.com/JuliaLang/julia/issues/39963, and in general this makes the output more readable while displaying frequencies obtained from fftfreq and rfftfreq.

On master

julia> f = fftfreq(5, 0.3)
5-element Frequencies{Float64}:
  0.0
  0.06
  0.12
 -0.12
 -0.06

julia> show(f)
[0.0, 0.06, 0.12, -0.12, -0.06]

julia> f = rfftfreq(5, 0.3)
3-element Frequencies{Float64}:
 0.0
 0.06
 0.12

julia> show(f)
[0.0, 0.06, 0.12]

After this PR:

julia> f = fftfreq(5, 0.3)
5-element Frequencies{Float64}:
  0.0
  0.06
  0.12
 -0.12
 -0.06

julia> show(f)
[0:2; -2:-1]*0.06

julia> f = rfftfreq(5, 0.3)
3-element Frequencies{Float64}:
 0.0
 0.06
 0.12

julia> show(f)
[0:2;]*0.06

As a consequence:

on master

julia> g() = rfftfreq(100, 1)
g (generic function with 1 method)

julia> @code_warntype g()
Variables
  #self#::Core.Const(g)

Body::Frequencies{Float64}
1 ─ %1 = Main.rfftfreq(100, 1)::Core.Const([0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35000000000000003, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41000000000000003, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47000000000000003, 0.48, 0.49, 0.5])
└──      return %1

After this PR:

julia> @code_warntype g()
Variables
  #self#::Core.Const(g)

Body::Frequencies{Float64}
1 ─ %1 = Main.rfftfreq(100, 1)::Core.Const([0:50;]*0.01)
└──      return %1

jishnub avatar Jul 26 '21 10:07 jishnub

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (111eda5) 94.80% compared to head (41f58b5) 94.83%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #55      +/-   ##
==========================================
+ Coverage   94.80%   94.83%   +0.02%     
==========================================
  Files           5        5              
  Lines         443      445       +2     
==========================================
+ Hits          420      422       +2     
  Misses         23       23              

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Jul 26 '21 10:07 codecov[bot]

@stevengj @ararslan Could you have a look at this?

jishnub avatar Aug 18 '21 16:08 jishnub

Looks fine to me.

stevengj avatar Aug 19 '21 13:08 stevengj

I personally don't find it to be a significant improvement in readability but I also don't care much.

ararslan avatar Aug 19 '21 17:08 ararslan

To me this seems to be a quality-of-life improvement, as it makes the output of @code_warntype significantly more readable on terminals with word wrap. Without this, the constant may span several pages of terminal output making it pretty hard to scroll through and find useful information.

Even otherwise, it's easier to get the number of frequency bins from this display format.

On master:

julia> f = fftfreq(10, 3);

julia> show(f)
[0.0, 0.3, 0.6, 0.8999999999999999, 1.2, -1.5, -1.2, -0.8999999999999999, -0.6, -0.3]

This PR:

julia> show(f)
[0:4; -5:-1]*0.3

One may obtain, for example, the index of the Nyquist frequency without the need to count.

jishnub avatar Aug 20 '21 06:08 jishnub

An alternative would be to print fftfreq(5, 0.3), the constructor. That's like what zip does.

mcabbott avatar Sep 03 '21 19:09 mcabbott

Gentle bump. I'm not sure about using functions to represent the types, since this can't be uniquely determined for rfftfreq.

julia> rfftfreq(4,4) == rfftfreq(5,5)
true

Perhaps it's better to represent the exact form of the constructor, although that might be a bit cryptic if one doesn't know what the fields are. E.g.:

julia> f = rfftfreq(4, 4); show(f)
Frequencies(3, 3, 1.0)

The original suggestion in the PR is more readable, but the constructor will firstly communicate the type, and secondly, it will always create the correct object (which is what the docstring of show recommends). In either case, we probably do want to go ahead with this PR.

jishnub avatar Feb 03 '24 11:02 jishnub