Digital Art VI: End of Week 14

The last three weeks have been very intense!  The main focus has been on laboratory work, both with Processing and Final Projects.

Week 12 began with another round of Presentations on papers from past Bridges conferences.  This proved to be successful again — with topics ranging from geometrical furniture to zippergons to maps of Thomas More’s Utopia.  We all learned something new!

The time not spent on Presentations that week was devoted to working on projects.  Students were finding their stride, and their ideas were really beginning to take shape.

Two students were interested in image processing, so Nick has been working with them.  The initial problem was that doing anything in Sage involving image processing was just too slow — you’re code is essentially sent to a remote server, executed, and the results sent back.  Since we’re using the free version, this means performance is unpredictable and far too slow for computation-heavy tasks.

So Nick helped with installing Python, finding image processing packages, etc.  This process always takes a lot longer than you imagine, but eventually all issues were resolved.

While Nick was working on image processing, I was helping others.  One student was really interested in using L-systems — one of my favorite geometrical topics recently!   But all my work with Thomas involved code written in Postscript and Mathematica.  Which meant I had to rewrite it in Python.

This proved to be quite a bit trickier than I thought.  The student was looking at The Algorithmic Beauty of Plants, and was interested in modeling increasingly complex L-systems.  First, the simplest type, like that used to generate the Koch curve.  Next came bracketed L-systems, and then bracketed L-systems with multiple rules.  I did finally get all these to work; I intend to clean up the code and share it in a future post.

Week 13 was devoted entirely to Processing and project work.  I started the week with introducing a few new ideas.  What really inspired the class were the mouseX and the mouseY variables.  When your mouse is in screen space, the mouseX and mouseY variables contain the location of your mouse.  So you can put an object where the mouse is, or have the x-coordinate of the mouse in some way determine the color or the size of the object.  The possibilities are virtually endless.

Here’s a sample movie made with this technique.

Since the code is just a few lines long, it won’t take long to explain.  Here is the complete program:


The drawPoint function will draw a point centered at the position of the mouse.  But in addition to those coordinates, the function takes an addition argument:  float(mouseX)/500.  This argument is 0 at the left edge of the screen, and 1 at the right edge.  (Recall the need for “float,” since otherwise Python will perform integer division and give 0 for any number less than 500.)

So the stroke command uses the parameter p to determine how much red is in the color specification.  When p is 0, there is no red, so the dot is black.  And when p is 1, the dot is red.  I used “p**0.4” as an illustration that interpolation need not be linear — the exponent of p determines how quickly or slowly the dot gets brighter as you move the mouse to the right.  Of course the dot also gets larger as you move your mouse to the right, as is clear by the strokeWeight function call.

I showed this example as I introduced the movie project.  Their assignment was to make a movie — anything they wanted to try.  The complete prompt is given on Day 34 of the course website, but I’ll give the gist of it here.  The main goal was to have students use linear interpolation in at least four different ways in their movie.  Of course they could use nonlinear interpolation if they wanted to, but it wasn’t required.

There was no length requirement — it’s easy to make a movie longer by adding more frames.  Just be creative!  Interpolation is a very useful tool in making movies and animations, and has a mathematical basis as well.  So I wanted that to be the focus of the project.  I also had them write a brief narrative about their use of interpolation.

This is Andrew’s movie.  You can clearly see the use of interpolation here in different ways.  It was also nice to see the use of trigonometry to calculate the centers of the dots.


Ella was interested in L-systems, and so Nick spent some time working with her on Python code during his weekly office hours.  Here is what she created.


Lucas wanted to use some interaction with the mouse, and he also had the idea of the sun setting as you moved the mouse down the screen.  Watch how the fractal clouds move with the location of the mouse as well.


So you can see how varied the use of interpolation was!  The students really enjoyed having control over the possible special effects, and created a wide range of interesting features in their movies.

