Vectorization: Hands-on experience!

Hands-down, the first step to learning vectorization should be hands-on.

Unfortunately, I lack the following (which are often used for vectorization):

  • Fancy tablet pen
  • Vectorization software

Of course, the second thing is easy to get online for free; there’s resources like InkScape, for instance. But I felt lazy, so here’s what I restricted myself to:

  • Mouse
  • Microsoft Powerpoint

As it turns out, Powerpoint 2007 is a pretty fancy piece of software. You know that “curve” tool? Yeah, that thing is pretty useful. I used it to trace over the following picture, because ‘Murica:

https://i0.wp.com/upload.wikimedia.org/wikipedia/commons/1/1b/Abraham_Lincoln_November_1863.jpg

At first, the picture looked kind of boring, since I just captured the most prominent features. This could be considered the “first iteration”:

lincoln_boringBut hey, it seems like it’s getting somewhere. So I added a few more “Smart Shapes” and colors, and glasses:

hipster_lincoln_signed

Eureka! Fabulous! So next time you want to draw something cool, look no further than PowerPoint. If you’re interested, the original file is here. (Use group -> ungroup as necessary to get the individual shapes.)

A New Project: Vectorization

Most of our images on the internet are raster, or “pixel,” images. That means they can’t be scaled – when you zoom in, they’ll become fuzzy. So how can we avoid this? Vectorization.

Vectorization is the process of defining images by their geometric relationships with each other. The text on your computer is an example – you can zoom in forever and the edges will still be smooth. Humans also perceive in vectors – we distinguish objects by their edges, not by their appearances on a fixed array. SVG’s, or Scalable Vector Graphics, are useful tools for creating great-looking scalable images; however, they always end up looking “cartoony” because of the limitations of computer shading. To see what I’m talking about, check out this world map – and try zooming in as much as possible: http://upload.wikimedia.org/wikipedia/commons/6/63/A_large_blank_world_map_with_oceans_marked_in_blue.svg.

So, for the next few weeks I’m going to find out how vectorization works – the algorithms, the philosophy behind it, etc. Hopefully, if this turns out good, I’ll be able to make my own vector images from raster images!

Polar Equation of a Hexagon

Have you ever heard of a squircle? It’s kind of like a circle, but with more pronounced “edges.” When you plot one out, it looks like a beveled square (at least in the first quadrant). Here’s an example:

\sqrt[p]{x^p+y^p}=1 where p>2

When p=4:

    MSP10791gh815119g79g4c700003eb5a454hi49eic3

Isn’t that nice? It looks so happy!

But, in a wildly unrelated tangent, I was wondering, how would you represent a hexagon? More specifically, how would you represent a hexagon in the polar coordinate system?

Just for fun, I’m going to couch this in terms of a scientific investigation.

Question: What is the polar equation for a hexagon?
Hypothesis: It’ll involve an absolute-value sine function. That’s because the x-y graph should look something like this:

hypothesis

Variables: Independent = x, \theta; Dependent = y. (See what I did there? Okay…)

Investigation: I decided to begin by dealing with the equilateral triangle in the first quadrant. It looks like this:

diagram

I then solved for the value of x.

x=\frac{\sin60^\circ}{\sin(120^\circ-\theta)}=\frac{\frac{\sqrt3}{2}}{\sin120^\circ\cos\theta-\sin\theta\cos120^\circ}=\frac{\frac{\sqrt3}{2}}{\frac{\sqrt3}{2}\cos\theta+\frac{1}{2}\sin\theta}

This solution can be converted into a different form:

x=\frac{\sqrt3}{\sqrt3\cos\theta+\sin\theta}=\frac{\sqrt3}{2\sin(\theta+60^\circ)}=\frac{\sqrt3}{2}\csc\left(\theta+60^\circ\right)

Now, if you add a floor function, you can have it repeat for angles up to 360 degrees!

x=\frac{\sqrt3}{2}\csc(\theta+60^\circ-60^\circ\lfloor\frac{\theta}{60^\circ}\rfloor)=\boxed{\frac{\sqrt3}{2}\csc(\theta-60^\circ\lfloor\frac{\theta}{60^\circ}+1\rfloor)}

Conclusion: The hypothesis was incorrect – the graph is actually a concatenation of segments from a cosecant graph. Below is a graph of this equation in Wolfram Alpha!

