# bitRAKE Studio

Fragments of discovery littered with nuggets of innovation

## Sunday, January 27, 2013

### Still alive and coding...

http://azspcs.net/Contest/Factorials

## Wednesday, March 09, 2011

### Automata Captcha Idea

## Saturday, December 15, 2007

### Collatz Conjecture

For me the most fasinating thing about the Collatz Conjecture is how it so blantantly points to a deficiency in mathematics. It seems incredibly obvious that it is true. The problem lies in a way to say that no loops are created excluding one - a limited understanding of process dynamics.

Recently, I've changed the problem to eliminate the split condition - there is no reason to divide even numbers by two. Without the split we have a simplified algorithm, but it must work with larger numbers. This doesn't seem like an intuitive step.

1. y <= 1+Shr[Xor[x,x-1],1]

2. if x=y then step 5

3. x <= 3x + y

4. goto step 1

5. number is a power of two

The first step calculates the value of least set bit. Instead of dividing by two, one is scaled up to match the bit which would make (x) odd if it were down scaled. Only when a single bit is set does the algorithm end (step 2). (y) can be tracked progressively instead of looking at the complete representation of (x) as step 3 always clears the least set bit (or more). Of course, I've coded this in x86:

; check Collatz Conjecture on multi-percision numberTry a really big number - like 2^131072 + 3

;

; carry flag set on array overflow

; carry flag clear on pass

