In chaos theory, we study a bit of complex analsis, necessary for describing the dynamics of complex functions. In doing so, we redefined differentiability for the complex plane (essentially the same limit definition, although it simplifies differently because of the imaginary components). 

We then worked with complex functions and worked at finding whether or not they are differentiable at certain points. In doing this, I noticed a pattern. Through 30 minutes in the math lab with a chalk board, I developed equations that simplify the process of finding the differentiability of a complex function at a point – using partial derivatives, and splitting a complex function into a function on the real part and a function on the imaginary part.

Only just now have I discovered that this is already known, a set of equations in complex analysis! I was just browsing wikibooks and discovered the _very_ same formulas I derived! They’re called the Cauchy-Riemann Equations, and they use partial derivatives to analyze the differentiability of a complex function. 

Do I at least get a cookie or something?

http://en.wikibooks.org/wiki/Complex_Analysis/Complex_Functions/Analytic_Functions

I’ve finished my Bifurcations program (including the spit-polish, minus one feature). It’s all very nice, I think.

I’ve also finished my Mandelbrot program (again), this time it it’s multithreaded! I really want to bench it against my last iteration. It’s about 10x faster than the old one – instant calculation, unless you zoom to a part with a lot of black (and therefore a lot of iterations). 

The default way to run it uses two threads, but I’ve compiled it with 35 threads and it’ll still run (without as much of a speed boost, of course.) At a certain point extra threads add nothing – in general anything over the number of processor cores, although I haven’t tested explicity (which is why I want to bench everything.)

Mr. Andersen is using my work as I finish it for his chaos class, I’m rather proud of that =). It was, after all, what its itended use was. He showed them the bifurcation program today, I heard, and he’s shown my preview video to the class as well. It’s the video I made (to E-30-something) so that the people overseeing all distinction projects know that I’m doing something. It’s purely a preview, my final (for my presentation) will hopefully go to around E-100. 

Watch it Now!

It’s been a long while since I’ve posted, and for good reason. School started! 

This means that I have no time, ever, for anything. I’m constantly working. The past few weeks have been kind of ridiculous for me. This past weekend I had to finish my National Merit Semifinalist packet, which required a 500 gloat essay (I hate these. “Tell us how awesome you are, maybe you’ll get some money.”) I also had to complete the preliminary test for the Deutscholympiade (International German Olympics – Dec. 5, Chicago), which was no easy task. Having only had a year of German, my vocabulary is not really amazing yet, so much of my time was spent inferring the meaning of words. I also had to write an essay about myself and my hobbies, which was unfortunate since I didn’t know any of the words for my hobbies (except Differentialrechnung and Integralrechnung – Differential and Integral Calculus).

The LAN Party for the comp sci club is Saturday night – looking forward to it. I’ll probably be lame and do homework – but everyone else should have fun! (I’m president, I’m allowed to not have fun :P ) Also, SAT is this Saturday – I haven’t studied at all, so we’ll see how that goes. Next weekend is Sadies, and a Math Competition in Baton Rouge. I’ll have to look over lower math…It’s been a while (as conceited as that sounds, it’s true. I can’t do Cal2 anymore)

Somehow I’ve managed to continue working on my distinction project, which will require it’s own post.

I hope this gives at least a little insight into life at lsmsa, I’d eventually like to post some examples of the workload (e.g. “This paper got a D. This paper got an A. Note the difference.”)

-Evan

I’ve just finished the modifications to my Mandelbrot program that will allow me to zoom past the normal limitations of C++.

I didn’t finish ipfloat, I’ve put that on the backburner for now (although I _will_ be finishing it before the end of summer). Instead, I used GMP – GNU Multiprecision Library. It’s not the ideal solution; it’s very bulky and slow – but it gets the job done. Hopefully when I finish ipfloat I can improve size, if not speed.

Anyway, here is my very first, preliminary zoom image! The colouring is dull, I know – I need to write an algorithm for more than one colour.

Mandelbrot Deep Zoom