That takes us to Week 14.  On Monday, we had a guest speaker come in, Chamberlain Fong.  I met him in Finland at Bridges this summer, only to find out he lives the next neighborhood over in San Francisco!  He gave a very interesting talk about taking pictures with a spherical or hemispherical camera lens, and the issues involved in printing the pictures.

The problem is essentially the same as creating a map of the globe — making a sphere flat.  There will always be distortion, but you have some control over what type of distortion.  You can keep angles the same, or areas the same — or some combination of the two.  And as these cameras keep getting cheaper, there will be a growing interest in making your spherical photos look realistic.

And although we had class on Wednesday, some students had already left for Thanksgiving Break.  So Nick and I were available to help on an open lab day.  Most of the students actually showed up, and we had a productive day working on movies (which were due Wednesday) and projects.

The next (and final!) post on Mathematics and Digital Art will survey the students’ Final Projects, so stay tuned!

On Coding IV: Mathematica

In my last installment of “On Coding,” I talked more about functional proramming and how working with LISP so heavily influenced my coding in Mathematica.  To continue the thread, I’ll need to jump ahead on my timeline, since a lot of what I’ll say applies to my current use of Mathematica.  Then next time, I’ll need to jump back to my college days since I was also learning Postscript in parallel with LISP and Mathematica.

One nice feature of LISP and Mathematica interfaces is that they’re interpreters, meaning you interact directly with the kernel.  I can just type “3 + 2” and get a return value of 5, without needing to put the expression in a wrapper function.  This makes is easy to try out new functions.  And in Mathematica, there are thousands of functions — so lots to try out!

But aside from functional programming aspects, I think one fundamental advantage of using LISP or Mathematica is the fundamental data structure:  a list “(  )” in LISP, or “{  }” in Mathematica.  This is a fluid, untyped data structure, and is perhaps the most general way to store data.

In many languages, variables are typed.  That means if you want an array, you have to say what is in the array.  Is it an array of integers?  String?  Reals?  You can’t mix and match.

In Mathematica (and other languages as well, like Python), there are no restrictions as to what goes in a list.  So you can have a list like

{42, 3.1416, “Hello world!”, {0, 1, 2}},

and that would be no problem at all.

This is actually a very nice feature, but you do have to be careful.  If you try evaluating

Plus @@ {42, 3.1416, “Hello world!”, {0, 1, 2}},

you actually get

{45.1416 + “Hello World!”, 46.1416 + “Hello World!”, 47.1416 + “Hello World!”}!

The reason is that the “+” operator in Mathematica is overloaded, meaning it performs differently depending on what the arguments are.

The 42 + 3.1416 = 45.1416 is evaluated first.  Now a real can’t be added to a string, so Mathematics leaves the expression in an abstract form,

45.1416 + “Hello World!”,

without actually evaluating.  But when {0, 1, 2} is finally added, the “+” operator adds 45.1416 + “Hello World!” to each element of the list, and returns the resulting list.  Of course addition is commutative, so 0, 1, and 2 are added to the real part of the expression.

In a language like C++ or even Python, this would be unthinkable.  You’d get an error message right away.  But in Mathematica, all would be well — almost.  If you made a typo in your list of objects to add and Mathematica found a way to add them, you might get some rather bizarre behavior if that result were passed to some other function.  In other words, you’ve just got to be careful.

This fluidity makes creating graphics easy, in my opinion.  A graphics object is essentially a list of directives and objects, like

{Blue, Line[{{0,0}, {1,1}}], Red, Disk[{2,2}, 1]}.

Mathematica interprets this as follows.  First, make the stroke color Blue, and draw a line from (0,0) to (1,1).  Change the stroke color to Red, and then draw a disk of radius 1 centered at (2,2).

This loose structure makes creating graphics objects simple, as all you’re doing is building a list.  And that list contains a series of instructions about how to create an image.

There’s a slight drawback, for me at least.  I get frustrated sometimes when I program in a language like Python, where data structures enclosed in “[  ]” might be lists, tuples, or vectors, for example.  You often need to explicitly say what you want, as in using the function

vector([0, 1, 2]).

