Friday, 13 October 2017

KISS

-Safety, speed, usability, etc. all generally speaking originate from the same source, the system doing as little as possible in the simplest and understandable way possible while achieving the goal of doing a lot of the same thing it's good at.

-Transparency: the system must be transparent and open. It must not do anything behind the users back. The user must be able to view all that is going on in their system and understand it.

-Non-redundancy: in UI there ought to be only one way of doing things so as not to confuse the user or waste their time by making them learn many ways of doing the same thing.

-Limited abstraction: working close to the hardware while maintaining a level of readability and functionality. Unnecessary abstraction leads to waste of time, less speed, worse security and confusion.

-Stay out of the way of the user, never popup anything unless requested, never run anything in the background unless specifically requested.

Visit Russia, find subs, observe Militsiya, get a cold (after two years of health).
WM design ideas:

Applications are allowed to bring themselves on top only once (when they are started within certain time). After that the user must ALT+TAB to bring them on top.

OS/Compiler stuff:

1) Compile a static busybox and copy the files to a HDD image (after making the partition):
mount -o offset=32256 sda.bin tmp
2) mknod a few devices
3) Compile linux kernel
Tools these days...
4) qemu-system-x86_64 -m 512 -kernel bzImage -append "root=/dev/sda1" -enable-kvm -hda sda.bin

5) Modify tcc so it can be compiled into static binary, improve the assembler by adding syscall, use statically linked uClibc for startup code (plan: write the startup code entirely from scratch).

x86_64-asm.h: DEF_ASM_OP0(syscall, 0x0f05)
tccpp.c: get rid of ldexp and make your own d = d*((1<<((int)(exp_val-frac_bits))));
tccelf.c: get rid of all things related to libtcc1.a and crt?.o
tcc.c: add missing (dummy) function void __assert_fail (const char *assertion, const char *file, unsigned int line, const char *function) { abort(); }

tcc -DCONFIG_TCC_STATIC -o tcc.o -c tcc.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o libtcc.o -c libtcc.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o tccpp.o -c tccpp.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o tccgen.o -c tccgen.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o tccelf.o -c tccelf.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o tccasm.o -c tccasm.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o tccrun.o -c tccrun.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o x86_64-gen.o -c x86_64-gen.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o i386-asm.o -c i386-asm.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o libtcc1.o -c libtcc1.c -DTCC_TARGET_X86_64 -I./include -static
tcc -DCONFIG_TCC_STATIC -o alloca86_64.o -c alloca86_64.S -DTCC_TARGET_X86_64 -I./include -static

gcc -nostdlib -static -o tcc libtcc1.o alloca86_64.o tcc.o libtcc.o tccpp.o tccgen.o tccelf.o tccasm.o tccrun.o x86_64-gen.o i386-asm.o ../uClibc-0.9.33/lib/crt1.o ../uClibc-0.9.33/lib/crti.o ../uClibc-0.9.33/lib/crtn.o ../uClibc-0.9.33/lib/libc.a
strip tcc

6) End up with standalone 290 kB static C-compiler/assembler.

Boots in a second.

void* syscall(void* syscall_number, void* param1, void* param2, void* param3) {
  __asm__ __volatile__(
    "mov %0, %%rax\n"
    "mov %1, %%rdi\n"
    "mov %2, %%rsi\n"
    "mov %3, %%rdx\n"
    "syscall\n"
    :
    : "g" (syscall_number), "g" (param1), "g" (param2), "g" (param3)
    : "rax", "rdi", "rsi", "rdx");
}

typedef unsigned long int uintptr;
typedef long int intptr;

static intptr write(int fd, void const* data, uintptr nbytes) {
  syscall((void*)1, (void*)(intptr)fd, (void*)data, (void*)nbytes);
}

int main(int argc, char* argv[]) {
    write(1, "Hello, World!\n", 15);

    return 0;
}

_start() {
  __asm__ __volatile__(
    "call main\n"
    "mov $60, %rax\n"
    "mov 0, %rdi\n"
    "syscall\n");
}

7) Compile hello world on a few MB linux installation on a 64 bit CPU.


8) Port my fluid/Navier-Stokes simulator into javascript while you're at it, eliminate need for fft by short relaxation method and simply write del, del2 and other vector and matrix operations into for loops. Much faster with SDL, but pretty much realtime in javascript as well. Also runs fine in my cellphone.