Mandelbrot Deep Zoom

Tada! This image is centered around -1.78646693153666370 + 0i , with 2000 iterations and an escape radius of 2.

In other news, I’m still working on the Media Center program. Unfortunately, one of the Telerik controls doesn’t work the way it should, so I’m using a MS DataGridView for the time being.

And it seems to me
That reality
Time, two lumps of su
Garnish my life, today by day
We work, we act for Shakespeare
In your eye, pull out the
Splinter minal dis easy to behave
ing like there’s no one else around
peg in a square hole in the ground.

GMP compiled in VC9 EE, make’d in cygwin, currently make checking. Late for work.

An excellent song by the comedy group, Monty Python. Unfortunately, it has very little to do with the content of this post, I just happened to have listened to it recently.

I’ve been away on vacation, and I won’t bore you with too many details. Highlights: World of Coke, Six Flags, Stone Mountain, Cats, Williamsburg, Root Beer, Family I see once every 3 years.

Now back to business. Whilst away, I did a bit of work on my ipfloat and polished the + function; there currently no bugs that I know of (heap and stack errors fixed), and it’s the most efficient iteration of the software yet. I’ve decided to freeze the plus logic and finish everything else before attempting any further optimizations. My next task is multiplication, so Fast Fouriers will soon be explored in depth on this blog.

I do need to rewrite my output function. By a silly oversight, it won’t print anything with a negative exponent. Should be relatively easy to fix, at most an hour.

I’m also currently writing software for the media center, which I haven’t really mentioned before. It keeps track of inventory and work service students, but I’m porting it to a new interface system – screenshots soon.

I have to do some heavy German studying as well, so although I’ve stopped my postly practice sentences, expect more interesting things (poetry, mayhaps?) from time to time.

I know that this is a lame, thrown together post and I apologize. I’m going to try to improve the quality of my future posts, that this may become something of a real blog.

I’ve mentioned speed improvements in a better addition algorithm that I’m writing. I’ve already finished the parts that actually improve on the original, so I thought I’d go ahead and outline the algorithm.

Originally, this is what was done:

Input:

123.021 + 1.1

Convert input to:

123021+001100

Then loop through and add each column, carrying as necessary. The result would be 124121, and then the output function would combine that with the exponent: 124.121.

The new algorithm is based on the fact that unless both numbers have the same number of digits and the same exponent, there will be some of this “overlap”, which is what the padding eliminated in the old algorithm. But why pad with 0’s? Aren’t I just adding? Don’t I know what a number + 0 is before I calculate it? Of course.

So the new algorithm identifies which parts of the numbers would just get added to insignificant zeros (as opposed to significant zeros, like the ones in “2002″) and copies them over verbatim to the result, no calculations necessary.

For example:

Input:

123.021 + 1.1

Intermediate steps:

(copy outliers)

Result = 120.021

(perform addition, the loop described above, but only for the middle two digits)

Result = 124.121

Make sense? In this example, I cut the number of times the addition loop runs from 6 to 2! This won’t save time in all cases, but in some it will greatly improve things.

In my last post I mentioned that I was fixing a heap overflow and making speed improvements to the + function in ipfloat. Memory in C++ is stored in an interesting way. There are two main sections of memory that a programmer must worry about – the heap and the stack. (There is a global region of memory as well, but this doesn’t usually create problems, unless the program is designed poorly and data is not well encapsulated.)

The heap is “dynamic memory” – any dynamic variables get allocated in the heap. Essentially, anything created using new or malloc will get stored here. The stack is for local variables, parameters, and temporary variables (created during assignments/operations that are never explicitly created).

What was my problem? Heap overflow/corruption. This is what was happening:
Heap:
|-man-||–thisMan–||–rhsMan–|
thisMan and rhsMan were normalized with zero’s, so they became a little larger. But man must be expanded to hold the result of both of the other two, so if the difference between sizes of man and rhsMan was too great, man would overflow and corrupt thisMan. And since man was calculated from thisMan, _bad things_ would happen.

