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 number
Try 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 8TestBuffer rb 32*1024 ; zero bytes
Why 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.)