Evolution of First Names: Unisex Names and Nicknames

In two previous installments we considered various aspects of the given name data from 1880 to the present day compiled by the Social Security Administration. In this final article I'll take a look at unisex names and nicknames.

Of the 93889 names in the database, 8914 (just less than 10%) have been used for both genders. These “unisex names” (also known as epicene or gender-neutral names) are becoming progressively more common.

Some names have always been used for both boys and girls. New names are also continuously being introduced, many of which are also immediately applied to both genders. Bennie was unisex from its first appearance in 1880. Bobby has been applied to both genders from its first recorded use in 1900, although over time it has been given to girls less often. Clare also started out as a unisex name in 1880, but over time its use for boys has declined. There have been no boys named Clare for over a decade. Cyncere has only been in use since 1999 but has been applied consistently to both genders. Delorean was first used as an unisex name in 1982. It has recently been given only to boys though. Not too surprisingly, it was first used between 1981 and 1983 when the DeLorean DMC-12 was being manufactured (some years before the release of Back to the Future in 1985!). Halley was introduced as a given name in 1910, when Halley's Comet was visible to the naked eye. Interestingly, although Halley was given to boys and girls in similar numbers in 1910, it subsequently became a girls' name. In 1985 and 1986 (years around the re-appearance of the comet), there was a resurgence of boys named Halley.

At the other end of the spectrum, some names were traditionally used exclusively for either girls or boys, but are now being applied to both. Halsey was originally a boys' name and was only given to a girl for the first time in 1981. Indiana was a name used only for girls until 1990, when it was adopted as a boys' name as well. This might be linked to the Indiana Jones movies which appeared in the 1980s. It makes one wonder why George Lucas chose this historically feminine name for his overtly masculine hero? Other examples of names which only recently became unisex are Campbell, Moe, Embry and Franc.

Are unisex names shared evenly between the sexes? The histogram below shows the distribution of unisex names in terms of their proportional use for each gender. The peak on the left represents names applied almost exclusively to boys, while the peak on the right is the equivalent for girls. The distribution is distinctly bathtub shaped: the vast majority of names are still applied predominantly to one gender or the other and therefore fall in the extreme bins on the left and right. The peak on the left includes names like Matt, Bart and Norbert, which have been given to only a few girls. The peak on the right captures predominantly girls' names like Daphne, Sybil and Scarlett, which have been assigned to only a handful of boys. Clearly these are names which are broadly considered to be either masculine or feminine.


In the middle of the plot lie names which have an even split between boys and girls. Here we have, for example, Gabriyel, Keagyn, Laetyn, Nicola, Jacyn, Kobi, Babe, Tracy, Rael, Codie, Adrean, Daine, Germany, Burnice, Mikah, Shelby and Quanta. Interestingly, these truly unisex names are generally ones that have only entered popular use in recent years.

Although in some countries unisex names are not used due to legal or social restrictions, they are fairly common in the USA. But just how common are they? In order to restrict our attention to those names which are truly unisex, we'll consider only names with a gender ratio between 10% and 90% (between the vertical dashed lines on the histogram above). To determine whether the use of these names is accelerating, we can compare the number of unisex names to the total number of names in use. The plot below shows how the number of given names climbs from 1889 in 1880 to 30579 in 2014, an escalation of more than 1600%. By contrast, the number of unisex names expands from 47 to 1598 over the same time period, which is roughly an increase of 3400%. So the proportion of names which are being used for both genders has grown from 2.5% to 5.2%: clearly unisex names are becoming more fashionable.


There is also a growing tendency for children to be given names which would traditionally be considered as nicknames. The plot below shows the incidence of selected nicknames as given names. Many of these nicknames are unisex as well. For example, Terry, Chris and Alex are used for both girls and boys across almost all states.

Nicknames are derived in a variety of ways. Some are contractions of longer names, like Sam from Samuel, while others are expansions of shorter names, like Frankie derived from Frank. Letter swapping is another route to nicknames, like Izzy from Isaac, Isaiah, Isabel or Isabella, and Joey from Joseph, Josephine or Joanna. Both Izzy and Joey are obviously unisex too! Still others are formed by truncating a name and adding i, ie or y, for example, Maddi, Charlie or Sammy. Many nicknames are homophones, pronounced the same but spelled differently, such as Charli, Charlie and Charly.