So, while 3.14159 + 2.18281 would cause no problems (man wouldn’t need to expand at all), and even something like 2.323123222312341 + 123123123.12312 would be okay, something like 0.00000000000000000001 + 123123123.123123123 would _at least_ corrupt data, if not overflow the heap altogether.

This is because 0.00000000000000000001 is actually stored in memory as [1, -20, +] and 123123123.123123123 is stored as [123123123123123123, 8, +]. This makes man=1, thisMan = 000000000000000000001, and rhsMan=123123123123123123. Man is stored _before_ thisMan, so in order to expand to fit all of the digits, it must of necessity overflow into thisMan.

How did I fix this? By completely restructuring, of course :P

This is how it works now:
Heap:
|–man–||–rhs–||—-result—-|

Now instead of copying man into a temporary variable and expanding man to hold the result, I make the temporary variable hold the result and its space is allocated _after_ the original values. No corruption!

I also reworked the addition algorithm (haven’t finished yet), to save some time. I’ll save that for another post, I’m now out of time.

I just received my transcript and my schedule for next year, so I thought I’d share them. This is going out on a limb for me, because I don’t like sharing which classes I made B’s in. I figured since this blog is supposed to be about LSMSA life, I’d go ahead with it.

8th
Algebra 1 – P (apparently this was P/F? I had no idea)

9th
Algebra 2 – B
Biology 1 – A
English 1 – A
Geometry – A
Health – A
Band – A
PE – A
Physical Science – A
World Geography – A

10th
Band – A
Advanced Math – A
American History – A
Calculus 1 – A
Chemistry 1 – A
Civics – A
Computer Science – A
English 2 – A
Free Enterprise – A

11th (LSMSA)
Adv. Progr. in C++ – A
Composition/Literature – A
German 1 – A
Chaos Theory – A
Calculus II – B
Calculus III – B
Vector Calculus – A
Fund. of Music – A
Physics III – A
Modern Algebra – A
Intro to Music Theory – B
Weight Training – A
Classical Mechanics – A

Schedule for Next Year:
Semester 1
MWF
10:00 – Weight Training
11:00 – German II
12:00 – Advanced Music Theory 1
(Monday) 6:30-9:00 – Computer Hardware

TR
8:00 – American Lit
9:25 – Kultur Tag (German II)
10:50 – Programming in Java

Semester 2
MWF
11:00 – German II
4:00 – Linear Algebra

TR
8:00 – Graph Theory
9:25 – Kultur Tag (German II)
10:50 – Brit Lit (Hall)
1:40 – Data Structures

They scheduled me for 6 and 5 classes, I signed up for 7 and 8. So I need to go get my schedule changed…

In other news, I’m rewriting the + function again. Fixed heap corruption and making speed improvements.

It’s been a while since I’ve posted because I really wanted to have something to show for myself. I finally have a completely working += function (for non-programmer types, a+=b is equivalent to a = a+b). It took longer than I expected because I kept rewriting it – I started from scratch 3 times. I kept seeing better ways to structure it to get better performance, better readability, and be able to handle all cases. In the end, it’s not perfect, I still have some optimizing to do, but that comes last. The important thing is that it’s finished and does exactly what it’s supposed to.

Also, I compiled this not only with wxDev-C++, which is the shmancy graphical IDE that I’m using for this project, but also with gnu g++ running on Cygwin. If you’ve never heard of Cygwin, you’re missing out – it’s a complete bash shell that will run in windows. I’ve successfully compiled my program in linux! (Technically unix, but it doesn’t matter in this case). I did have to write an itoa() function, which is built in on my other compiler but undefined with g++, but it was worth it.

I’m tacking the code onto the end of my post so you can look at it if you care, but I think the output is what’s important right now. To test it, I added the first 1000 digits of pi to the first 1000 digits of e. What better to test a program? Here’s the output (the beginning bits are the compilation, if you’re not familiar):