This is highly annoying to the Mathematica programmer, who thinks Python should be clever enough to figure it out….  So I find myself always looking up what type of argument is passed to a certain function to make sure I don’t get a runtime error.

Another advantage of using LISP and Mathematica, in my opinion, is that the return value of a function is the last statement executed.  This is a very nice feature — once you get used to it, you can’t image how you ever lived without it….

Let’s look at a simple example which takes advantage of this feature and uses some functional programming ideas.  Here’s the Python code:


Nothing complicated going on here, just add two variables based on whether one of them is positive or not.  Here is the Mathematica code:


Yes, it’s really just one line!  The If statement returns the function “Plus” if the variable x is positive, and the function “Times” otherwise.  This return value can be immediately applied to the list containing x and y in order to carry out the desired operation.

Unless you’ve worked with a functional programming language before, this type of coding construct might seem a little strange.  But once you get used to thinking this way, you really can code more efficiently.

I also like that the decision about what function to used is very clearly based on whether the variable x is positive or not, since the If statement returns the name of a function.  Of course it’s clear in the Python code since the example is so simple, but the Mathematica code really drives the point home.

The one drawback for me is forgetting the “return” statement in Python all the time.  I’m so used to this feature in Mathematica that it’s automatic in my thinking about code.

The list structure and how return values are handled, in additional to the functional programming aspects, are the two features which most directly impact the way I write code in Mathematica.  But I can’t end this discussion without saying a few words about graphics.

I enjoy the absolute control you have about every feature in Mathematica.  You essentially have a blank slate, and can put just about anything you want anywhere you want.  I’ve never used a user interface to create graphics, and never will.

The reason is that you are often constrained by the available options with a GUI.  Not so in Mathematica.  Essentially, if you can conceive it, you can implement it.  It may take some time and a lot of code, but it can be done….

So that briefly summarizes my relationship with Mathematica, which is ongoing.  Next time, Postscript!

p-adic Numbers II: When Big is Small

Today we’ll finish our brief introduction to p-adic numbers.  It’s been a few weeks, so it couldn’t hurt to skim over the first post to refresh your memory.


After we finish our discussion of …..4444444, we’ll look at how to use ideas related to p-adic numbers to create fractal images like the one above.

Recall that our goal was to show that in the field of p-adic numbers, we had

.....444444444 = -1.

I should point out that the term field in mathematics has a very specific meaning, but we won’t be going into any more details about fields here.

In preparing to show this, we defined the 5-size of a number to be


where 5^q is the largest power of 5 which is a factor of n.  Although unconventional, this distance function satisfies all the necessary properties.

Here is where things get really interesting!  While thinking in terms of ordinary distance, it seems that the terms in the sequence of numbers

4, 44, 444, 4444, 44,\!444, \ldots

keep getting further and further apart.  But in terms of the 5-size, they actually get closer together.

Let’s see why.  The 5-distance between 4 and 44 is


since 5 is the largest power of 5 going into 40.  Recall that we’re working in base 5, so that in fact


So the highest power of 5 going into a number, written in base 5, is the number of 0’s at the end of that number.

Next, the distance between 44 and 444 is


since 5^2 is the largest power of 5 dividing 400.

Can you see where we’re going with this?  If you subtract a number with n fours from a number with n+1 fours, you get 4\cdot5^n, and so the 5-distance between them is |4\cdot5^n|_5=1/{5^n}. Therefore, as you keep adding fours, the numbers actually get closer and closer together when you consider the 5-size of their respective differences.

In mathematical terms, we say the sequence

4, 44, 444, 4444, 44,\!444, \ldots

converges with respect to the 5-distance, much as we say that 0.999999999..... converges with respect to the usual distance on real numbers.

What does this sequence converge to?  Suppose that

.....444444444 = L.

Let’s try to find L.  This is where addition modulo 5 comes in!  Consider the following addition problem:

\begin{tabular}{r}.....444444444\\1\\ \hline .....000000000\end{tabular}.