Which unisex names are going to be popular in the next few years? Dakota, Justice, Jessie and Casey have rated highly in recent years and are likely to be popular in the future too. Other possibilities are Riley, Quinn and Skyler. Of course, you don't need to follow the crowd. There is a host of other names ranging from the common to the esoteric. How about Windsor, Rhen or Tyme?

Evolution of First Names: Fashionable and Popular Names

Last week I took a high level look at the trends in children's names over the last century. Today I'll dig a little deeper and examine the ebb and flow in popularity of some specific names.

It has recently been suggested that a given name can be used to infer a range of personal characteristics including gender, age and ethnicity. This is certainly not unreasonable. Estimating age from a given name is in some cases quite reliable, since names go in and out of fashion, and their prevalence thus varies with time.

The number and variety of given names in use has expanded dramatically since the end of the nineteenth century, when the majority of names were of classical or Biblical origin. Many new names have subsequently been adopted or invented. And today celebrities and fictional characters have a significant influence on popular names.

Names like Fannie, Mabel, Clarence and Fred were in vogue at the end of the nineteenth century, but are rarely used today. By contrast, some names that are currently popular, like Abigail, Madison, Caleb and Ethan were scarcely used in earlier times. Perennial classics, for example, Katherine, Elizabeth, Clarke and Joseph, have been used consistently over the years. These would, of course, not be very good candidates for age inference!

Some names fade regularly in and out of fashion, while others are popular for only a short interval before disappearing completely. These are likely to be rather good indicators of age. The plot below shows the number of times some names were assigned over the years from 1880 to the present day. The names considered were selected to illustrate how fickle naming fashions can be. For example, Ashley and Jessica became popular in the 1980s, but their popularity was short lived and by the late 1990s they were seldom used. Similarly, Jason was briefly a fashionable boys' name in the 1970s, while Brian enjoyed popularity for around three decades, reaching a peak in the 1970s.


Which names have been the most popular over the last century? John was consistently the leading boys' name from 1880 through to the early 1920s. Robert then rose to first place, reigning for more than a decade before James took over. James was followed by Michael from the 1960s until 1999, when it was replaced by Jacob. In 2013 Noah rose to the top of the heap.


Among girls' names, Mary reigned for even longer than John, occupying the top spot from 1880 until 1946, when it was supplanted by Linda. Linda was only on top for six years before Mary reclaimed first place until the early 1960s. Lisa, Jennifer, Jessica, Ashley, Emily, Isabella and Sophia in turn were subsequently the most popular girls' names. Emma, popular at the end of the nineteenth century, faded in popularity during the twentieth century, but has staged a resurgence over the last two decades. In the last few years Emma has been battling it out at the top with Isabella and Sophia.


So much for the popular names. What about the more unusual names? Rocket has been used for about 100 boys since the turn of the new millennium. The number of boys named Jedi now exceeds 50 and there have been a few boys named Thunder every year since the 1970s. There have been more than 2000 girls named Tequila and there are also now a smattering of girls named Leeloo. Nirvana, which is a niche girls name, has slowly been gathering popularity since the 1970s. Interestingly there was a handful of boys named Excel in 1922 (clearly not the same Excel!). Rogue, which was a rare boys name back in the 1930s, is now being used in increasing numbers for both genders. These are just a few that stand out. There are a horde of other esoteric names being used.

Which names are going to be the most popular over the next few years? It's hard to tell, but for boys it will probably be Jacob, Mason, Ethan or Noah, while for girls it is likely to be one of Sophia, Emma or Isabella.

It's interesting to consider the factors which determine a name's popularity. The names of cities and states can make attractive given names. Titles have also become prominent as given names. In South Africa, for example, Doctor and Professor are not uncommon! Words implying opulence (valuable gems and metals), nouns, last names and the names of historical figures have all been used as given names at one time or other.

In our data around 3000 names correspond to those of a state, city or town, ranging from Aberdeen to Zurich. Virginia, Charlotte, Brookyln and Austin have been popular choices in all states across the USA. Seattle has been used as a given name 5 times (but only in Utah), while Detroit has been assigned 5 times (but only in Virginia).

Names of precious gems and a few metals have also been used as given names. Ruby and Amber are rather popular across all states. Tin has been used 59 times (but only in California), while 8 children have been named Copper (but only in Texas). California and Texas are the most adventurous, employing the widest variety of names in this category.