<script type="text/javascript">
window.onload = function() {
  var  t = document.getElementById("a").getContext("2d");
  var  g = t.createImageData(128, 128);
  var  N = 128;
  var  f = new Array(N*N);
  var  p = new Array(N*N);
  var  u = new Array(N*N);
  var  v = new Array(N*N);
  var ux = new Array(N*N);
  var vx = new Array(N*N);
  var uy = new Array(N*N);
  var vy = new Array(N*N);
  var u2 = new Array(N*N);
  var v2 = new Array(N*N);
  var us = new Array(N*N);
  var vs = new Array(N*N);
  var px = new Array(N*N);
  var py = new Array(N*N);

  function r(tframe) {
    var a, b, x, y;

    for(y=-10; y<10; y++)
      for(x=-10; x<10; x++)
        u[0.75*N+x+(N/2+y)*N] = 0.15;

    for(y=1; y<N-1; y++)
      for(x=1; x<N-1; x++) {
        ux[x+y*N] = 0.50*(u[(x+1)+y*N] -                u[(x-1)+y*N]);
        vx[x+y*N] = 0.50*(v[(x+1)+y*N] -                v[(x-1)+y*N]);
        uy[x+y*N] = 0.50*(u[x+(y+1)*N] -                u[x+(y-1)*N]);
        vy[x+y*N] = 0.50*(v[x+(y+1)*N] -                v[x+(y-1)*N]);
        u2[x+y*N] = 0.25*(u[(x+1)+y*N] - 2.0*u[x+y*N] + u[(x-1)+y*N]);
        v2[x+y*N] = 0.25*(v[(x+1)+y*N] - 2.0*v[x+y*N] + v[(x-1)+y*N]);
        u2[x+y*N]+= 0.25*(u[x+(y+1)*N] - 2.0*u[x+y*N] + u[x+(y-1)*N]);
        v2[x+y*N]+= 0.25*(v[x+(y+1)*N] - 2.0*v[x+y*N] + v[x+(y-1)*N]);
      }

    for(x=0; x<N*N; x++) {
      us[x] = u[x] + u[x]*ux[x] + v[x]*uy[x] + u2[x]/20.0 - px[x]/20.0 + 0.00000;
      vs[x] = v[x] + u[x]*vx[x] + v[x]*vy[x] + v2[x]/20.0 - py[x]/20.0 - 0.00000;
    }

    for(y=1; y<N-1; y++)
      for(x=1; x<N-1; x++) {
        f[x+y*N] = 0.5*(us[(x+1)+y*N] - us[(x-1)+y*N] + vs[x+(y+1)*N] - vs[x+(y-1)*N]);
        p[x+y*N] = 0.25*(p[(x+1)+y*N] + p[x+(y+1)*N] + p[(x-1)+y*N] + p[x+(y-1)*N] - f[x+y*N]);
    }

    for(y=1; y<N-1; y++)
      for(x=1; x<N-1; x++) {
        px[x+y*N] = 0.5*(p[(x+1)+y*N] - p[(x-1)+y*N]);
        py[x+y*N] = 0.5*(p[x+(y+1)*N] - p[x+(y-1)*N]);
         u[x+y*N] = us[x+y*N] - px[x+y*N];
         v[x+y*N] = vs[x+y*N] - py[x+y*N];
      }

    window.requestAnimationFrame(r);
    for(x=0; x<N*N; x++) {
      a = 4*x;
      b = 1500*Math.sqrt(u[x]*u[x] + v[x]*v[x]);
      if(b>255) b = 255;
      g.data[a] = b;
      g.data[a+1] = b;
      g.data[a+2] = b;
      g.data[a+3] = 255;
    }
    t.putImageData(g, 0, 0);
  }
  for(x=0; x<128*128; x++) {
     f[x] = 0;
     p[x] = 0;
     u[x] = 0;
     v[x] = 0;
    ux[x] = 0;
    uy[x] = 0;
    vx[x] = 0;
    vy[x] = 0;
    u2[x] = 0;
    v2[x] = 0;
    us[x] = 0;
    vs[x] = 0;
    px[x] = 0;
    py[x] = 0;
  }
  window.requestAnimationFrame(r);

};
</script>
<canvas id="a" width="128" height="128" style=width:12cm;height:12cm></canvas>

Monday, 2 October 2017

Belonging, purpose, transcendence and storytelling...

Navier-Stokes, good luck making the code shorter...


N  = 192; dt = 0.25; p = zeros(N, N);
u = zeros(N, N); v = zeros(N, N); ustar = zeros(N, N); vstar = zeros(N, N);
k = pi*[0:(N/2-1) (-N/2):(-1)]; [x y]  = meshgrid(k, k); ds = -(x.^2 + y.^2);
ds(1,1) = 1; px = 0.0; py = 0.0; gx = 0.0; gy = 0.0;
for t = 0:1000
    % constant velocity zone
    u(N/2-10:N/2+10, N/2-10:N/2+10) = 0.2;

    % solve intermediate velocity U*
    [ux uy] = gradient(u);
    [vx vy] = gradient(v);
    ustar = u + (u.*ux + v.*uy + del2(u)/20 - px/20 + gy)*dt;
    vstar = v + (u.*vx + v.*vy + del2(v)/20 - py/20 + gx)*dt;

    % solve Poisson equation: del2(p) = f
    fhat = fft2(divergence(ustar, vstar));
    p = N^2*real(ifft2(fhat./ds));

    % enforce del(U) = 0
    [px py] = gradient(p);
    u = ustar - px*dt;
    v = vstar - py*dt;

    cla; surface(sqrt(u.^2 + v.^2), 'edgecolor', 'none'); drawnow;
end

Espoo is full of furry animals.
Just a basic wave equation...


u  = zeros(192, 192);
du = zeros(192, 192);
[x y] = meshgrid(linspace(-1, 1, 192), linspace(-1, 1, 192));
for t = 0:0.002:0.4
    u = u + exp(-1000*((x-0.7*sin(7*t)).^2+(y-0.7*sin(11*t)-0.2).^2));
    u = u + 0.5*exp(-1000*((x+0.7*sin(5*t)).^2+(y+0.7).^2))*sin(3*31*t);

    du = du + del2(u);   
    u = u + du;
       
    cla; imagesc(u); drawnow;
end

...