We’ll take a moment to interpret this sum.  On the very right (the units place), we add 1 + 4.  But that’s 5, and there is no digit “5” in base 5 — rather, we write “10.”  This means write down the 0, and carry the 1.  But then in the second column from the left (the 5’s place), we have 1+ 4 = 10, and so we write down the 0 and carry the 1.

As you can see, this process never ends, and the result is an infinite string of 0’s, which is 0.  This shows that

.....444444444 + 1 = 0,

or, in other words,

.....444444444 = -1!

And here’s the really mind-blowing part.  Consider the geometric series


in base 5.  The first term is 4, and the common ratio is 5.  So the sum is


Yes, the geometric series formula works when r is 5!  The reason is that when you keep multiplying numbers by 5 in the field of p-adic numbers, you’re really bringing them closer together.  Sounds impossible — but this can all be rigorously proved in the world of p-adic numbers.

Though we’ve only taken a small peek at the world of p-adic numbers, I’d like to take a few moments to say why they are significant when it comes to creating fractal images.  After all, that was the reason I found out about p-adic numbers in the first place!

On Day008, I discussed a way to determine which way you need to turn at any point during the construction of the Koch curve.  Here are the first few iterations of the Koch curve algorithm, in case you’ve forgotten.


In that post, I said I “discovered” that at step n, all you needed to do was look at the highest power of 2 going into n, and turn one way if that power was even, and another way if that power was odd.

But if you think about it for a moment, this is just what we did to calculate 5-size — found the highest power of one number which divides another number.  And if we just look at those exponents, we get what’s called a 5-adic valuation.  The first several terms look like this:


Any number not divisible by 5 has a valuation of 0, multiples of 5 have a valuation of at least 1, although for 25, you get 2.  And so on.

Actually, just a few weeks ago, I read in a paper I found online that the Koch curve can be generated by a 2-adic valuation.  As often happens in experimenting with mathematical ideas, you often re-discover ideas someone else already knew about.

I didn’t really care, though.  Doing mathematics is as much about the process as the result, and I really had fun “discovering” this, and writing my own proof showing how it generated the Koch curve.

So this got me thinking.  If you can generate fractal images with a 2-adic valuation, why not try a p-adic valuation for some value of p different from 2?

And to my amazement, it works in very much the same way!  But in order to generate a curve using two angles, you have to take the p-adic valuation, and then take it mod 2.  This generates a sequence of 0’s and 1’s, and that’s all you need.

I also found out that my work reproving an old result actually helped a lot — since I was able to prove a similar result for curves generated by a p-adic valuation in almost exactly the same way.  And my previous work already had me thinking about the relevant features of these new curves.  So when you discover some cool mathematical fact that someone else already knew, well, don’t despair.  Just entertain the thought that great minds think alike….


I’ve been experimenting a lot with p-adic valuations recently — this image is based on a 3-adic valuation.  I’ll only say that this opens up an entire new world of fractal image possibilities.  Check out my Twitter @cre8math for more cool examples!

Digital Art V: End of Week 11

It’s been an exciting three weeks in Mathematics and Digital Art!  We began Week 9 after our Fall break with a talk by Carlo Sequin.  Here’s Carlo with one of his sculptures at the University of California, Berkeley.


I met Carlo through the Bridges conferences; he currently sits on the Board.  Since he’s so close by, I thought it would be great to have him visit my class.

His talk centered around the computer graphics programs he wrote in order to design sculptures like the one you see in the picture above.  Carlo included several different parameters, allowing an incredible variety of images to be generated.

Then he focused on a few of his sculptures and described the design process from conception to final sculpture.  He even remarked how he got lucky once — he and his team forgot to measure the width of the door they needed to take the sculpture through, and it fit with just a few inches to spare….

Friday, Day 24, was our first Project day.  Students’ ideas were still somewhat vague — they did have to write a Proposal, but still didn’t have a clear direction.  We made some progress, though the next Project day helped quite a bit more.