Deeper insight into the use of names of locations and valuables can be gained from the plots here and here respectively.

Returning to the first plot in the article, you might have wondered why there is a flat line in the Male column for Ashley. Similarly, why is there a flat line in the Female column for Jason? This is rather interesting. At times, according to the data, these names have also been used for the “other” gender. Those lines are not entirely flat: the peaks are just rather small relative to the peaks for the “normal” gender. For example, Ashley has been used as a boys' name too, with usage extending from the 1970s to the 1990s and peaking at a count of around 750 in 1980. The timing of the peak is roughly the same as that for Female Ashleys, but around 75 times smaller. In 1934 there were 170 boys named Betty, while in 1989 there were 252 boys named Jessica. Quite surprising! Conversely, traditionally boys' names used for girls: there were 10 girls named Jason in 2010 and 174 named Donald in 1930. The data come with some caveats regarding names mistakenly assigned to the wrong gender. So it's quite possible that these anomalies are the results of data artefacts. On the other hand, given their relative prevalence, it's also possible that they are valid.

Regardless of questions relating to the quality of the data, there are clearly some names conventionally associated with one gender but also being used for the other gender. However, certain names have been used more or less evenly for both genders. These unisex names will be the topic of the next post in this series.

Graph from Sparse Adjacency Matrix

I spent a decent chunk of my morning trying to figure out how to construct a sparse adjacency matrix for use with graph.adjacency(). I'd have thought that this would be rather straight forward, but I tripped over a few subtle issues with the Matrix package. My biggest problem (which in retrospect seems rather trivial) was that elements in my adjacency matrix were occupied by the pipe symbol.

> adjacency[1:10,1:10]
10 x 10 sparse Matrix of class 'ngCMatrix'
 [1,] . . . . . | . . . .
 [2,] . . . . . . . | . .
 [3,] . . . . . . . . . .
 [4,] . . . . . . . . . .
 [5,] . . . . | . . . . .
 [6,] . . . . . . . . . .
 [7,] . . . . . . . . . .
 [8,] . . . . . . . . . .
 [9,] . . . . . . . . . .
[10,] . | . . . . . . . .

Of course, the error message I was encountering didn't point me to this fact. No, that would have been far too simple! The solution is highlighted in the sample code below: you need to specify the symbol used for the occupied sites in the sparse matrix.

> library(Matrix)
> set.seed(1)
> edges = data.frame(i = 1:20, j = sample(1:20, 20, replace = TRUE))
> adjacency = sparseMatrix(i = as.integer(edges$i),
+                          j = as.integer(edges$j),
+                          x = 1,
+                          dims = rep(20, 2),
+                          use.last.ij = TRUE
+ )

The resulting adjacency matrix then looks like this:

> adjacency[1:10,1:10]
10 x 10 sparse Matrix of class 'dgCMatrix'
 [1,] . . . . . 1 . . . .
 [2,] . . . . . . . 1 . .
 [3,] . . . . . . . . . .
 [4,] . . . . . . . . . .
 [5,] . . . . 1 . . . . .
 [6,] . . . . . . . . . .
 [7,] . . . . . . . . . .
 [8,] . . . . . . . . . .
 [9,] . . . . . . . . . .
[10,] . 1 . . . . . . . .

And can be passed into graph.adjacency() without any further issues.

> library(igraph)
> graph = graph.adjacency(adjacency, mode = 'undirected')


Evolution of First Names: Changes over the Last Century

In light of recent developments, a bit of work that I did almost two years ago has become rather relevant.


In a chapter of Freakonomics entitled “Would a Roshanda by Any Other Name Smell as Sweet?”, Steven Levitt and Stephen Dubner consider the influence a given name can have on a child's future, from their performance at school to career opportunities and beyond. Many parents believe that the name they choose for their child will have a significant effect on their future, and there is certainly data to support this idea. However, there is also evidence to the contrary. Levitt and Dubner cite the real example of two brothers named Winner and Loser. Loser turned out to be a success, while Winner was appreciably less fortunate. It is probably reasonable to conclude that a given name is only one of many factors contributing to a child's destiny!

Levitt and Dubner further speculate that the name chosen for a child reflects more on the parents (specifically their care, intentions and status), and that it is these factors, rather than the name, which will have a greater influence on the upbringing of a child, and hence his or her future. Although there may be a correlation between names and destiny, there is probably no direct causal link.