Evan@EvanLaptop ~
$ cd ipfloat
Evan@EvanLaptop ~/ipfloat
$ g++ -o iptest -O ipfloat.cpp main.cpp
Evan@EvanLaptop ~/ipfloat
$ ./iptest
ipfloat addition test program
Enter the first floating point decimal:
3.141592653589793238462643383279502884197169399375105820974944592307816406286208 99862803482534211706798214808651328230664709384460955058223172535940812848111745 02841027019385211055596446229489549303819644288109756659334461284756482337867831 65271201909145648566923460348610454326648213393607260249141273724587006606315588 17488152092096282925409171536436789259036001133053054882046652138414695194151160 94330572703657595919530921861173819326117931051185480744623799627495673518857527 24891227938183011949129833673362440656643086021394946395224737190702179860943702 77053921717629317675238467481846766940513200056812714526356082778577134275778960 91736371787214684409012249534301465495853710507922796892589235420199561121290219 60864034418159813629774771309960518707211349999998372978049951059731732816096318 59502445945534690830264252230825334468503526193118817101000313783875288658753320 83814206171776691473035982534904287554687311595628638823537875937519577818577805 321712268066130019278766111959092164201989
Enter the second floating point decimal: 2.718281828459045235360287471352662497757247093699959574966967627724076630353547 59457138217852516642742746639193200305992181741359662904357290033429526059563073 81323286279434907632338298807531952510190115738341879307021540891499348841675092 44761460668082264800168477411853742345442437107539077744992069551702761838606261 33138458300075204493382656029760673711320070932870912744374704723069697720931014 16928368190255151086574637721112523897844250569536967707854499699679468644549059 87931636889230098793127736178215424999229576351482208269895193668033182528869398 49646510582093923982948879332036250944311730123819706841614039701983767932068328 23764648042953118023287825098194558153017567173613320698112509961818815930416903 51598888519345807273866738589422879228499892086805825749279610484198444363463244 96848756023362482704197862320900216099023530436994184914631409343173814364054625 31520961836908887070167683964243781405927145635490613031072085103837505101157477 041718986106873969655212671546889570350354
The resulting number is: 5.859874482048838473822930854632165381954416493075065395941912220031893036639756 59319941700386728349540961447844528536656891125820617962580462569370338907674818 84164313298820118687934745037021501814009760026451635966356002176255831179542924 10032662577227913367091937760464196672090650501146337994133343276289768444921849 50626610392171487418791827566197462970356072065923967626421356861484392915082175 11258940893912747006105559582286343223962181620722448452478299327175142163406587 12822864827413110742257569851577865655872662372877154665119930858735362389813101 26700432299723241658187346813883017884824930180632421367970122480560902207847289 15501019830167802432300074632496023648871277681536117590701745382018377051707123 12462922937505620903641509899383397935711242086804198727329561543930177179559563 56351201968897173534462114551725550567527056630113002015631723127049103022807946 15335168008685578543203666499148068960614457231119251854609961041357082919735282 363431254173003988933978783505981734552343

Nifty, eh? I’m proud. I’ll be working on multiplication next. I think I’ll start with a schoolboy approach, O(N^2) and then try my hand at Fast Fouriers to try and get O(Nlog(N)). Actually, I’ve read that optimized approaches can get O(Nlog(log(N))), but of course that doesn’t necessarily mean a performance improvement.

In other news, I’m working out every morning now. I’ve only been to the gym three times and I’m already seeing some good strength improvements. I’ll be in amazing shape by the end of summer (and I have an exercise buddy to make sure I’m up at 6 every morning!)

Here’s the code for interested parties. I’m sorry it’s not formatted well, sooner or later I’ll get some css to work here to try and make it more readable.