; (otherwise it loops forever: not likely, but hasn't been proven)

;

; NOTE: array should be twice the size of number to test - too large

; is not a problem as only active bits are operated on.

CollatzArrayQ:

label .arr at esp+4+32 ; BigInt

label .len at esp+8+32 ; length (dwords)

pushad

mov ebx,[.arr]

mov eax,[.len]

mov edx,1

mov esi,ebx

lea ebp,[ebx+eax*4]

; address past number in EDI (active end marker)

; (need at least one zero dword on end!)

.z: dec eax

test dword [ebx+eax*4],-1

je .z

lea edi,[ebx+eax*4+4]

cmp edi,ebp

je .over

; advance to lowest set bit

.0: test [esi],edx

jne .1

.0a: rol edx,1

jnc .0 ; HINT: taken

add esi,4

cmp esi,ebp ; end

cmovnc esi,ebx ; reset

jmp .0

; ESI[ECX] is first set bit, multiply by three and add ESI[ECX]

; all (virtual) lower bits are zero.

.1:

; test if buffer is == ESI[ECX] then done!

cmp [esi],edx

jne .kx ; HINT: taken

; if EDI==ESI+4 or (ESI+4==EBP && EDI==EBX)

; (faster than testing all of buffer)

mov ecx,edi

lea eax,[esi+4]

cmp edi,ebx

cmove ecx,ebp

cmp eax,ecx

je .x

.kx:

push edx

push esi

.2:

mov eax,3

mov ecx,edx

mul dword [esi]

add eax,ecx

adc edx,0

mov [esi],eax

add esi,4

cmp esi,ebp ; end

cmovnc esi,ebx ; reset

cmp esi,edi

jne .2

test edx,edx

je .5

cmp edi,[esp]

je .over

mov [edi],edx

add edi,4

cmp edi,ebp ; end

cmovnc edi,ebx ; reset

.5: pop esi

pop edx

jmp .0a ; we just cleared that bit

.x: popad

clc

retn 8

.over: popad

stc

retn 8

TestBuffer rb 32*1024 ; zero bytesWhy is this important? The algorithm is no longer concerned with value of (x) except for the exit condition - the same operation takes place each loop. It is sufficient to show that (y) -> (x) for all (x), and the conjecture is true. The multiplication by three is irrelavant because the addition propells the least set bit at a rate greater than the constant multiple!

mov dword [TestBuffer],3

mov dword [TestBuffer+16*1024],1

push 32*1024/4 ; L1 cache size (c:

push TestBuffer1

call CollatzArrayQ

; 3829ms on my machine

(c:

**Update:**

Status of the 3x+1 class record progress as of: Dec 13, 2007. Intervals areBasically, a trillion per day, per Ghz.

indicated in blocks of 20,000,000,000,000 (20 E+12 or 20 trillion numbers).

Calculation of a single block takes approximately 20 days of (idle) time on a

Pentium 1000 MHz.

Naturally, I'm currious how my routine compares:

Currently, they are working on 7 * 2^53 block of numbers. I ran a test of my algorithm for 2^24 numbers (in that block range) which took 38781ms. Which means it is roughly 25 times

**slower**. Their algorithm is tuned for this size and uses large data structures (to avoid processing numbers). I might be able to double the speed of my algorithm, but confirming ranges of numbers is not what it's designed for.

## Sunday, November 11, 2007

### Slices of Weekend Pi

There is also a bit of irony in irrational numbers. Mathematics was first designed to track finances and military forces in an attempt to add great stablity. Imagine the surprise when even the simiplest of systems could produce absolute chaos and uncertainty.

Pi(π) is the most famous irrational number and countless lifetimes have been spent in it's study and popularization. Yesterday I spent a couple hours devising an x86 version of the BBP algorithm:

; NOTE: This isn't the fastest way to compute pi approximations.(FASM Syntax)

;

; TESTING STATUS:

; confirmed valid for all input [0,10000]

;

; digit time (1.6Ghz Dothan)

; ------------------------------------------

; 10^4 16 ms

; 10^5 219 ms

; 10^6 2860 ms 6C65D566

; 10^7 33938 ms

; 10^8 407828 ms

;

; Pi hex digit extraction:

;3.

; 243F6 A8885 A308D 31319 8A2E0 37073 44A40 93822

; 299F3 1D008 2EFA9 8EC4E 6C894 52821 E638D 01377

; 16^EBP MOD ECX=8k+z

; Special cases:

; EBP=0, return 1

; ECX=1, return 0

;

; EDX is return value

mpow: xor edx,edx

cmp ecx,1

je .x

bsr ebx,ebp

mov edx,1

jne .1

.x: retn

.0: mul eax

div ecx

.1: bt ebp,ebx

mov eax,16

jnc .2

mul edx

div ecx

.2: dec ebx

mov eax, edx

jns .0

retn

series:

xor edi,edi ; fraction

.1: call mpow ; 16^EBP mod ECX

xor eax,eax

div ecx ; EDX:0 / 8k+m

add ecx,8 ; 8k+m, k[0,EBP]

add edi,eax

dec ebp

jns .1

mov ebp,10000000h

.2: mov eax,ebp

xor edx,edx

div ecx

add ecx,8

shr ebp,4

cmp ecx,ebp

lea edi,[edi+eax]

jna .2

retn

PiHex:

pushad

mov ebp,[esp+36]

mov ecx,1

call series

lea esi,[edi*4]

mov ebp,[esp+36]

mov ecx,4

call series

sub esi,edi

sub esi,edi

mov ebp,[esp+36]

mov ecx,5

call series

sub esi,edi

mov ebp,[esp+36]

mov ecx,6

call series

sub esi,edi

mov [esp+28],esi

popad

retn 4

invoke PiHexDigit, 1000000

## Tuesday, October 30, 2007

### Crossing Segment Intersections

It didn't even seem that difficult, really. My first two tries were completely from my gut. One was a brute force stab with sorting in one dimension: usually these attempts just help me get a feel for the problem. With 5000 lines that means over 12 million intersection test - sorting and early exit dropped it down to about 4 million. Certainly within range of brute forcing on modern processors.

The intersection test itself seemed to be problem. So, I used a little topology to devise a test based strictly on triangle area, given the connected graph of the four points. Got a different result, but it was close enough to the last one to give a sense of accomplishment. (It's really fast and merits further research.)

Where could the problem be? I searched the web for algorithms - seems line sweeping is all the rage. Quickly, I plugged a couple different intersection tests into my first attempt. Two more different answers!

Have to put the problem aside for now...

## Friday, October 19, 2007

### An Improvement to Random

I created a macro in MASM to ease direct access to the random array:

mov ebp, PRNG_CA_Pasqualoni_StateWidth / 4Here the random data is stored in EAX, and EBP indexes into the array. If using a register to index into the array seems like a bad idea then try to write a function with less overhead than load/storing a register. The intent is to churn through a massive number of random integers.

_0: PRNG_CA_Pasqualoni eax, ebp

; (do somthing with random data)

jXX _0 ; until exit condition reached

The features of MASM have been used to encapsulate the routine within an object module. Although the code is not lengthy it demonstrates coding techniques which make code reusable and easy to understand. The interface is described in a concise way within the include file - there is no need to look at the code to use the functions. Following the defined interface allows the code to operate in a transparent way. Within the assembly file all the nuances are explained making modification in the future less error prone. The file is small enough to fit on a couple screens of text and be quickly comprehended.

(Below is my MASM conversion.)