Levitt and Dubner also considered the distinctive naming patterns among black and white Americans, presenting some intriguing results. But that's a story for another day. In this series of three articles I will look in detail at the evolution over time of given name usage in the United States. The analyses will be based on data compiled by the Social Security Administration extending from 1880 to the present day. These data are essentially complete but, in the interests of privacy, exclude those names which have fewer than 5 occurrences.

We will start by taking a high-level look at the number of given names. At the end of the nineteenth century there were only around 4000 different given names in use around the United States. By 2012 this number had escalated to more than 33 000. The plots below show how the number of given names has changed with time. The trend towards greater variety is readily apparent. However, this trend is by no means uniform. There was a dramatic increase around the outbreak of World War I, followed by a decade (roughly 1920 to 1930) during which the number of names being used actually declined. After that there has been a steady increase in the number of names, reaching a peak in 2008 when 20 430 and 14 598 different names were given to girls and boys respectively. Since then there has been a steady decline in name diversity.


If one compares the number of names (left panel) to the number of births (right panel), then something interesting emerges: the explosion of names around World War I is mirrored by a sudden increase in the number of births. However, the next peak in births, following the end of World War II, was not accompanied by a significant increase in the variety of names. Possibly these “Baby Boomers” were more or less satisfied with the range of names already in use.

Note that the number of births could be placed in a different context by normalizing to the size of the population. This would give the per capita birth rate. However, for the purpose of comparison with the number of names, the absolute number of births is a more meaningful statistic.

Interestingly, there is almost always a greater variety of girls' names. The histogram below shows the distribution of the ratio of girls' names to boys' names calculated on an annual basis. It is clear that for only a handful of years have a greater variety of names been assigned to boys than girls. On average (dashed vertical line) there are 42% more girls' names in use.


Is it reasonable to assume that these patterns apply uniformly across the entire United States? Let's have a look. If we break the number of names in use down according to state then the data look like this:


The upward trend in the variety of names seems to be driven by only a few states. California, Texas and New York make the largest contributions to the growth. Some states, like Alabama, North Dakota and Wyoming, have experienced very little growth at all. Interestingly, these states are among the most conservative states according to a survey by Gallup. That makes some sense: they are probably rather concerned about tradition and preserving their heritage. However, the converse does not appear to hold: the states with the most rapid growth in names are not high on the liberal end of the spectrum. Ideology is evidently not the only factor fueling the growth in names.

The gender ratio has also evolved dramatically over time. The choropleth below shows how the ratio of girls' names to boys' name has changed over time for each of the continental states.


Nevada is the most dynamic, with the balance swinging regularly back and forth between the genders. The number of girls' names is consistently dominant across most states for an extended period between around 1950 and 1990. After this, boys' names gain the ascendancy is some states. This is particularly evident in North and South Dakota, Idaho, Montana and Wyoming. California and Texas, in addition to having an enormous range of names, also appear to use a far greater variety of girls' names.

Each generation wants new symbols, new people, new names. They want to divorce themselves from their predecessors.Jim Morrison

It's conceivable that some states are more eager to separate themselves from the past. By using new names, freshly invented or co-opted from elsewhere, they are hoping that each new generation will be different from the last. Other states are quite happy for the pool of given names to remain more or less the same. Perhaps they were happier with the last generation?

This analysis has not taken into account the influence of nicknames and derivative names. Is it possible that the excess of girls' names is caused by the adoption of cute variations of existing names? These issues will be considered later in the series, in addition to examining the prevalence of names used across both genders.

LIBOR and Bond Yields

I've just been looking at the historical relationship between the London Interbank Offered Rate (LIBOR) and government bond yields. LIBOR data can be found at Quandl and comes in CSV format, so it's pretty simple to digest. The bond data can be sourced from the US Department of the Treasury. It comes as XML and requires a little more work.

> treasury.xml = xmlParse('data/treasury-yield.xml')
> xml.field = function(name) {
+   xpathSApply(xmlRoot(treasury.xml), paste0('//ns:entry/ns:content//d:', name),
+               function(x) {xmlValue(x)},
+               namespaces = c(ns = 'http://www.w3.org/2005/Atom',
+                              d = 'http://schemas.microsoft.com/ado/2007/08/dataservices'))
+ }
> bonds = data.frame(
+   date = strptime(xml.field('NEW_DATE'), format = '%Y-%m-%dT%H:%M:%S', tz = 'GMT'),
+   yield_1m = as.numeric(xml.field('BC_1MONTH')),
+   yield_6m = as.numeric(xml.field('BC_6MONTH')),
+   yield_1y = as.numeric(xml.field('BC_1YEAR')),
+   yield_5y = as.numeric(xml.field('BC_5YEAR')),
+   yield_10y = as.numeric(xml.field('BC_10YEAR'))
+ )