equation

MSP4451ebii1aae7067eh200000ce06gaeh1e52fa7

Hey, Naveen – What’ve you been up to?

Hi everyone! It’s been a long month of hard work (and sleeping in over Winter Break :P), and it’s time for me to announce… GeneRegPy!

Basically, GeneRegPy is a piece of software I developed over the break. I’d been studying “Gene Regulatory Networks” and their functions for a while now, and I finally applied it by designing biological circuits.

Each network is defined by nodes (individual genes and their corresponding transcription factors) and edges (vectors from one node to another, representing transcription factor activity). The software simulates the network, and provides an output that helps the user understand the network’s behavior. I’ve verified it with previous works; in particular, Alon and Mangan’s FFLs and Elowitz’s Repressilator.

Although I lack access to professional journals, I have been trying my best to create networks with useful functions, and hopefully they will prove to be new and/or more effective than existing ones!

Math is Beautiful: Squares and Imaginary Numbers

I’m gonna tell you right now: The clockwise rotation of a square is isomorphic to the group {1, i, -1, -i} multiplied by -i.

So basically, let’s say we had a table of rotations for a square with counterclockwise vertices A, B, C, and D. But let’s assign the values 1, i, -1, and -1 (the powers of i) to these four vertices, respectively. It’s clear that each position can be determined by multiplying the original group by -i in order to rotate the square clockwise (left-to-right):

position 0 degree 90 degrees 180 degrees 270 degrees
1 A (1) D (-i) C (-1) B (i)
2 B (i) A (1) D (-i) C (-1)
3 C (-1) B (i) A (1) D (-i)
4 D (-i) C (-1) B (i) A (1)

I think this is amazing! A connection between geometry and complex numbers! The tools math has given us are wonderful and amazing. So beautiful.

A One-Line Primality Test

Learning the J programming language has got me thinking in terms of vectors. Since the TI-84 is optimized for list functions, why not use it to implement vector operations? (See my earlier post, here)

It is well-known that there exists a one-line, purely mathematical (no if’s, loops, branches, etc.) APL prime number finder:

PRIMES: (~R\in R\circ,\times R)/R\leftarrow1\downarrow\iota R

Now, what this program does is initialize a vector from 1 to R, drop the first element (as seen by 1\downarrow), create an outer product, create a vector representing the values contained in the outer product, and logically inverting this vector, and select the values in the original R that correspond with “1”‘s. This is a pretty cool solution, and I was inspired to write a primality tester in the same spirit of vector operation.

The first problem is the actual method of testing whether the number is prime. My own implementation creates two identical vectors from 2 to a number A, inclusive. Then, with the first vector, it divides A each element to create a new vector. The second vector is treated in the same way, but only storing the integer parts. Then, the two vectors are subtracted. All values that are equal to 0 are stored in a new vector as 1s, and those that are not as 0s. Thus, your resulting vector is a vector from 2 to A with 1s representing the positions of divisors of A. Because this vector will only have a 1 in it if it’s divisible by a number, the way to tell if it’s prime is by taking the sum of the elements and seeing if the value is zero. If it is, then eureka! You’ve got a prime number.

But did you catch the error in that last paragraph? I wrote that I generated a vector from 2 to A, which should always yield a program output of “Not Prime” (since A is divisible by A). But that is clearly not the case! But I still wouldn’t want to create a vector going from 2 to A-1; what if I had a large number like 2017 (the next prime year)? Wouldn’t I want to optimize in some way?

Turns out that the way you can optimize is limiting the vector length to 1 plus the integer part of the square-root of A. That’s because checking any number above that would be redundant – the numbers less than the square root of A will have always been checked! So that makes our search a little simpler, and extends the range of numbers we can check in this optimized way. (The maximum list length for the TI-84 is 999, meaning you can theoretically go to values up to 999999 this way, since it gives a vector range from 2 to 1000 inclusive.)

The final challenge is displaying the text without if-then statements. I did this using boolean conditionals built into the calculator, and displaying a substring of “NOT PRIME” starting at either position 0 or 4 depending on whether the sum of the resultant vector’s elements was 1 or 0.

The full text of the (one-line!) calculator command is below, partitioned into blocks of 16 characters for your transcription convenience:

101→A:iPart(√(A)
)+1:sum((iPart(A
/seq(x,x,2,Ans,1
))-A/seq(x,x,2,A
ns,1))=0)=0:sub(
"NOT PRIME    ",
1+(Ans=1 or A=2)
*4-4(A=1),9

Have fun 😉

Inverses of the Hilbert Matrix

Have you ever heard of the J programming language?

Exactly. Me neither.

It’s an APL-inspired language: it tries to systematize mathematical notation – especially notation associated with vectors/lists/matrices/arrays. So that makes it useful for making succinct programs. For instance, an APL primality program can take as little as one line!

So basically, the J programming manual told me that J is especially effective at finding inverses due to its precision and etc etc. So I’m going to do my first program on finding the inverse of different-sized Hilbert matrices.

Okay so J is a very, very dense language. Every symbol has a lot of meaning. I have two choices for a program structure:

n =: 6 NB. Desired size for the Hilbert Matrix
x =: %. %(1 + (i.n) +/ i.n) NB. Constructs the Hilbert Matrix and inverts
x NB. Displays X.

The above program is nice since it is short and sweet and easy to manipulate – just change n! But it has a problem: precision. Note the output for this program:

   36    _630      3360     _7560       7560      _2772
 _630   14700    _88200    211680    _220500      83160
 3360  _88200    564480 _1.4112e6    1.512e6    _582120
_7560  211680 _1.4112e6  3.6288e6   _3.969e6  1.55232e6
 7560 _220500   1.512e6  _3.969e6     4.41e6 _1.74636e6
_2772   83160   _582120 1.55232e6 _1.74636e6     698544

This is difficult to work with. The “e” values indicate that for larger values, there may be rounding off. So to fix this, I use arbitrary precision in a slightly more wordy program:

x =: i.6x NB. Defines the size - WITH arbitrary precision!
x =: 1 + x +/ x NB. Constructs a Hilbert Matrix
x =: %. %x NB. Takes the matrix inverse of the inverse
x NB. Displays x

The output of this is as follows – much cleaner!

   36    _630     3360    _7560     7560    _2772
 _630   14700   _88200   211680  _220500    83160
 3360  _88200   564480 _1411200  1512000  _582120
_7560  211680 _1411200  3628800 _3969000  1552320
 7560 _220500  1512000 _3969000  4410000 _1746360
_2772   83160  _582120  1552320 _1746360   698544

Now note how there are no “e” thingies in the numbers! It’s using arbitrary precision at its finest.

Now, going along with my second (more precise) program, here are the Hilbert matrix inverses in order from 1 to 10. Super easy because J is so nice!

So here is my final program:

v =: i.
hilbert =: %.@:(%)@:(1&+)@:(v+/v)

hilbert 1x
hilbert 2x
hilbert 3x
hilbert 4x
hilbert 5x
hilbert 6x

(I’m pretty sure loops are possible; I’m just not there yet.)

Here is the output:

   hilbert 1x
1
   hilbert 2x
 4 _6
_6 12
   hilbert 3x
  9  _36   30
_36  192 _180
 30 _180  180
   hilbert 4x
  16  _120   240  _140
_120  1200 _2700  1680
 240 _2700  6480 _4200
_140  1680 _4200  2800
   hilbert 5x
   25   _300    1050   _1400    630
 _300   4800  _18900   26880 _12600
 1050 _18900   79380 _117600  56700
_1400  26880 _117600  179200 _88200
  630 _12600   56700  _88200  44100
   hilbert 6x
   36    _630     3360    _7560     7560    _2772
 _630   14700   _88200   211680  _220500    83160
 3360  _88200   564480 _1411200  1512000  _582120
_7560  211680 _1411200  3628800 _3969000  1552320
 7560 _220500  1512000 _3969000  4410000 _1746360
_2772   83160  _582120  1552320 _1746360   698544

Woohoo! One thing that stands out to me immediately is that H(1,1) is always the square of the dimension. Interesting, eh?

In the future I plan to build upon my learning using the tutorial at http://www.rogerstokes.free-online.co.uk/book.htm#toc. ^_^

Design: Chinese Numeric Pangraph

Based off an initial design and suggestions from friends, I finally constructed a prototype infographic, which I will use boolean algebra to simplify.

Presented by yours truly, and created proudly with Microsoft Paint (click image to view it in all its hi-res glory):

keymap

Can’t wait to finish this!!!