On Monday, Day 25, we dived into working with Processing.  I kept in mind the comments from students’ response papers which I mentioned in my previous post — they really wanted to learn more about code.

Now coding is a precision endeavor, as there is no room for error as far as syntax is concerned.  So after working through a simple example, I presented them with the following movie.

Admittedly it’s not a blockbuster…but their lab work was to duplicate this movie as precisely as possible.  I gave them a basic template (see the May 2016 archives for the start of a six-part series on Processing which I used as a basis for their lab work), but they didn’t just have to tweak numbers — they also had to add new elements.

The main mathematical tool involved was linear interpolation, which we went over in some detail in class.  The next class, I had them work on recreating the following movie.

This proved a bit more challenging.  Some students at first thought there was a rotation involved — but it’s just linear interpolation again, on a somewhat larger scale.  Here are the prompts I gave them:

  • the screen is 500 x 500 pixels;
  • the dots are always 25 pixels from the edge;
  • the colors are the standard red, green, blue, and orange;
  • the smaller dots are 100 pixels wide, and the larger ones are 200 pixels wide.

The main challenge was working in screen space, since they needed to calculate the exact centers of the circles.  Of course students progressed at different rates, and they were finally getting the main point — you can use linear interpolation to morph any aspect of an image which depends on a numerical parameter.  As a mathematician, I was used to thinking along these lines all the time, but it’s a concept that takes a while to really sink in if it’s new.

Friday, Day 27, was our next project day.  We worked at fleshing out more details of the students’ various projects.  Two students wanted to explore image processing, so Nick continued working with them to download the appropriate packages and get Python installed on their computers.  Such projects are never as easy as they sound, but Nick did get everything to work.

While he was doing that, I circulated with the other studets, discussing their projects and answering a few questions about making movies, if they had them.  It was a productive day, and everyone left class with a much clearer idea of their project than they had the week before.

On Monday, we continued our work with Processing.  I went through an example from my earlier blog posts — making a movie which morphs a Sierpinski triangle — in some detail, explaining it line by line.  Again, the most challenging part was converting from user space to screen space.  A fractal which fit in a unit square had to be scaled and moved to fit nicely into screen space.

This took just about the entire class.  Although we had done work previously with iterated function systems, we did have to take some time to review certain aspects of the code we used before.  Then on Day 29, I had them duplicate the following movie.

In order to focus on the coding, I began the movie with a fractal they had on a previous quiz, so they knew which affine transformations to start with.  They had to figure out how to modify one of the transformations to produce the final image, and then use linear interpolation to create the movie.

This proved challenging, but everyone made good progress during the lab.  They are supposed to finish by Monday.

On Friday of Week 11, we had our second guest speaker — Shirley Yap from California State University, East Bay.  I met Shirley last February when Nick and I went to a regional meeting of the Mathematical Association of America.  She was in charge of organizing the Art Exhibition Nick and I had pieces in.

After showing a few interactive examples from her web page, Shirley focused her discussion on the following piece she created.

Leaves of Glass

She talked a lot about the challenges of making a physical piece, rather than a work of digital art.  For example, she actually wanted to use glass, but is was not possible to etch in glass given the tools she had available.  So she had to settle for acrylic, which is very easy to smudge if you aren’t careful.  You see, the individual squares can pivot where they are screwed in, so the artwork is interactive.

There were also size requirements, since she had to be able to take in on the airplane with her to a conference.  Other issues arose — in some ways working digitally is a lot easier.  As Shirley remarked, once you drill a hole, you can’t undrill it…but it’s easy to change a parameter in digital work.

What was really nice was that Shirley talked about mathematical envelopes (one of my favorite topics; I’ve written about it before on my blog), and the curves she used to make her envelopes — Bernstein polynomials.  She took the time to go through a few simple examples, so that students got a sense of what these curves are like.  It was a nice example of yet another topic in mathematics students hadn’t seen before being used to create art.  Truly, mathematics is everywhere….

Stay tuned for the next update of Mathematics and Digital Art!