Once I had a data frame for each time series, the next step was to convert them each to xts objects. With the data in xts format it was a simple matter to enforce temporal overlap and merge the data into a single time series object. The final step in the analysis was to calculate the linear coefficient, or beta, for a least squares fit of LIBOR on bond yield. This was to be done with both a 1 month and a 1 year moving window. Both of these could be achieved quite easily using rollapply() from the zoo package.

Below is the visualisation which I quickly put together on Plotly. Again I am profoundly impressed by just how easy this service is to use and how magnificent the interactive results are.

Guy Kawasaki on Personal Branding

Kelsey Jones of Search Engine Journal interviews Guy Kawasaki of Canva. The key take-home message is that maintaining a personal brand is vital even if you are permanently employed. Specifically, it's important to keep a visible record of who you have worked for and your personal successes.

I'm living proof. I did one thing right for Apple thirty years ago. I've been coasting ever since. Just need to do one thing really right.
Guy Kawasaki

The quote above is, of course, tongue in cheek, but it bears a nugget of truth: showcase your achievements on LinkedIn and other social media because they all contribute to your personal brand.

#MonthOfJulia Day 38: Imaging


Julia has a few packages aimed at image processing. We'll start by looking at the TestImages package, which hosts a selection of sample images, then briefly visit the ImageView package before moving onto the Images package, which implements a range of functions for image manipulation.

Test Images

The TestImages package currently provides 25 sample images, which form a convenient basis for experimentation.

julia> using TestImages
julia> readdir(joinpath(homedir(), ".julia/v0.4/TestImages/images/"))
25-element Array{ByteString,1}:

We'll load the archetypal test image (the November 1972 Playboy centerfold of Lena Söderberg).

julia> lena = testimage("lena_color_256.tif");

Of course, now that we've loaded that image, we'll want to take a look at it. To do that we'll need the ImageView package.

julia> using ImageView
julia> view(lena)
(ImageCanvas,ImageSlice2d: zoom = Graphics.BoundingBox(0.0,256.0,0.0,256.0))

You can optionally specify the pixel spacing as a parameter to view(), which then ensures that the aspect ratio of the image is conserved on resizing. There are various other bobs and whistles associated with view(): you can click-and-drag within the image to zoom in on a particular region; various simple transformations (flipping and rotation) are possible; images can be annotated and multiple images can be arranged on a canvas for simultaneous viewing.

Image Representation

Outside of the test images, an arbitrary image file can be loaded using imread() from the Images package. Naturally, there are also functions for writing images, imwrite() and writemime().

julia> using Images
julia> earth = imread(joinpath(homedir(), ".julia/v0.4/TestImages/images/earth_apollo17.jpg"))
RGB Images.Image with:
  data: 3000x3002 Array{ColorTypes.RGB{FixedPointNumbers.UfixedBase{UInt8,8}},2}
    IMcs: sRGB
    spatialorder:  x y
    pixelspacing:  1 1

The default representation for the Image object tells us its dimensions, storage type and colour space. The spatial order indicates that the image data are stored using row major ordering. It's also possible to specify physical units for the pixel spacing, which is particularly important if you are analysing images where absolute scale matters (for example, medical imaging). There are convenience methods for a few image properties.

julia> colorspace(earth)
julia> height(earth)
julia> width(earth)

We can examine individual pixels within the image using the indexing operator.

julia> earth[1,1]

Each pixel is of type RGB (defined in the Colors package), which encapsulates a tuple giving the proportion of red, green and blue for that pixel. The underlying image data can also be accessed via the data() method.


The image can be split into its component colour channels using separate().

julia> earth_rgb = separate(earth)
RGB Images.Image with:
  data: 3002x3000x3 Array{FixedPointNumbers.UfixedBase{UInt8,8},3}
    IMcs: sRGB
    colorspace: RGB
    colordim: 3
    spatialorder:  y x
    pixelspacing:  1 1