ipfloat &ipfloat::operator +=(const ipfloat &rhs){
int c = 0, carry = 0, i;
char* thisMan = new char[strlen(getMan())+1];
char* rhsMan = new char[strlen(rhs.getMan()) + 1];
strcpy(thisMan, getMan());
strcpy(rhsMan, rhs.getMan());
//following code "aligns" decimals for addition.
int thisBefore, thisAfter, rhsBefore, rhsAfter;
thisBefore = (exp>=0) ? exp + 1 : 1;
thisAfter = strlen(man) - exp - 1;
rhsBefore = (rhs.getExp()>=0) ? rhs.getExp() + 1 : 1;
rhsAfter = strlen(rhs.getMan()) - rhs.getExp() - 1;
if(getExp()<0)
{
free(thisMan);
thisMan = (char*)malloc(sizeof(char)*(strlen(getMan()) - getExp() +1));
for(c = 0; c<-getExp(); c++)
thisMan[c] = '0';
thisMan[c] = '';
strcat(thisMan, getMan());
}
if(rhs.getExp()<0)
{
free(rhsMan);
rhsMan = (char*)malloc(sizeof(char)*(strlen(rhs.getMan()) - rhs.getExp()+1));
for(c = 0; c<-rhs.getExp(); c++)
rhsMan[c] = '0';
rhsMan[c] = '';
strcat(rhsMan, rhs.getMan());
}
if(thisBefore>rhsBefore)
{
char* tmp = new char[strlen(rhsMan) + 1];
strcpy(tmp, rhsMan);
free(rhsMan);
rhsMan = (char*)malloc(sizeof(char)*(strlen(rhs.getMan()) + (thisBefore - rhsBefore) + 1));
for(c = 0; c<(thisBefore-rhsBefore); c++)
rhsMan[c] = '0';
rhsMan[c] = '';
strcat(rhsMan, tmp);
}
else if(rhsBefore>thisBefore)
{
char* tmp = new char[strlen(thisMan) + 1];
strcpy(tmp, thisMan);
free(thisMan);
thisMan = (char*)malloc(sizeof(char)*(strlen(getMan()) + (rhsBefore - thisBefore) + 1));
for(c = 0; c<(rhsBefore-thisBefore); c++)
thisMan[c] = '0';
thisMan[c] = '';
strcat(thisMan, tmp);
}
if(thisAfter>rhsAfter)
{
char* tmp = new char[strlen(rhsMan) + 1];
strcpy(tmp, rhsMan);
free(rhsMan);
rhsMan = (char*)malloc(sizeof(char)*(strlen(tmp) + (thisAfter-rhsAfter) + 1));
strcpy(rhsMan, tmp);
for(c=strlen(tmp); c<strlen(tmp) + (thisAfter-rhsAfter); c++)
rhsMan[c] = '0';
rhsMan[c] = '';
}
else if(rhsAfter>thisAfter)
{
char* tmp = new char[strlen(thisMan) + 1];
strcpy(tmp, thisMan);
free(thisMan);
thisMan = (char*)malloc(sizeof(char)*(strlen(tmp) + (rhsAfter-thisAfter) + 1));
strcpy(thisMan, tmp);
for(c=strlen(tmp); c<strlen(tmp) + (rhsAfter-thisAfter); c++)
thisMan[c] = '0';
thisMan[c] = '';
}
//actually add
free(man);
man = (char*)malloc(sizeof(char)*(strlen(thisMan) + 1));
for(i = strlen(thisMan); i>=0; i--)
{
man[i] = (char)((((int)(thisMan[i] + rhsMan[i] - 2*'0')) + carry)%10) + '0';
carry = (thisMan[i] + rhsMan[i] - 2*'0' + carry >9)?1:0;
}
man[strlen(thisMan)] = '';
exp = (exp>rhs.getExp())? exp : rhs.getExp();
if(carry==1)
{
char* tmp = new char[strlen(man) + 1];
strcpy(tmp, man);
man = (char*)malloc(sizeof(char)*(strlen(tmp)+2));
man[0] = '1';
man[1] = '';
strcat(man, tmp);
exp++;
}
return *this;
}

Ich bin sehr begeistert diesen Abend!
I am very excited this evening! (Google: I am very enthusiastic about this evening!)