Note that the result is a three-dimensional Array. The spatial order has also changed, which means that the data are now represented using column major ordering. The data are thus effectively transposed.

Simple Image Processing

Kernel-based filtering can be applied using imfilter() or imfilter_fft(), where the latter is better suited to larger kernels. There's a variety of helper functions for constructing kernels, like imaverage() and gaussian2d().

julia> lena_smooth = imfilter(lena, imaverage([3, 3]));
julia> lena_very_smooth = imfilter_fft(lena, ones(10, 10) / 100);
julia> lena_gauss_smooth = imfilter_gaussian(lena, [1, 2]);

The effects of the above smoothing operations can be seen below, with the original image on the left, followed by the 3-by-3 and 10-by-10 boxcar filtered versions and finally the Gaussian filtered image.


The imgradients() function calculates gradients across the image. You can choose from a set of methods for calculating the gradient. The morphological dilation and erosion operations are available via dilate() and erode().

julia> (lena_sobel_x, lena_sobel_y) = imgradients(lena, "sobel");
julia> lena_dilate = dilate(lena);
julia> lena_erode = erode(lena);

Below are the two components of the image gradient calculated using the Sobel operator followed by the results of dilate() and erode().



Other Packages

The ImageMagick package implements further imaging functionality. If, in the future, it provides an interface to the full functionality on the ImageMagick suite then it will be a truly phenomenal resource. Also worth looking at is the PiecewiseAffineTransforms package which implements a technique for warping portions of an image.

If you'd like to exercise your image processing and machine learning skills in Julia, take a look at the First Steps With Julia competition on kaggle.

#MonthOfJulia Day 37: Fourier Techniques


The Fourier Transform is often applied to signal processing and other analyses. It allows a signal to be transformed between the time domain and the frequency domain. The efficient Fast Fourier Transform (FFT) algorithm is implemented in Julia using the FFTW library.

1D Fourier Transform

Let's start by looking at the Fourier Transform in one dimension. We'll create test data in the time domain using a wide rectangle function.

julia> f = [abs(x) <= 1 ? 1 : 0 for x in -5:0.1:5];
julia> length(f)

This is what the data look like:
We'll transform the data into the frequency domain using fft().

julia> F = fft(f);
julia> typeof(F)
julia> length(F)
julia> F = fftshift(F);

The frequency domain data are an array of Complex type with the same length as the time domain data. Since each Complex number consists of two parts (real and imaginary) it seems that we have somehow doubled the information content of our signal. This is not true because half of the frequency domain data are redundant. The fftshift() function conveniently rearranges the data in the frequency domain so that the negative frequencies are on the left.

This is what the resulting amplitude and power spectra look like:
The analytical Fourier Transform of the rectangle function is the sinc function, which agrees well with numerical data in the plots above.

2D Fourier Transform

Let's make things a bit more interesting: we'll look at the analogous two-dimensional problem. But this time we'll go in the opposite direction, starting with a two-dimensional sinc function and taking its Fourier Transform.

Building the array of sinc data is easy using a list comprehension.

julia> f = [(r = sqrt(x^2 + y^2); sinc(r)) for x in -6:0.125:6, y in -6:0.125:6];
julia> typeof(f)
julia> size(f)

It doesn't make sense to think about a two-dimensional function in the time domain. But the Fourier Transform is quite egalitarian: it's happy to work with a temporal signal or a spatial signal (or a signal in pretty much any other domain). So let's suppose that our two-dimensional data are in the spatial domain. This is what it looks like:

Generating the Fourier Transform is again a simple matter of applying fft(). No change in syntax: very nice indeed!

julia> F = fft(f);
julia> typeof(F)
julia> F = fftshift(F);

The power spectrum demonstrates that the result is the 2D analogue of the rectangle function.

Higher Dimensions and Beyond

It's just as easy to apply the FFT to higher dimensional data, although in my experience this is rarely required.

Most of the FFTW library's functionality has been implemented in the Julia interface. For example:

  • it's possible to generate plans for optimised FFTs using plan_fft();
  • dct() yields the Discrete Cosine Transform;
  • you can exploit conjugate symmetry in real transforms using rfft(); and
  • it's possible to run over multiple threads using FFTW.set_num_threads().

Watch the video below in which Steve Johnson demonstrates many of the features of FFTs in Julia.