├── 493.f ├── README.md ├── alg_surf.nim ├── archive.nim ├── bodies ├── 3body ├── 8star-rotation ├── antimatter ├── armageddon ├── atom ├── awesome ├── binary ├── binaryStars ├── dance10 ├── entropy-universe ├── fourellipses ├── hypnosis ├── illusion ├── its-a-trap ├── kaleidoscope ├── kevin ├── massive-squirrel-battle ├── planets ├── planets-elliptical ├── planetsparty ├── pluto ├── quad-stars ├── renegade ├── soap-opera ├── spiral ├── suninterference ├── twin-binaries ├── uniform100 ├── uniform3 └── uniform8 ├── body.nim ├── btree.nim ├── btreeDisk.nim ├── btreedx ├── Makefile ├── btreedx.cpp ├── btreedx.h ├── btreedx.nim ├── btreedx.o └── btreedx_port.nim ├── cifar ├── cifar.nim ├── mat.nim └── nn.nim ├── cl ├── dc.cl ├── dc_zvm.cl ├── mandelbrot.cl ├── sh.cl ├── voronoi.cl └── vsl.cl ├── color_map.nim ├── complex_inline.nim ├── convexhull ├── convexhull_ptr.nim ├── convexhull_ref.nim ├── waterman.nim └── wp.nim ├── ctm.nim ├── dc.nim ├── f128.nim ├── f128cpp.nim ├── f16.nim ├── fastsin.nim ├── fir.nim ├── fizzbuzz.nim ├── formants.nim ├── formants ├── dr_wav.c ├── dr_wav.h ├── dr_wav.nim ├── dr_wav.o ├── formants ├── formants.nim ├── lpc.nim ├── nim_fftw3.nim ├── poly_roots_laguerre.nim ├── sig_wind.nim └── test.wav ├── fortran ├── 493.f ├── for_desc.nim ├── libalgebra.f90 ├── libalgebra.nim ├── makefile ├── n493.nim ├── param.f ├── param.nim ├── paramf90.f90 ├── quadmath.nim └── rpoly.f90 ├── fourinline.nim ├── gltextures.nim ├── high_precision ├── c128.nim ├── complex.h ├── complex_std.nim ├── complex_wrap.nim ├── f128.nim ├── f128cpp.nim ├── f16.nim ├── hpa.nim ├── i128.nim ├── int128.cpp ├── mandel_mpfr.nim ├── mpfr.nim └── mpfr_test.c ├── hpa.nim ├── hypercube.nim ├── i128.nim ├── implicit_funcs.nim ├── line_art.nim ├── llvm ├── Makefile ├── expression.nim ├── expression_llvm ├── expression_llvm.nim ├── funcs.cpp ├── funcs.nim ├── libfuncs.so ├── llvm.h ├── llvm.nim └── rand_expr.nim ├── lpc.nim ├── lsystem.l ├── lsystem.nim ├── lzma.nim ├── mandel.nim ├── mandel32.nim ├── mandel_par.nim ├── mandel_weave.nim ├── mesh.nim ├── mnist ├── README.md ├── data.zip ├── mat.nim ├── mnist.nim └── nn.nim ├── mpfr.nim ├── nim_fft3w.nim ├── nim_fftw3.nim ├── par.nim ├── pi.nim ├── pig_ocl.nim ├── poly ├── common.nim ├── flag.nim ├── johnson.nim ├── parser.nim ├── polyhedron.nim ├── transform.nim └── vertex.nim ├── poly_32 ├── common.nim ├── flag.nim ├── johnson.nim ├── par.nim ├── parser.nim ├── polyhedron.nim ├── transform.nim ├── ui_gl.nim └── vertex.nim ├── poly_json_parser.nim ├── poly_roots_duran_kerner.nim ├── polygonizer.nim ├── polygonizer_am.nim ├── polygonizerc.nim ├── polyhedron.nim ├── quadmath.nim ├── quaternion.nim ├── queen.nim ├── roots_poly.nim ├── rpoly.nim ├── sh.nim ├── sig_wind.nim ├── sparse_mtx.nim ├── stereogram ├── images │ ├── depthMaps │ │ ├── 3gear.jpg │ │ ├── b52.jpg │ │ ├── ball.jpg │ │ ├── bee2.jpg │ │ ├── bio.jpg │ │ ├── borrodepth.png │ │ ├── bottle.jpg │ │ ├── cube2.jpg │ │ ├── cupdepth.jpg │ │ ├── deer.jpg │ │ ├── dino.jpg │ │ ├── doldemo.jpg │ │ ├── drg.jpg │ │ ├── earth1.jpg │ │ ├── gitara.jpg │ │ ├── globe.jpg │ │ ├── izba3.jpg │ │ ├── kruh.jpg │ │ ├── panak.jpg │ │ ├── plane.jpg │ │ ├── retazka.jpg │ │ ├── shark.jpg │ │ ├── smsun.jpg │ │ ├── socha2.jpg │ │ ├── star.jpg │ │ ├── stolicka.jpg │ │ ├── struna.jpg │ │ ├── teapot.jpg │ │ ├── telo2.jpg │ │ ├── valec.jpg │ │ └── ventil.jpg │ └── texturePatterns │ │ ├── fial.jpg │ │ ├── rand4.jpg │ │ ├── rand7.jpg │ │ ├── random2.jpg │ │ ├── tree.jpg │ │ ├── txt1.png │ │ ├── txt3.png │ │ ├── txt4.png │ │ ├── txt5.jpg │ │ ├── txt6.jpg │ │ ├── txt7.jpg │ │ ├── zelena.jpg │ │ └── zelena2.jpg └── stereogram.nim ├── sudoku.nim ├── swbinimg ├── symmetric_icons.nim ├── test.vsl ├── uniform_polyhedra.nim ├── v2v.nim ├── vec.nim ├── vec3.nim ├── voronoi.nim ├── voronoi_weave.nim ├── vsl-samples ├── 3 voice rythm-01.vsl ├── 3 voice rythm.vsl ├── _flwr01.vsl ├── alien march.vsl ├── aus flower 01.vsl ├── aus flower exp.vsl ├── bal_phi.vsl ├── bell.vsl ├── bolw_bal_phi.vsl ├── bowl-mix.vsl ├── bowl.vsl ├── cadence.vsl ├── default-02.vsl ├── default.vsl ├── mediterraneum.vsl ├── pacman.vsl ├── r3.vsl └── waka-waka.vsl ├── vsl.nim ├── vsl_compiler.nim ├── vsl_scanner.nim ├── waterman ├── cpp │ ├── Face.cpp │ ├── Face.h │ ├── FaceList.cpp │ ├── FaceList.h │ ├── HalfEdge.cpp │ ├── HalfEdge.h │ ├── Makefile │ ├── Point3d.cpp │ ├── Point3d.h │ ├── QuickHull3D.cpp │ ├── QuickHull3D.h │ ├── Vector3d.cpp │ ├── Vector3d.h │ ├── Vertex.cpp │ ├── Vertex.h │ ├── VertexList.cpp │ ├── VertexList.h │ ├── Waterman.cpp │ ├── Waterman.h │ ├── main.cpp │ ├── nim_interface.cpp │ └── rust_interface.cpp ├── waterman.nim └── waterman_poly.nim ├── wav ├── dr_wav.c ├── dr_wav.h ├── dr_wav.nim └── test.wav ├── yacl.nim ├── zlib.nim ├── zm.nim ├── zmviewer.nim └── zvm.nim /README.md: -------------------------------------------------------------------------------- 1 | # nim 2 | nim language developments, 3 | compile with: nim c --experimental --threads:on -d:release -d:danger 4 | -------------------------------------------------------------------------------- /bodies/3body: -------------------------------------------------------------------------------- 1 | 3 2 | 1.25e11 3 | 0.000e00 0.000e00 0.0500e04 0.000e00 5.974e24 earth.gif 4 | 0.000e00 4.500e10 3.000e04 0.000e00 1.989e30 sun.gif 5 | 0.000e00 -4.500e10 -3.000e04 0.000e00 1.989e30 sun.gif 6 | 7 | -------------------------------------------------------------------------------- /bodies/8star-rotation: -------------------------------------------------------------------------------- 1 | 8 2 | 22e10 3 | 6.85e10 0 0 39e3 5e29 pluto.gif 4 | 8.125e10 0 0 -31e3 5e29 pluto.gif 5 | 11.875e10 0 0 -11e3 5e29 pluto.gif 6 | 13.125e10 0 0 -81e3 5e29 pluto.gif 7 | -6.85e10 0 0 -39e3 5e29 pluto.gif 8 | -8.125e10 0 0 31e3 5e29 pluto.gif 9 | -11.875e10 0 0 11e3 5e29 pluto.gif 10 | -13.125e10 0 0 81e3 5e29 pluto.gif 11 | 12 | Creator of the universe: Eric Schlossberg 13 | -------------------------------------------------------------------------------- /bodies/antimatter: -------------------------------------------------------------------------------- 1 | 3 2 | 2.50e+11 3 | -1.5000e+11 0.0000e+00 0.0000e+00 0.0000e+00 8.0000e+30 sun.gif 4 | 1.5000e+11 0.0000e+00 0.0000e+00 0.0000e+00 8.0000e+30 sun.gif 5 | 0.0000e+11 0.0000e+00 0.0000e+00 0.0000e+00 -2.0000e+30 uranus.gif 6 | 7 | 8 | Creator of the universe: Kevin Henneck 9 | 10 | The bodies do not move on account of uranus, which has negative mass. 11 | -------------------------------------------------------------------------------- /bodies/armageddon: -------------------------------------------------------------------------------- 1 | 50 2 | 7.00E+11 3 | 0.000e00 0.000e00 0.000e00 0.000e00 1.9890e30 sun.gif 4 | 8.500e11 4.000e11 -0.900e04 -0.500e04 1.9990e30 blackhole.gif 5 | 5.790e10 0.000e00 0.000e00 4.790e04 3.3020e23 mercury.gif 6 | 1.082e11 0.000e00 0.000e00 3.500e04 4.8690e24 venus.gif 7 | 1.496e11 0.000e00 0.000e00 2.980e04 5.9740e24 earth.gif 8 | 2.279e11 0.000e00 0.000e00 2.410e04 6.4190e23 mars.gif 9 | 7.783e11 0.000e00 0.000e00 1.307e04 1.8986e27 jupiter.gif 10 | -2.58E+11 -2.33E+11 1.31E+04 -1.45E+04 7.000E+12 asteroid.gif 11 | 3.38E+11 7.31E+10 -4.12E+03 1.90E+04 8.390E+12 asteroid.gif 12 | -3.19E+11 1.39E+11 -7.80E+03 -1.79E+04 7.430E+12 asteroid.gif 13 | 1.87E+11 2.93E+11 -1.64E+04 1.05E+04 3.310E+12 asteroid.gif 14 | -7.13E+10 -3.40E+11 1.91E+04 -4.00E+03 9.970E+12 asteroid.gif 15 | 3.33E+11 7.59E+10 -4.33E+03 1.90E+04 1.690E+12 asteroid.gif 16 | -1.63E+11 -3.03E+11 1.72E+04 -9.22E+03 1.100E+12 asteroid.gif 17 | -7.32E+09 3.47E+11 -1.95E+04 -4.12E+02 6.350E+12 asteroid.gif 18 | -9.53E+10 -3.31E+11 1.87E+04 -5.39E+03 5.240E+12 asteroid.gif 19 | -3.48E+11 -3.91E+10 2.18E+03 -1.94E+04 3.600E+12 asteroid.gif 20 | -6.54E+09 -3.45E+11 1.95E+04 -3.70E+02 7.430E+11 asteroid.gif 21 | -1.41E+11 3.14E+11 -1.78E+04 -7.99E+03 2.570E+12 asteroid.gif 22 | 1.50E+11 -3.15E+11 1.76E+04 8.37E+03 3.890E+12 asteroid.gif 23 | 2.95E+11 -1.82E+11 1.02E+04 1.66E+04 1.850E+12 asteroid.gif 24 | -1.44E+11 -3.17E+11 1.78E+04 -8.05E+03 7.340E+12 asteroid.gif 25 | -2.18E+10 3.43E+11 -1.95E+04 -1.24E+03 7.160E+11 asteroid.gif 26 | -3.31E+11 1.05E+11 -5.89E+03 -1.86E+04 1.840E+12 asteroid.gif 27 | -4.34E+09 -3.49E+11 1.95E+04 -2.42E+02 6.290E+12 asteroid.gif 28 | 8.70E+10 3.36E+11 -1.89E+04 4.89E+03 5.840E+12 asteroid.gif 29 | -2.50E+11 2.40E+11 -1.35E+04 -1.41E+04 3.310E+12 asteroid.gif 30 | 1.91E+11 -2.86E+11 1.62E+04 1.08E+04 4.820E+12 asteroid.gif 31 | 2.53E+11 -2.34E+11 1.32E+04 1.43E+04 7.250E+12 asteroid.gif 32 | 5.00E+10 3.40E+11 -1.93E+04 2.83E+03 5.270E+12 asteroid.gif 33 | 1.52E+11 3.14E+11 -1.75E+04 8.50E+03 5.630E+12 asteroid.gif 34 | -1.63E+11 -3.05E+11 1.72E+04 -9.18E+03 9.660E+12 asteroid.gif 35 | -3.17E+11 -1.48E+11 8.25E+03 -1.77E+04 3.290E+12 asteroid.gif 36 | 3.63E+10 3.47E+11 -1.94E+04 2.03E+03 4.840E+12 asteroid.gif 37 | 2.97E+11 -1.81E+11 1.02E+04 1.66E+04 8.290E+12 asteroid.gif 38 | -3.47E+11 -7.09E+09 3.98E+02 -1.95E+04 5.240E+12 asteroid.gif 39 | 3.13E+11 1.56E+11 -8.69E+03 1.74E+04 2.380E+12 asteroid.gif 40 | -3.26E+11 1.09E+11 -6.19E+03 -1.85E+04 4.420E+11 asteroid.gif 41 | 2.52E+11 -2.32E+11 1.32E+04 1.43E+04 3.890E+11 asteroid.gif 42 | 4.07E+10 3.44E+11 -1.94E+04 2.29E+03 9.980E+12 asteroid.gif 43 | 3.60E+10 3.47E+11 -1.94E+04 2.01E+03 9.950E+12 asteroid.gif 44 | 2.61E+11 -2.32E+11 1.29E+04 1.46E+04 2.470E+12 asteroid.gif 45 | -3.44E+11 1.07E+10 -6.04E+02 -1.95E+04 8.260E+12 asteroid.gif 46 | 3.06E+11 -1.64E+11 9.22E+03 1.72E+04 3.530E+12 asteroid.gif 47 | 1.91E+11 -2.90E+11 1.63E+04 1.07E+04 7.440E+12 asteroid.gif 48 | 3.04E+11 1.60E+11 -9.08E+03 1.72E+04 4.640E+12 asteroid.gif 49 | 2.15E+11 2.71E+11 -1.53E+04 1.21E+04 9.480E+12 asteroid.gif 50 | 3.41E+10 3.43E+11 -1.94E+04 1.92E+03 7.660E+11 asteroid.gif 51 | -2.84E+11 -2.02E+11 1.13E+04 -1.59E+04 5.630E+12 asteroid.gif 52 | -3.22E+11 1.26E+11 -7.08E+03 -1.82E+04 6.760E+12 asteroid.gif 53 | 3.39E+11 8.17E+10 -4.56E+03 1.89E+04 1.760E+12 asteroid.gif 54 | -1.97E+11 -2.82E+11 1.60E+04 -1.12E+04 4.020E+12 asteroid.gif 55 | 56 | Creator of universe: Dzhelil Rufat, COS 126, Spring 2004 57 | 58 | This file can be used to simulate the entrance of a black hole into 59 | the Solar System. Special effects can be observed such as the deformation of 60 | the asteroid field, the swing shot effect of Jupiter around the 61 | black hole and a collision between Jupiter and the Sun. Earth survives the 62 | entrance of the black hole but its orbit becomes extrememly eccentric. 63 | 64 | -------------------------------------------------------------------------------- /bodies/atom: -------------------------------------------------------------------------------- 1 | 9 2 | 2.50e11 3 | 1.496e11 0.000e00 0.000e00 2.980e04 5.974e24 electron.png 4 | -1.496e11 0.000e00 0.000e00 2.980e04 5.974e24 electron.png 5 | 0.000e00 0.000e00 0.000e00 0.000e00 1.989e30 nucleus.png 6 | -1.082e11 0.000e00 0.000e00 3.500e04 4.869e24 electron.png 7 | 1.082e11 0.000e00 0.000e00 3.500e04 4.869e24 electron.png 8 | 2.279e11 0.000e00 0.000e00 2.410e04 6.419e23 electron.png 9 | -2.279e11 0.000e00 0.000e00 2.410e04 6.419e23 electron.png 10 | 0.000e00 2.279e11 2.410e04 0.000e00 6.419e23 electron.png 11 | 0.000e00 -2.279e11 -2.410e04 0.000e00 6.419e23 electron.png 12 | 13 | Creator of universe: Christina Chang, COS 126, Fall 2008 14 | 15 | I created the Princetonium universe (by combining the Plutonium symbol 16 | (I thought it appropriate given the astronomical context) with the atomic 17 | structure of Oxygen). Princetonium has 8 protons(+), 8 neutrons(n), and 18 | 8 electrons(-). While the atomic universe depicted in my animation is only 19 | a rough visual of the atom, I drew the parallel between electron orbitals 20 | and planetary orbits. 21 | -------------------------------------------------------------------------------- /bodies/binary: -------------------------------------------------------------------------------- 1 | 2 2 | 5.0e10 3 | 0.0e00 4.5e10 1.0e04 0.0e00 1.5e30 sun.gif 4 | 0.0e00 -4.5e10 -1.0e04 0.0e00 1.5e30 sun.gif 5 | 6 | -------------------------------------------------------------------------------- /bodies/binaryStars: -------------------------------------------------------------------------------- 1 | 5 2 | 3.00e11 3 | -0.900e11 0.000e00 0.000e00 -2.000e04 1.989e30 sun.gif 4 | 0.900e11 0.000e00 0.000e00 2.000e04 1.989e30 sun.gif 5 | -1.300e11 0.000e00 0.000e00 -8.000e04 5.974e23 earth.gif 6 | 1.300e11 0.000e00 0.000e00 8.000e04 5.974e23 earth.gif 7 | -1.600e11 0.000e00 0.000e00 5.500e04 3.302e20 mercury.gif 8 | -------------------------------------------------------------------------------- /bodies/dance10: -------------------------------------------------------------------------------- 1 | 10 2 | 12.000e11 3 | 1.000e11 0 0 129132.5 1e32 sun.gif 4 | -1.000e11 0 0 -129132.5 1e32 sun.gif 5 | 2.828e11 2.828e11 100000 -100000 1e26 earth.gif 6 | 2.828e11 -2.828e11 -100000 -100000 1e26 earth.gif 7 | -2.828e11 -2.828e11 -100000 100000 1e26 earth.gif 8 | -2.828e11 2.828e11 100000 100000 1e26 earth.gif 9 | 9.000e11 0 0 97500 1e24 mars.gif 10 | -9.000e11 0 0 -97500 1e24 mars.gif 11 | 0.000 9e11 -97500 0 1e24 mars.gif 12 | 0.000 -9e11 97500 0 1e24 mars.gif 13 | 14 | Creator of universe: Rohan Kapadia, COS 126, Spring 2004 15 | 10 dancing bodies 16 | -------------------------------------------------------------------------------- /bodies/entropy-universe: -------------------------------------------------------------------------------- 1 | 17 2 | 2.50e11 3 | 2.20e11 0.000e00 0.000e00 2.000e04 5.974e24 earth.gif 4 | 0.000e00 2.20e11 -2.000e004 0.000e00 6.419e23 mars.gif 5 | -2.20e11 0.000e00 0.000e00 -2.000e04 3.302e23 mercury.gif 6 | 0.000e00 0.000e00 0.000e00 0.000e00 1.989e30 sun.gif 7 | 0.000e00 -2.20e11 2.000e04 0.000e00 4.869e24 venus.gif 8 | 9 | 2.20e11 2.20e11 0.000e00 2.000e04 5.974e24 earth.gif 10 | -2.20e11 2.20e11 -2.000e004 0.000e00 6.419e23 mars.gif 11 | -2.20e11 -2.20e11 0.000e00 -2.000e04 3.302e23 mercury.gif 12 | 2.20e11 -2.20e11 2.000e04 0.000e00 4.869e24 venus.gif 13 | 14 | 1.10e11 1.10e11 0.000e00 2.000e04 5.974e24 earth.gif 15 | -1.10e11 1.10e11 -2.000e004 0.000e00 6.419e23 mars.gif 16 | -1.10e11 -1.10e11 0.000e00 -2.000e04 3.302e23 mercury.gif 17 | 1.10e11 -1.10e11 2.000e04 0.000e00 4.869e24 venus.gif 18 | 19 | 1.10e11 0.000e00 0.000e00 2.000e04 5.974e24 earth.gif 20 | 0.000e00 1.10e11 -2.000e004 0.000e00 6.419e23 mars.gif 21 | -1.10e11 0.000e00 0.000e00 -2.000e04 3.302e23 mercury.gif 22 | 0.000e00 -1.10e11 2.000e04 0.000e00 4.869e24 venus.gif 23 | 24 | Creator of universe: Zachary Kreider, COS 126, Fall 2008 25 | 26 | 27 | Starts with the four sets of the four planets from 28 | planets.txt (earth, mars, mercury, and venus) arranged in squares 29 | around the sun. The squares rotate around the sun while the distance 30 | from each point on the square to the sun oscillates. Over time, due 31 | to the different masses of each planet in each square, the squares 32 | deteriorate into a chaotic group of particles tracing elliptical 33 | revolutions about the sun at different distances and periods. I 34 | called my universe "Entropy Universe" because of this gradual breakdown 35 | into chaos. 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /bodies/fourellipses: -------------------------------------------------------------------------------- 1 | 69 2 | 2.50e11 3 | 1.50e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 4 | -1.50e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 5 | 0.00e00 -1.50e11 2.29e04 0.00e00 7.45e19 pluto.gif 6 | 0.00e00 1.50e11 -2.29e04 0.00e00 7.45e19 pluto.gif 7 | 1.48e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 8 | -1.48e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 9 | 0.00e00 -1.48e11 2.29e04 0.00e00 7.45e19 pluto.gif 10 | 0.00e00 1.48e11 -2.29e04 0.00e00 7.45e19 pluto.gif 11 | 1.46e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 12 | -1.46e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 13 | 0.00e00 -1.46e11 2.29e04 0.00e00 7.45e19 pluto.gif 14 | 0.00e00 1.46e11 -2.29e04 0.00e00 7.45e19 pluto.gif 15 | 1.44e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 16 | -1.44e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 17 | 0.00e00 -1.44e11 2.29e04 0.00e00 7.45e19 pluto.gif 18 | 0.00e00 1.44e11 -2.29e04 0.00e00 7.45e19 pluto.gif 19 | 1.42e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 20 | -1.42e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 21 | 0.00e00 -1.42e11 2.29e04 0.00e00 7.45e19 pluto.gif 22 | 0.00e00 1.42e11 -2.29e04 0.00e00 7.45e19 pluto.gif 23 | 1.40e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 24 | -1.40e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 25 | 0.00e00 -1.40e11 2.29e04 0.00e00 7.45e19 pluto.gif 26 | 0.00e00 1.40e11 -2.29e04 0.00e00 7.45e19 pluto.gif 27 | 1.38e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 28 | -1.38e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 29 | 0.00e00 -1.38e11 2.29e04 0.00e00 7.45e19 pluto.gif 30 | 0.00e00 1.38e11 -2.29e04 0.00e00 7.45e19 pluto.gif 31 | 1.36e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 32 | -1.36e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 33 | 0.00e00 -1.36e11 2.29e04 0.00e00 7.45e19 pluto.gif 34 | 0.00e00 1.36e11 -2.29e04 0.00e00 7.45e19 pluto.gif 35 | 1.34e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 36 | -1.34e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 37 | 0.00e00 -1.34e11 2.29e04 0.00e00 7.45e19 pluto.gif 38 | 0.00e00 1.34e11 -2.29e04 0.00e00 7.45e19 pluto.gif 39 | 1.32e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 40 | -1.32e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 41 | 0.00e00 -1.32e11 2.29e04 0.00e00 7.45e19 pluto.gif 42 | 0.00e00 1.32e11 -2.29e04 0.00e00 7.45e19 pluto.gif 43 | 1.30e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 44 | -1.30e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 45 | 0.00e00 -1.30e11 2.29e04 0.00e00 7.45e19 pluto.gif 46 | 0.00e00 1.30e11 -2.29e04 0.00e00 7.45e19 pluto.gif 47 | 1.28e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 48 | -1.28e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 49 | 0.00e00 -1.28e11 2.29e04 0.00e00 7.45e19 pluto.gif 50 | 0.00e00 1.28e11 -2.29e04 0.00e00 7.45e19 pluto.gif 51 | 1.26e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 52 | -1.26e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 53 | 0.00e00 -1.26e11 2.29e04 0.00e00 7.45e19 pluto.gif 54 | 0.00e00 1.26e11 -2.29e04 0.00e00 7.45e19 pluto.gif 55 | 1.24e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 56 | -1.24e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 57 | 0.00e00 -1.24e11 2.29e04 0.00e00 7.45e19 pluto.gif 58 | 0.00e00 1.24e11 -2.29e04 0.00e00 7.45e19 pluto.gif 59 | 1.22e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 60 | -1.22e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 61 | 0.00e00 -1.22e11 2.29e04 0.00e00 7.45e19 pluto.gif 62 | 0.00e00 1.22e11 -2.29e04 0.00e00 7.45e19 pluto.gif 63 | 1.20e11 0.00e00 0.00e00 -2.29e04 7.45e19 pluto.gif 64 | -1.20e11 0.00e00 0.00e00 2.29e04 7.45e19 pluto.gif 65 | 0.00e00 -1.20e11 2.29e04 0.00e00 7.45e19 pluto.gif 66 | 0.00e00 1.20e11 -2.29e04 0.00e00 7.45e19 pluto.gif 67 | 1.49e11 1.49e11 1.00e04 3.29e04 5.40e20 sun.gif 68 | -1.49e11 -1.49e11 -1.00e04 -3.29e04 5.40e20 sun.gif 69 | 1.49e11 1.00e11 1.00e04 2.286e4 5.50e20 venus.gif 70 | -1.49e11 -1.00e11 -1.00e04 -2.286e4 5.50e20 venus.gif 71 | 0.000e00 0.000e00 0.000e00 0.000e00 5.974e30 earth.gif 72 | 73 | Universe created by: Chris Thompson 2010 Spring 2007 74 | -------------------------------------------------------------------------------- /bodies/hypnosis: -------------------------------------------------------------------------------- 1 | 5 2 | 2.50e11 3 | 0.000e00 0.000e00 0.000e00 0.000e00 1.989e30 sun.gif 4 | 1.496e11 0.000e00 0.000e00 2.980e04 5.974e24 earth.gif 5 | -1.496e11 0.000e00 0.000e00 2.980e04 5.974e24 earth.gif 6 | 0.000e00 1.496e11 2.980e04 0.000e00 5.974e24 earth.gif 7 | 0.000e00 -1.496e11 2.980e04 0.000e00 5.974e24 earth.gif 8 | 9 | Creator of universe: Katie Smith, COS 126, Spring 2004 10 | 11 | I find this arrangement rather hypnotic. 12 | -------------------------------------------------------------------------------- /bodies/illusion: -------------------------------------------------------------------------------- 1 | 16 2 | 2.50e11 3 | 1.000e11 0.000e00 0.000e00 -2.52664e05 1.000e32 earth.gif 4 | -1.000e11 0.000e00 0.000e00 2.52664e05 1.000e32 mars.gif 5 | 0.000e00 1.000e11 2.52664e05 0.000e00 1.000e32 mercury.gif 6 | 0.000e00 -1.000e11 -2.52664e05 0.000e00 1.000e32 venus.gif 7 | 1.000e07 0.000e00 0.000e00 0.000e00 1.000e01 sun.gif 8 | 0.000e00 1.000e07 0.000e00 0.000e00 1.000e01 sun.gif 9 | -1.000e07 0.000e00 0.000e00 0.000e00 1.000e01 sun.gif 10 | 0.000e00 -1.000e07 0.000e00 0.000e00 1.000e01 sun.gif 11 | 1.000e13 1.000e13 -1.000e06 -1.000e06 2.000e32 blackhole.gif 12 | 1.000e13 -1.000e13 -1.000e06 1.000e06 2.000e32 blackhole.gif 13 | -1.000e13 1.000e13 1.000e06 -1.000e06 2.000e32 blackhole.gif 14 | -1.000e13 -1.000e13 1.000e06 1.000e06 2.000e32 blackhole.gif 15 | 0.000e00 1.414e13 0.000e00 -1.414e06 2.000e22 blackhole.gif 16 | 0.000e00 -1.414e13 0.000e00 1.414e06 2.000e22 blackhole.gif 17 | -1.414e13 0.000e00 1.414e06 0.000e00 2.000e22 blackhole.gif 18 | 1.414e13 0.000e00 -1.414e06 0.000e00 2.000e22 blackhole.gif 19 | 20 | 21 | // This is a good test case for seeing if the positions are being updated 22 | // properly. 23 | // If there is one big force loop (i.e., program updates position 24 | // before computing all the new forces) the bodies will fly off 25 | // very quickly. 26 | // If everything is correct, the scenario will play out (four suns 27 | // emerge from center, suns and planets dance around until suns exit, 28 | // planets dance a bit more until black holes come and everyone 29 | // flies off the screen). 30 | 31 | Michael Gelbart Fall 06: 32 | 33 | This universe is a bit of an optical illusion at first. It starts out with 34 | 4 planets supposedly orbiting the sun, but they are actually just orbiting 35 | around their common center of mass, located exactly where the "sun" is. To 36 | determine these orbits I calculated what velocities they must have based on 37 | the radius of orbit and their masses. I did this by equating centripetal 38 | force to the total gravitational force (the sum of all the "inward-pulling" 39 | components of the forces from the other 3 planets - the perpendicular 40 | components cancel out). 41 | 42 | After a short amount of time, the sun "splits" into four, as there are 43 | actually 4 suns on top of each other, each one with a small initial velocity 44 | in a different direction. These "suns" are all set to negligible mass (10 kg) 45 | so that they do not apply any significant gravitational force on each other 46 | or on the planets (if they were heavy they would all immediately fly out 47 | at the beginning). However, because we know a = F/m and F is proportional to 48 | mass, the acceleration (which then defines velocity and position) is 49 | independent of the mass of the suns and therefore they are affected by the 50 | gravitational pull of other planets as if they were very heavy. 51 | 52 | Another interesting thing about this universe is the behaviour of the 4 suns 53 | after they leave the center of the planetary orbits. Each one flies outward, 54 | circles around a planet, comes back into the middle, and pauses for a short 55 | time. This process repeats a few times until finally the suns fly out of the 56 | screen. The entire behaviour just described is very interesting to observe, 57 | and, at least to me, is not at all what I would have expected. The pause 58 | is especially counter-intuitive as one would think it would require very 59 | precise conditions. 60 | 61 | Shortly after the suns depart, eight black holes (which are not really 62 | black holes as they actually have masses equal to the that of the planets) 63 | fly through the screen at a high speed (they start very far away), 64 | causing the planets to pull inward and then fly out towards the corners. 65 | In conclusion, the main point of interest in the universe is the initial 66 | optical illusion, but the rest of it looks quite neat, too. 67 | -------------------------------------------------------------------------------- /bodies/its-a-trap: -------------------------------------------------------------------------------- 1 | 7 2 | 2.50e11 3 | 0.0e00 -1.75e11 2.5e04 0.0e00 5.974e24 death_star.gif 4 | 0.000e00 0.000e00 0.000e00 0.000e00 1.989e30 endor.gif 5 | -1.496e11 1.496e11 3.0e03 -2.60e04 5.974e23 rebel_cruiser.gif 6 | 1.0e12 0.000e00 -7.000e04 0.000e00 1.989e3 its_a_trap.gif 7 | 1.2e11 -1.25e12 0.00e00 7.000e04 1.989e3 star_destroyer.gif 8 | 1.6e11 -1.2e12 0.00e00 7.000e04 1.989e3 star_destroyer.gif 9 | 2.0e11 -1.25e12 0.00e00 7.000e04 1.989e3 star_destroyer.gif 10 | 11 | 12 | Creator of universe: Jim Valcourt, COS 126, Fall 2008 13 | 14 | My universe recreates the rebel alliance's attack on the second Death 15 | Star from Return of the Jedi. First, the rebel cruiser rounds Endor 16 | to attack the Death Star. When the cruiser pulls within attacking 17 | range, it becomes clear that the shield is not down. Han had failed 18 | them. "It's a trap!" the good admiral exclaims, and the rebels beat 19 | a hasty retreat with star destroyers hot on their heels. 20 | 21 | -------------------------------------------------------------------------------- /bodies/kaleidoscope: -------------------------------------------------------------------------------- 1 | 25 2 | 2.50e11 3 | 0.000e00 0.000e00 0.000e00 0.000e00 1.989e30 sun.gif 4 | 1.500e11 0.000e00 0.000e00 1.030e04 7.350e22 mars.gif 5 | -1.500e11 0.000e00 0.000e00 -1.030e04 7.350e22 mars.gif 6 | 0.000e00 1.500e11 -1.030e04 0.000e00 7.350e22 mars.gif 7 | 0.000e00 -1.500e11 1.030e04 0.000e00 7.350e22 mars.gif 8 | 1.061e11 1.061e11 -7.283e03 7.283e03 7.350e22 mars.gif 9 | -1.061e11 -1.061e11 7.283e03 -7.283e03 7.350e22 mars.gif 10 | 1.061e11 -1.061e11 7.283e03 7.283e03 7.350e22 mars.gif 11 | -1.061e11 1.061e11 -7.283e03 -7.283e03 7.350e22 mars.gif 12 | 1.000e11 0.000e00 0.000e00 -2.030e04 7.350e22 earth.gif 13 | -1.000e11 0.000e00 0.000e00 2.030e04 7.350e22 earth.gif 14 | 0.000e00 1.0000e11 2.030e04 0.000e00 7.350e22 earth.gif 15 | 0.000e00 -1.000e11 -2.030e04 0.000e00 7.350e22 earth.gif 16 | 7.070e10 7.070e10 1.4350e4 -1.435e04 7.350e22 earth.gif 17 | -7.070e10 -7.070e10 -1.4350e4 1.435e04 7.350e22 earth.gif 18 | 7.070e10 -7.070e10 -1.4350e4 -1.435e04 7.350e22 earth.gif 19 | -7.070e10 7.070e10 1.4350e4 1.435e04 7.350e22 earth.gif 20 | 2.279e11 0.000e00 0.000e00 2.410e04 6.419e23 jupiter.gif 21 | 0.000e00 2.279e11 -2.410e04 0.000e00 6.419e23 jupiter.gif 22 | -2.279e11 0.000e00 0.000e00 -2.410e04 6.419e23 jupiter.gif 23 | 0.000e00 -2.279e11 2.410e04 0.000e00 6.419e23 jupiter.gif 24 | 1.610e11 1.610e11 1.700e04 -1.700e04 6.419e23 jupiter.gif 25 | -1.610e11 -1.610e11 -1.700e04 1.700e04 6.419e23 jupiter.gif 26 | -1.610e11 1.610e11 1.700e04 1.700e04 6.419e23 jupiter.gif 27 | 1.610e11 -1.610e11 -1.700e04 -1.700e04 6.419e23 jupiter.gif 28 | -------------------------------------------------------------------------------- /bodies/kevin: -------------------------------------------------------------------------------- 1 | 9 2 | 2.5e11 3 | 0.0e00 0.000e00 0.00e00 0.00e00 2e32 kevin.gif 4 | 6.25e10 0.000e00 0.00e00 5.66e05 6e24 mercury.gif 5 | -6.25e10 0.000e00 0.00e00 -5.66e05 6e24 earth.gif 6 | 0 6.250e10 -5.66e05 0.00e00 6e24 mars.gif 7 | 0 -6.250e10 5.66e05 0.00e00 6e24 venus.gif 8 | 1.414e11 1.414e11 1.20e05 -1.20e05 2e24 sun.gif 9 | -1.414e11 1.414e11 1.20e05 1.20e05 2e24 sun.gif 10 | 1.414e11 -1.414e11 -1.20e05 -1.20e05 2e24 sun.gif 11 | -1.414e11 -1.414e11 -1.20e05 1.20e05 2e24 sun.gif 12 | 13 | Creator of the universe: Alex Kandabarow 14 | 15 | Kevin Wayne is the center of the solar system. There are 8 planets, 4 rotating 16 | in elliptical orbits in one direction, and 4 others rotating in a different 17 | direction with even more elliptical orbits. I used the formulas 18 | V(orb)=sqrt(G*mass(sun)/r) and V(esc)=sqrt(2*G*mass(sun)/r) and found a value in 19 | between to create an elliptical orbit. 20 | -------------------------------------------------------------------------------- /bodies/planets: -------------------------------------------------------------------------------- 1 | 5 2 | 2.50e+11 3 | 1.4960e+11 0.0000e+00 0.0000e+00 2.9800e+04 5.9740e+24 earth.gif 4 | 2.2790e+11 0.0000e+00 0.0000e+00 2.4100e+04 6.4190e+23 mars.gif 5 | 5.7900e+10 0.0000e+00 0.0000e+00 4.7900e+04 3.3020e+23 mercury.gif 6 | 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 1.9890e+30 sun.gif 7 | 1.0820e+11 0.0000e+00 0.0000e+00 3.5000e+04 4.8690e+24 venus.gif 8 | -------------------------------------------------------------------------------- /bodies/planets-elliptical: -------------------------------------------------------------------------------- 1 | 5 2 | 2.50e11 3 | 0.000e00 0.000e00 0.000e00 0.000e00 1.989e30 sun.gif 4 | 5.790e10 0.000e00 0.000e00 2.395e04 3.302e23 mercury.gif 5 | 1.082e11 0.000e00 0.000e00 1.750e04 4.869e24 venus.gif 6 | 1.496e11 0.000e00 0.000e00 1.490e04 5.974e24 earth.gif 7 | 2.279e11 0.000e00 0.000e00 1.205e04 6.419e23 mars.gif 8 | -------------------------------------------------------------------------------- /bodies/planetsparty: -------------------------------------------------------------------------------- 1 | 10 2 | 2.50e11 3 | 0.0e00 0.000e00 0.00e00 0.00e00 2e32 sun.gif 4 | 6.25e10 0.000e00 0.00e00 5.66e05 6e24 mercury.gif 5 | -6.25e10 0.000e00 0.00e00 -5.66e05 6e24 earth.gif 6 | 0 6.250e10 -5.66e05 0.00e00 6e24 mars.gif 7 | 0 -6.250e10 5.66e05 0.00e00 6e24 venus.gif 8 | 2.828e11 2.828e11 100000 -100000 1e26 jupiter.gif 9 | 2.828e11 -2.828e11 -100000 -100000 1e26 saturn.gif 10 | -2.828e11 -2.828e11 -100000 100000 1e26 uranus.gif 11 | -2.828e11 2.828e11 100000 100000 1e26 neptune.gif 12 | -1.828e11 1.828e11 100000 100000 1e16 pluto.gif 13 | 14 | 15 | Creator of this universe: Mary Fan 16 | 17 | The inner planets party, with those giant gas outer planets 18 | joining in the fun every so often. Pluto, who is not a real planet, 19 | awkwardly does his own little thing. 20 | -------------------------------------------------------------------------------- /bodies/pluto: -------------------------------------------------------------------------------- 1 | 13 2 | 7.50e12 3 | 1.496e11 0.000e00 0.000e00 2.980e04 5.974e24 earth.gif 4 | 6.579e12 0.000e00 3.410e05 0.000e00 1.3055e22 pluto.gif 5 | 5.790e10 0.000e00 0.000e00 4.790e04 3.302e23 mercury.gif 6 | 0.000e00 0.000e00 0.000e00 0.000e00 1.989e30 sun.gif 7 | 1.082e11 0.000e00 0.000e00 3.500e04 4.869e24 venus.gif 8 | 3.59e13 0.000e00 -1.641e06 0.000e00 6.419e33 pluto.gif 9 | 2.279e11 0.000e00 0.000e00 2.410e04 6.419e23 mars.gif 10 | 7.779e11 0.000e00 0.000e00 1.307e04 1.899e27 jupiter.gif 11 | 1.427e12 0.000e00 0.000e00 9.639e03 5.6846e26 saturn.gif 12 | 5.503e12 0.000e00 0.000e00 5.432e03 1.0243e26 neptune.gif 13 | 2.870e12 0.000e00 0.000e00 6.795e03 8.683e25 uranus.gif 14 | 0.000e00 -9.99e12 0.000e00 1.999e06 1.000000 goodbye.gif 15 | 0.000e00 -3.50e13 0.000e00 1.999e06 1.000000 imback.gif 16 | 17 | Creator of the Universe: Andrew Dixon 18 | 19 | Pluto's vengeance 20 | 21 | -------------------------------------------------------------------------------- /bodies/quad-stars: -------------------------------------------------------------------------------- 1 | 8 2 | 3.00e11 3 | -0.900e11 0.000e00 0.000e00 -2.000e04 1.989e30 sun.gif 4 | 0.900e11 0.000e00 0.000e00 2.000e04 1.989e30 sun.gif 5 | -1.300e11 0.000e00 0.000e00 -8.000e04 5.974e23 earth.gif 6 | 1.300e11 0.000e00 0.000e00 8.000e04 5.974e23 earth.gif 7 | 0.000e00 -1.900e11 0.000e00 -2.000e04 1.989e29 sun.gif 8 | 0.000e00 1.900e11 0.000e00 2.000e04 1.989e29 sun.gif 9 | 0.000e00 -0.300e11 0.000e00 -8.000e04 5.974e27 earth.gif 10 | 0.000e00 0.300e11 0.000e00 8.000e04 5.974e27 earth.gif 11 | 12 | Creator of universe: John Son, COS 126, Spring 2004 13 | -------------------------------------------------------------------------------- /bodies/renegade: -------------------------------------------------------------------------------- 1 | 6 2 | 2.50e11 3 | 0.000e00 0.000e00 0.000e00 0.000e00 2e32 sun.gif 4 | 2e11 0.000e00 0.000e00 2.582e05 6e24 earth.gif 5 | -2e11 0.000e00 0.000e00 -2.582e05 6e24 earth.gif 6 | 0e0 2e11 -2.582e05 0.000e00 6e24 earth.gif 7 | 0e0 -2e11 2.582e05 0.000e00 6e24 earth.gif 8 | 2.0001e11 0.000e00 0e0 -2.646e05 4.869e14 pluto.gif 9 | 10 | Creator of universe: David Cohen-Tanugi, COS 126, Fall 2006 11 | 12 | I created a symmetric/conformist universe with four earths rotating in 13 | uniform circular motion (using a=mv2/r) and a renegade/daredevil planet 14 | that runs in the opposite direction teases the earths by barely touching 15 | them. Will it ever lose at its own rebel game, by coming too close to an 16 | earth and get trapped in its orbit? -------------------------------------------------------------------------------- /bodies/soap-opera: -------------------------------------------------------------------------------- 1 | 4 2 | 3.00e11 3 | 0.000e00 1.1547e11 -3.6524e4 0.0000 3.300e30 sun.gif 4 | 1.000e11 -5.7735e10 1.8262e4 3.1631e4 3.300e30 mars.gif 5 | -1.000e11 -5.7735e10 1.8262e4 -3.1631e4 3.300e30 venus.gif 6 | -2.500e11 0.0000e00 0.000e00 6.000e04 3.302e20 mercury.gif 7 | 8 | Creator of universe: Katie Smith, COS 126, Spring 2004 9 | 10 | The story: Everyone knows about the love triangle involving Mars, Sun, and Venus, for both 11 | Mars and Sun are in love with the beautiful Venus. Mercury secretly loves Venus as well, 12 | but does not dare to get involved with anything that would anger Sun, a powerful 13 | politician, or Mars, a dangerous gang leader. Sun loses interest in Venus, and it looks 14 | for a while that Mars and Venus will be married. Mercury, nearly hopeless, drifts off 15 | alone. But when Mars proposes to Venus, she realizes that she does not love him, and 16 | finds a clever way to convince him that he does not want her, so they part ways very 17 | quickly. Venus now thinks she is alone, but Mercury is there to follow, and pursue his 18 | love... 19 | -------------------------------------------------------------------------------- /bodies/spiral: -------------------------------------------------------------------------------- 1 | 17 2 | 2.50e11 3 | 0.0 0.0 0.0 0.0 1.989e30 sun.gif 4 | 0.0 16.0e10 2.0e4 -2.0e4 5.974e24 mars.gif 5 | -16.0e10 0.0 2.0e4 2.0e4 5.974e24 mars.gif 6 | 0.0 -16.0e10 -2.0e4 2.0e4 5.974e24 mars.gif 7 | 16.0e10 0.0 -2.0e4 -2.0e4 5.974e24 mars.gif 8 | 6.0e10 6.0e10 -5.0e3 5.0e4 5.974e27 venus.gif 9 | -6.0e10 6.0e10 -5.0e4 -5.0e3 5.974e27 venus.gif 10 | -6.0e10 -6.0e10 5.0e3 -5.0e4 5.974e27 venus.gif 11 | 6.0e10 -6.0e10 5.0e4 5.0e3 5.974e27 venus.gif 12 | 18.0e10 18.0e10 -1.0e4 1.0e2 6.419e23 mars.gif 13 | -18.0e10 18.0e10 1.0e2 -1.0e4 6.419e23 mars.gif 14 | -18.0e10 -18.0e10 1.0e4 1.0e2 6.419e23 mars.gif 15 | 18.0e10 -18.0e10 -1.0e2 1.0e4 6.419e23 mars.gif 16 | 0.0 23.0e10 1.0e4 -1.0e4 5.974e23 mars.gif 17 | -23.0e10 0.0 1.0e4 1.0e4 5.974e23 mars.gif 18 | 0.0 -23.0e10 -1.0e4 1.0e4 5.974e23 mars.gif 19 | 23.0e10 0.0 -1.0e4 -1.0e4 5.974e23 mars.gif 20 | -------------------------------------------------------------------------------- /bodies/suninterference: -------------------------------------------------------------------------------- 1 | 5 2 | 2.50e+11 3 | -1.5000e+11 0.0000e+00 0.0000e+00 -3.0000e+04 6.0000e+30 sun.gif 4 | 1.5000e+11 0.0000e+00 0.0000e+00 3.0000e+04 6.0000e+30 sun.gif 5 | 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 3.0000e+30 sun.gif 6 | -1.2000e+11 0.0000e+00 0.0000e+00 -1.5400e+05 6.0000e+26 pluto.gif 7 | 1.2000e+11 0.0000e+00 0.0000e+00 1.5400e+05 6.0000e+26 pluto.gif 8 | 9 | Creator of the Universe: Kevin Henneck 10 | 11 | -------------------------------------------------------------------------------- /bodies/twin-binaries: -------------------------------------------------------------------------------- 1 | 4 2 | 5.000e10 3 | -3.500e10 0.000e09 0.000e00 1.400e03 3.000e28 mercury.gif 4 | -1.000e10 0.000e09 0.000e00 1.400e04 3.000e28 venus.gif 5 | 1.000e10 0.000e09 0.000e00 -1.400e04 3.000e28 earth.gif 6 | 3.500e10 0.000e09 0.000e00 -1.400e03 3.000e28 mars.gif 7 | 8 | Creator of universe: David Costanzo, COS 126, Fall 2003 9 | 10 | -------------------------------------------------------------------------------- /bodies/uniform3: -------------------------------------------------------------------------------- 1 | 3 2 | 5.0E8 3 | 5.0E8 0.0 0.0 -248.22332833139765 7.999999999999999E23 earth.gif 4 | -2.4999999999999988E8 4.3301270189221936E8 214.96770814691595 124.11166416569877 7.999999999999999E23 earth.gif 5 | -2.500000000000002E8 -4.3301270189221925E8 -214.9677081469159 124.11166416569894 7.999999999999999E23 earth.gif 6 | 7 | Creator of the Universe: Colin Ponce, COS126, spring 2007. 8 | System of 3 bodies in uniform circular motion. 9 | 10 | Universe generated by 11 | 12 | % java UniformCircMotion 13 | 14 | -------------------------------------------------------------------------------- /bodies/uniform8: -------------------------------------------------------------------------------- 1 | 8 2 | 5.0E8 3 | 5.0E8 0.0 0.0 -273.5577101396693 1.9999999999999998E23 earth.gif 4 | 3.5355339059327376E8 3.5355339059327376E8 193.43451188562415 -193.43451188562415 1.9999999999999998E23 earth.gif 5 | 3.061616997868383E-8 5.0E8 273.5577101396693 -1.6750578705231275E-14 1.9999999999999998E23 earth.gif 6 | -3.5355339059327376E8 3.5355339059327376E8 193.43451188562418 193.43451188562415 1.9999999999999998E23 earth.gif 7 | -5.0E8 6.123233995736766E-8 3.350115741046255E-14 273.5577101396693 1.9999999999999998E23 earth.gif 8 | -3.535533905932738E8 -3.5355339059327376E8 -193.43451188562415 193.4345118856242 1.9999999999999998E23 earth.gif 9 | -9.184850993605149E-8 -5.0E8 -273.5577101396693 5.025173611569382E-14 1.9999999999999998E23 earth.gif 10 | 3.535533905932737E8 -3.535533905932738E8 -193.4345118856242 -193.4345118856241 1.9999999999999998E23 earth.gif 11 | 12 | 13 | Creator of the Universe: Colin Ponce, COS126, spring 2007. 14 | System of 8 bodies in uniform circular motion. 15 | 16 | Universe generated by 17 | 18 | % java UniformCircMotion 19 | -------------------------------------------------------------------------------- /btreedx/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @g++ -c btreedx.cpp 3 | @nim cpp -r -d:release -d:danger btreedx.nim 4 | -------------------------------------------------------------------------------- /btreedx/btreedx.nim: -------------------------------------------------------------------------------- 1 | # btreedx nim wrapper 2 | # g++ -c btreedx.cpp 3 | # nim cpp -d:release -d:danger btreedx_wrapper.nim 4 | 5 | {.passL:"btreedx.o".} 6 | {.passC:"-std=c++11".} 7 | 8 | # ffi 9 | type BtreeDX*{.importcpp:"BtreeDX", header:"btreedx.h".}= object 10 | proc newBtreeDX*() : ptr BtreeDX {.importcpp:"new BtreeDX()", header: "btreedx.h".} 11 | proc open*(bt:ptr BtreeDX, fileName:cstring) : bool {.importcpp:"#.open(@)", header: "btreedx.h".} 12 | proc close*(bt:ptr BtreeDX) : bool {.importcpp:"#.close()", header: "btreedx.h".} 13 | proc create*(bt:ptr BtreeDX, fileName:cstring, keylen:cint, unique:cint=1, overlay:cint=1) : bool {.importcpp:"#.create(@)", header: "btreedx.h".} 14 | proc add*(bt:ptr BtreeDX, key:cstring, recno:cint) : bool {.importcpp:"#.add(@)", header: "btreedx.h".} 15 | proc find*(bt:ptr BtreeDX, key:cstring, recno:var cint) : bool {.importcpp:"#.find(@)", header: "btreedx.h".} 16 | proc findEQ*(bt:ptr BtreeDX, key:cstring, recno:var cint) : bool {.importcpp:"#.findEQ(@)", header: "btreedx.h".} 17 | proc next*(bt:ptr BtreeDX, key:cstring, recno:var cint) : bool {.importcpp:"#.next(@)", header: "btreedx.h".} 18 | proc eraseEQ*(bt:ptr BtreeDX, key:cstring) : bool {.importcpp:"#.eraseEQ(@)", header: "btreedx.h".} 19 | proc eraseMatch*(bt:ptr BtreeDX, key:cstring) : bool {.importcpp:"#.eraseMatch(@)", header: "btreedx.h".} 20 | 21 | # wrapper 22 | proc open*(bt:ptr BtreeDX, fileName:string) : bool = bt.open(fileName.cstring) 23 | 24 | proc create*(bt:ptr BtreeDX, fileName:string, keylen:int, unique:int=1, overlay:int=1) : bool= 25 | bt.create(fileName.cstring, keylen.cint, unique.cint, overlay.cint) 26 | 27 | proc add*(bt:ptr BtreeDX, key:string, recno:int) : bool = bt.add(key.cstring, recno.cint) 28 | 29 | proc find*(bt:ptr BtreeDX, key:string, recno:var int) : bool = 30 | var ci = recno.cint 31 | result=bt.find(key.cstring, ci) 32 | recno=ci.int 33 | 34 | proc next*(bt:ptr BtreeDX, key:var string, recno:var int) : bool = 35 | var ci = recno.cint 36 | result=bt.next(key.cstring, ci) 37 | recno=ci.int 38 | 39 | # test 40 | 41 | when isMainModule: 42 | 43 | const 44 | n=1000 45 | filename="test.ndx" 46 | 47 | proc create_ins_find* = 48 | 49 | var bt = newBtreeDX() 50 | 51 | if bt.create(filename, 8): 52 | echo "created, inserting ",n," keys..." 53 | for i in 0..n: 54 | let key = $i 55 | if not bt.add(key, i): 56 | echo i,"," 57 | 58 | echo "finding..." 59 | for i in 0..n: 60 | let key = $i 61 | var recno=0 62 | if not bt.find(key, recno): 63 | echo "nf",i,"," 64 | 65 | var 66 | key="100" 67 | recno=0 68 | 69 | echo "next from ", key 70 | 71 | if bt.find(key, recno): 72 | for i in 0..10: 73 | echo key, ":",recno 74 | discard bt.next(key, recno) 75 | 76 | if bt.close(): 77 | echo "closed, ok" 78 | 79 | proc open_find* = 80 | var bt = newBtreeDX() 81 | if bt.open(filename): 82 | var 83 | part_key="45" 84 | key=part_key 85 | recno=0 86 | 87 | echo "partial match:", key 88 | if bt.find(key, recno): 89 | while true: 90 | stdout.write key, ":",recno, " | " 91 | if not bt.next(key, recno) or key[0..part_key.high]!=part_key: break 92 | 93 | discard bt.close 94 | echo "" 95 | 96 | create_ins_find() 97 | open_find() -------------------------------------------------------------------------------- /btreedx/btreedx.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rforcen/nim/4feaacbf3128d170adad529228b7d35d6d0c8ce0/btreedx/btreedx.o -------------------------------------------------------------------------------- /cifar/cifar.nim: -------------------------------------------------------------------------------- 1 | # cifar dataset reader 2 | 3 | #[ 4 | Binary version 5 | The binary version contains the files data_batch_1.bin, data_batch_2.bin, ..., data_batch_5.bin, as well as test_batch.bin. Each of these files is formatted as follows: 6 | 7 | <1 x label><3072 x pixel> 8 | ... 9 | <1 x label><3072 x pixel> 10 | 11 | In other words, the first byte is the label of the first image, which is a number in the range 0-9. The next 3072 bytes are the values of the pixels of the image. 12 | The first 1024 bytes are the red channel values, the next 1024 the green, and the final 1024 the blue. 13 | The values are stored in row-major order, so the first 32 bytes are the red channel values of the first row of the image. 14 | 15 | Each file contains 10000 such 3073-byte "rows" of images, although there is nothing delimiting the rows. 16 | Therefore each file should be exactly 30730000 bytes long. 17 | 18 | There is another file, called batches.meta.txt. This is an ASCII file that maps numeric labels in the range 0-9 to meaningful class names. 19 | It is merely a list of the 10 class names, one per row. The class name on row i corresponds to numeric label i. 20 | ]# 21 | 22 | from mat import vec 23 | 24 | const 25 | path = "cifar/cifar-10-batches-bin/" 26 | base_name = "data_batch_" # 1..5 27 | n_recs* = 10000 # in a file 28 | n_files* = 5 29 | total_recs* = n_recs * n_files 30 | image_width* = 32 31 | image_size* = image_width * image_width 32 | img_nbytes* = image_size * 3 # rgb per pixel 33 | 34 | n_labels* = 10 35 | meta_images* = ["airplane","automobile","bird","cat","deer","dog","frog","horse","ship","truck"] 36 | 37 | type 38 | Image* = array[img_nbytes, uint8] 39 | ImageFloat* = array[image_size, float32] 40 | 41 | CifarRec* = object 42 | label* : int8 43 | image* : Image 44 | 45 | Cifar* = object 46 | training* : ptr array[n_recs * n_files, CifarRec] 47 | test*: ptr array[n_recs, CifarRec] 48 | 49 | proc load_cifar*() : Cifar = 50 | var sbuff : string 51 | for i in 1..5: 52 | sbuff.add readFile(path & base_name & $i & ".bin") 53 | result.training = cast[ptr array[n_recs * n_files, CifarRec]](sbuff[0].addr) 54 | 55 | sbuff = readFile(path & "test_batch.bin") 56 | result.test = cast[ptr array[n_recs, CifarRec]](sbuff[0].addr) 57 | 58 | converter img_to_vec*(img : Image) : vec = # rgb -> 0..1 59 | for i in 0.. 4.0f) { 67 | image[index] = 68 | 0xff000000u | 69 | fire_pallete[((256 * it) / 50) % 256]; // iter element of pallete 70 | return; 71 | } 72 | } 73 | image[index] = 0xff000000u; // out of iter range -> black 74 | } -------------------------------------------------------------------------------- /cl/voronoi.cl: -------------------------------------------------------------------------------- 1 | // 2 | // voronoi.cl 3 | // 4 | 5 | // input point struct 6 | struct Point { 7 | float2 pos; 8 | uint color; 9 | uint pad; // 32 bit alignment field 10 | }; 11 | 12 | inline float dist_squared(float2 a, float2 b) { 13 | float2 c = a - b; 14 | return dot(c, c); 15 | } 16 | 17 | #define dist2(i) dist_squared(points[i].pos, current_point) 18 | 19 | // voronio kernel 20 | kernel void voronoi(global uint *image, // 0: output image 21 | global struct Point *points, // 1: point set 22 | int n_points // 2: n_points 23 | ) { 24 | 25 | uint black = 0xff000000u; 26 | 27 | size_t index = get_global_id(0); 28 | int width = (int)sqrt((float)get_global_size(0)); // w x w = n 29 | 30 | float2 current_point = (float2)(index % width, index / width) / width; 31 | 32 | uint color = black; 33 | float dist = dist2(0), circ_diam = 1e-6f; 34 | 35 | for (int i = 1; i < n_points; i++) { 36 | float d = dist2(i); 37 | 38 | if (d < circ_diam) { // draw center circle?? 39 | color = black; 40 | break; 41 | } 42 | if (d < dist) { 43 | dist = d; 44 | color = points[i].color; 45 | } 46 | } 47 | 48 | image[index] = black | color; 49 | } -------------------------------------------------------------------------------- /convexhull/wp.nim: -------------------------------------------------------------------------------- 1 | import math, vmath 2 | 3 | proc waterman_poly*(radius: float): seq[DVec3] = 4 | var coords: seq[DVec3] 5 | 6 | let (a, b, c) = (0.0, 0.0, 0.0) 7 | var s = radius # .sqrt 8 | let radius2 = s 9 | 10 | let (xra, xrb) = ((a - s).ceil, (a + s).floor) 11 | 12 | for ix in xra.int..xrb.int: 13 | 14 | let x=ix.float 15 | let r = radius2 - (x - a) * (x - a) 16 | if r < 0: continue 17 | 18 | s = r.sqrt 19 | let yra = (b - s).ceil 20 | let yrb = (b + s).floor 21 | 22 | 23 | for iy in yra.int..yrb.int: 24 | 25 | let 26 | y = iy.float 27 | ry = r - (y - b) * (y - b) 28 | 29 | if ry < 0: continue #case ry < 0 30 | 31 | var (zra, zrb) = (0.0, 0.0) 32 | if ry == 0 and c == c.floor: #case ry=0 33 | if (x + y + c).mod(2) != 0: continue 34 | else: (zra, zrb) = (c, c) 35 | else: # case ry > 0 36 | s = ry.sqrt 37 | (zra, zrb) = ( (c - s).ceil, (c + s).floor) 38 | if ((x + y).mod(2)) == 0: 39 | if zra.mod(2) != 0: zra += (if zra <= c:1 else: -1) 40 | else: 41 | if zra.mod(2) == 0: zra += (if zra <= c:1 else: -1) 42 | 43 | for z in countup(zra.int, zrb.int, 2): # save vertex x,y,z 44 | coords.add(dvec3(x, y, z.float)) 45 | coords 46 | 47 | proc waterman_poly_org*(radius: float): seq[DVec3] = 48 | var coords: seq[DVec3] 49 | 50 | let (a, b, c) = (0.0, 0.0, 0.0) 51 | var s = radius # .sqrt 52 | let radius2 = s 53 | 54 | let (xra, xrb) = ((a - s).ceil, (a + s).floor) 55 | 56 | var x = xra 57 | while x <= xrb: 58 | let r = radius2 - (x - a) * (x - a) 59 | if r < 0: 60 | x += 1 61 | continue 62 | 63 | s = r.sqrt 64 | let yra = (b - s).ceil 65 | let yrb = (b + s).floor 66 | var y = yra 67 | 68 | var (zra, zrb) = (0.0, 0.0) 69 | 70 | while y <= yrb: 71 | let ry = r - (y - b) * (y - b) 72 | if ry < 0: 73 | y += 1 74 | continue 75 | #case ry < 0 76 | 77 | if ry == 0 and c == c.floor: 78 | #case ry=0 79 | if (x + y + c).mod(2) != 0: 80 | y += 1 81 | continue 82 | else: 83 | zra = c 84 | zrb = c 85 | 86 | else: 87 | # case ry > 0 88 | s = ry.sqrt 89 | zra = (c - s).ceil 90 | zrb = (c + s).floor 91 | if ((x + y).mod(2)) == 0: 92 | if zra.mod(2) != 0: 93 | if zra <= c: 94 | zra = zra + 1 95 | else: 96 | zra = zra - 1 97 | else: 98 | if zra.mod(2) == 0: 99 | if zra <= c: 100 | zra = zra + 1 101 | else: 102 | zra = zra - 1 103 | 104 | var z = zra 105 | while z <= zrb: 106 | # save vertex x,y,z 107 | coords.add(dvec3(x, y, z)) 108 | z += 2 109 | 110 | y += 1 111 | 112 | x += 1 113 | 114 | coords 115 | 116 | proc normalize*(vec:var seq[DVec3])= 117 | var max = 0.0 118 | 119 | for v in vec: max = max.max(v.x.max(v.y.max(v.z))) 120 | if max != 0.0: 121 | for v in vec.mitems: v/=max 122 | -------------------------------------------------------------------------------- /dc.nim: -------------------------------------------------------------------------------- 1 | # Domain Coloring 2 | # dc.nim 3 | 4 | 5 | import math, complex, zvm, streams, weave, strformat 6 | 7 | type DomainColoring* = object 8 | w,h: int 9 | image*: seq[uint32] 10 | zvm: Zvm 11 | 12 | proc hsv_2_rgb(h: float, s: float, v: float): uint32 = 13 | # convert hsv to int with alpha 0xff00000 14 | let (r, g, b) = 15 | if s == 0.0: (v, v, v) 16 | else: 17 | let 18 | h = if h == 1.0: 0.0 else: h 19 | z = (h * 6.0).floor() 20 | f = h * 6.0 - z 21 | 22 | (p, q, t) = ( v * (1.0 - s), v * (1.0 - s * f), v * (1.0 - s * (1.0 - f)) ) 23 | 24 | case int(z): 25 | of 0: (v, t, p) 26 | of 1: (q, v, p) 27 | of 2: (p, v, t) 28 | of 3: (p, q, v) 29 | of 4: (t, p, v) 30 | of 5: (v, p, q) 31 | else: (0.0,0.0,0.0) 32 | 33 | # generate the ARGB'u32 34 | result = cast[uint32]([uint8(b*255), uint8(g*255), uint8(r*255), 0xff'u8]) 35 | 36 | 37 | proc set_pixel(dc : var DomainColoring, index: int) = 38 | 39 | const PI2 = PI * 2.0 40 | 41 | let 42 | limit = PI 43 | (rmi, rma, imi, ima) = (-limit, limit, -limit, limit) 44 | (i, j) = (index %% dc.w, index div dc.w) 45 | im = ima - (ima - imi) * j.float / (dc.h - 1).float 46 | re = rma - (rma - rmi) * i.float / (dc.w - 1).float 47 | 48 | v = dc.zvm.eval(complex(re, im)) 49 | 50 | var hue = v.phase() # calc hue, arg:phase -pi..pi 51 | if hue < 0.0: hue += PI2 52 | hue /= PI2 53 | 54 | var (m, ranges, rangee) = (v.abs(), 0.0, 1.0) # norm 55 | while m > rangee: 56 | ranges = rangee 57 | rangee *= E 58 | 59 | let 60 | k = (m - ranges) / (rangee - ranges) 61 | kk = 62 | if k < 0.5: k * 2.0 63 | else: 1.0 - (k - 0.5) * 2.0 64 | 65 | sat = 0.4 + (1.0 - (1.0 - kk)^3) * 0.6 66 | val = 0.6 + (1.0 - (1.0 - (1.0 - kk))^3) * 0.4 67 | 68 | dc.image[index] = hsv_2_rgb(hue, sat, val) 69 | 70 | proc write_ppm*(dc: DomainColoring, fn: string) = # write image netpbm P7 format 71 | var f = newFileStream(fn, fmWrite) 72 | if not f.isNil: 73 | f.write &"P7\nWIDTH {dc.w}\nHEIGHT {dc.h}\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n" 74 | f.writeData(dc.image[0].unsafeAddr, dc.image.len * sizeof(dc.image[0])) 75 | f.close() 76 | 77 | proc write_ppm6*(dc: DomainColoring, fn: string) = # write image to P6 netpbm 78 | var f = newFileStream(fn, fmWrite) 79 | if not f.isNil: 80 | f.write &"P6\n{dc.w} {dc.h} 255\n" 81 | for pix in dc.image: f.writeData(pix.unsafeAddr, 3) #rgb 82 | f.close() 83 | 84 | # proc write_image*(dc : DomainColoring, fn:string) = # needs pixie... 85 | # let image = newImage(dc.w, dc.h) 86 | # image.data = cast[seq[ColorRGBX]](dc.image) 87 | # image.writeFile(fn) 88 | 89 | proc newDC(w, h: int, zexpr: string): DomainColoring = 90 | result = DomainColoring(w: w, h: h, zvm: newZvm(zexpr), image:newSeq[uint32](w*h)) 91 | 92 | Weave.init() # generate dc image in parallel 93 | 94 | let dc_ptr = result.addr 95 | parallelFor index in 0.. y.hz: 1 11 | else: 12 | if x.hz < y.hz: -1 13 | else: 0 14 | 15 | proc cmp_pwr*(x, y: Formant): int = 16 | if x.pwr > y.pwr: 1 17 | else: 18 | if x.pwr < y.pwr: -1 19 | else: 0 20 | 21 | proc cmp_bw*(x, y: Formant): int = 22 | if x.bw > y.bw: 1 23 | else: 24 | if x.bw < y.bw: -1 25 | else: 0 26 | 27 | proc cmp_db*(x, y: Formant): int = 28 | - (x.cmp_pwr y) 29 | 30 | proc index2freq*(i:int, sample_rate:float, nfft:int) : float = 31 | i.float * (sample_rate / nfft.float) 32 | 33 | proc freq2index*(freq, sample_rate : float, nfft:int) : int = 34 | freq.int div (sample_rate / nfft.float).int 35 | 36 | proc db*(c : Complex) : float = 37 | result = 10.0 * (c.abs / 1e-12 ).log10 38 | if result.classify == fcNaN or result.classify == fcInf: result = 0 39 | 40 | proc `*`(x,y:seq[float]) : seq[float] = 41 | result = newSeq[float](x.len) 42 | for i in 0..x.high: result[i]=x[i]*y[i] 43 | 44 | proc formants*(samples: seq[float], sample_rate: float): (seq[Formant], seq[Complex64]) = 45 | var 46 | lpc = newLPC() 47 | roots: seq[Complex64] 48 | 49 | let # filter samples w/hamming window 50 | n_coeff = (2 + sample_rate / 100).int.power_2 # lpc coeff 51 | coeff = lpc.getCoefficients(n_coeff, samples * signal_window(HAMMING, samples.len)) 52 | srpi2 = sample_rate / (PI * 2) 53 | srpi = sample_rate / PI 54 | 55 | zroots(coeff, roots, true) 56 | 57 | var formants : seq[Formant] 58 | 59 | for root in roots: 60 | if root.im > 0.01: 61 | let 62 | hz = srpi2 * root.im.arctan2(root.re) 63 | bw = srpi * root.abs.ln 64 | 65 | if hz > 0 and bw < 400: # formant frequencies should be greater than 0 Hz with bandwidths less than 10 Hz 66 | formants.add(Formant(hz: hz.ceil, bw: bw, pwr: 0)) 67 | 68 | formants.sort(cmp_hz) 69 | 70 | 71 | # freq. response & calc. power 72 | var 73 | nfft = coeff.len.power_2 # sample_rate.int.power_2.shr 2 # closer power of 2 (log2) 74 | freqresp : seq[Complex64] 75 | fft = fft(nfft) 76 | 77 | fft.set(coeff) 78 | fft.exec() 79 | 80 | for i in 0.. x.bw < 1).sorted(cmp_pwr): echo f 120 | 121 | 122 | proc test_formants_wav_file= 123 | let 124 | file_name = "test.wav" 125 | wav = read_wav[float](file_name) 126 | 127 | echo "formants" 128 | echo "file :", file_name 129 | echo "sample rate:", wav.sample_rate 130 | 131 | var (formats, freqresp) = formants(samples = wav.samples, sample_rate = wav.sample_rate.float) 132 | 133 | formats = formats.sorted(cmp_bw).deduplicate 134 | echo "formants:", formats.len 135 | for f in formats[0..6].sorted(cmp_hz): echo f 136 | # for fr in freqresp: echo fr.re," ", fr.im 137 | 138 | test_formants_wav_file() 139 | -------------------------------------------------------------------------------- /formants/lpc.nim: -------------------------------------------------------------------------------- 1 | # lpc: linear predictive coding 2 | 3 | import math 4 | 5 | type LPC* = object 6 | count: int 7 | delayLine, impulseResponse, coefs: seq[float] 8 | 9 | # fwds 10 | proc getOutputSample*(lpc: var LPC, inputSample: float): float 11 | proc init*(lpc: var LPC) 12 | proc getCoefficients*(lpc: var LPC, p: int, x: seq[float]): seq[float] 13 | 14 | # methods 15 | proc newLPC*(): LPC = LPC() 16 | 17 | proc filter*(lpc: var LPC, y: seq[float], n: int): seq[float] = 18 | for i in 0..= lpc.coefs.len: lpc.count = 0 49 | 50 | proc getCoefficients*(lpc: var LPC, p: int, x: seq[float]): seq[float] = 51 | var r = newSeq[float](p+1) # = new double[p + 1] # size = 11 52 | let N = x.len # size = 256 53 | for T in 0..

::epsilon() 6 | 7 | converter ftoc(f: float): Complex64 = complex64(f, 0.0) 8 | 9 | proc polarc(p:Complex64): Complex64 = complex64(p.polar.r, p.polar.phi) 10 | 11 | # var FLT_EPSILON* {. importc: "FLT_EPSILON" header: "float.h" .} : cfloat 12 | # var DBL_EPSILON* {. importc: "DBL_EPSILON" header: "float.h" .} : cdouble 13 | let EPS {. importc: "DBL_EPSILON" header: "" .} : cdouble 14 | 15 | # real coeff 16 | proc zroots*(a: seq[float], roots: var seq[Complex64], polish: bool) = 17 | proc laguer(a: seq[Complex64], x: var Complex64, its: var int) = 18 | const 19 | MR = 8 20 | MT = 10 21 | MAXIT = MT * MR 22 | frac = [0.0, 0.5, 0.25, 0.75, 0.13, 0.38, 0.62, 0.88, 1.0] 23 | 24 | let m = a.len - 1 25 | 26 | for iter in 1..MAXIT: 27 | its = iter 28 | 29 | var 30 | b = a[m] 31 | err = b.abs 32 | d, f : Complex64 33 | abx = x.abs 34 | 35 | for j in countdown(m - 1, 0): 36 | f = x * f + d 37 | d = x * d + b 38 | b = x * b + a[j] 39 | err = b.abs + abx * err 40 | 41 | err *= EPS 42 | if b.abs <= err: return 43 | 44 | var 45 | g = d / b 46 | g2 = g * g 47 | h = g2 - 2.0 * f / b 48 | sq = ((m - 1).float * (m.float * h - g2)).sqrt 49 | gp = g + sq 50 | gm = g - sq 51 | 52 | abp = gp.abs 53 | abm = gm.abs 54 | 55 | if abp < abm: gp = gm 56 | 57 | var dx = if max(abp, abm) > 0: m.float / gp 58 | else: complex64(1 + abx, iter.float).polarc 59 | 60 | var x1 = x - dx 61 | if x == x1: return 62 | 63 | if iter %% MT != 0: x = x1 64 | else: x -= frac[iter div MT] * dx 65 | 66 | raise newException(ArithmeticDefect, "roots not found, too many iterations in laguer") 67 | 68 | var 69 | its: int 70 | m = a.high 71 | ac = a.map(x => x.ftoc) 72 | ad = ac 73 | 74 | roots = newSeq[Complex64](m) 75 | 76 | for j in countdown(m-1, 0): 77 | var 78 | x : Complex64 79 | ad_v = ad[0.. returning modified params p,r:', p, r 13 | 14 | return 15 | end 16 | 17 | subroutine param(op, degree, zeror, zeroi, fail) 18 | 19 | integer degree 20 | double precision op(101), zeror(101), zeroi(101) 21 | logical fail 22 | 23 | print *, '--> param.fortran: deg,ops 1,2 ', degree, op(1), op(2) 24 | 25 | fail=.false. 26 | degree=100 27 | 28 | return 29 | end -------------------------------------------------------------------------------- /fortran/param.nim: -------------------------------------------------------------------------------- 1 | # 2 | # quadmath type fortran parameter passing 3 | # @gfortran -fdefault-real-8 -c param.f 493.f 4 | # 5 | 6 | {.passL:"param.o 493.o libalgebra.o paramf90.o -lgfortran -lquadmath -lm".} 7 | 8 | import quadmath 9 | 10 | # gfortran descriptor 11 | type Descriptor = object 12 | base_addr : pointer 13 | elem_len : int64 # not required as defined in f90 14 | version: int32 # 1, " 15 | rank, attribute: int8 # " 16 | rtype: int16 # " 17 | dims : array[15, (int,int,int) ] # [lower_bound, extend, sm : int64 ]] 18 | 19 | proc newDesc[T](base_addr : openArray[T]) : Descriptor = 20 | result = Descriptor(base_addr:base_addr[0].unsafeAddr) 21 | for i in 0..1: result.dims[i]=(1, base_addr.len, 1) 22 | proc newDesc2d[T](base_addr : openArray[T], n,m:int) : Descriptor = 23 | result = Descriptor(base_addr:base_addr[0].unsafeAddr) 24 | result.dims[0]=(1, n, 1) 25 | result.dims[2]=(1, n, 1) 26 | result.dims[1]=(1, n, m) 27 | 28 | proc param (op:ptr float128,degree:ptr cint, zeror, zeroi:ptr float128, fail:ptr cint) {.importc:"param_".} 29 | proc param1(d, r:ptr float128) {.importc:"param1_".} 30 | proc rpoly (op:ptr float128, degree:ptr cint, zeror, zeroi:ptr float128, fail:ptr cint) {.importc:"rpoly_".} 31 | proc cbrt_dp(x:ptr float64) : float64 {.importc:"__lib_algebra_MOD_cbrt_dp".} 32 | proc cbrt_sp(x:ptr float32) : float32 {.importc:"__lib_algebra_MOD_cbrt_sp".} 33 | proc lineq_gausselim_dp(a,b:ptr Descriptor) {.importc:"__lib_algebra_MOD_lineq_gausselim_dp".} 34 | 35 | proc vec_1d_2d_param= # test passing 1d & 2d matrix 36 | 37 | proc pva1d(a:ptr Descriptor) {.importc:"pva1d_".} 38 | proc pva2d(a:ptr Descriptor) {.importc:"pva2d_".} 39 | 40 | const n = 5 41 | var 42 | a=newSeq[float](n*n) 43 | b=newSeq[float](n) 44 | 45 | for i in 0..a.high: a[i]=i.float 46 | for i in 0..b.high: b[i]=i.float 47 | 48 | echo "calling pva1d...", a 49 | 50 | var desc = newDesc(a) 51 | pva1d(desc.addr) 52 | 53 | echo "values modified...",a 54 | 55 | echo "calling pva2d...", a 56 | var desc2d = newDesc2d(a, 5,5) 57 | pva2d(desc2d.addr) 58 | 59 | echo "values modified...",a 60 | 61 | var descb = newDesc(b) 62 | lineq_gausselim_dp(desc2d.addr, descb.addr) 63 | echo a 64 | echo "result:",b 65 | 66 | 67 | 68 | 69 | proc test_no_desc_params= 70 | var xdp=123.45.float64 71 | echo "cbrt_dp:", cbrt_dp(xdp.addr) 72 | var xsp=123.45.float32 73 | echo "cbrt_sp:", cbrt_sp(xsp.addr) 74 | 75 | var 76 | dp=11111.float128 77 | r=22222.float128 78 | 79 | echo "param1 test, dp, r:", dp, ",",r 80 | param1(dp.unsafeAddr, r.unsafeAddr) 81 | echo "values returned from param1:", dp, ",",r 82 | 83 | var 84 | degree=10.cint 85 | op = @[1.float128, -55, 1320,-18150,157773, -902055,3416930,-8409500,12753576, -10628640, 3628800] #@[8.float,-8,16,-16,8,-8] 86 | zeror=newSeq[float128](degree) 87 | zeroi=newSeq[float128](degree) 88 | 89 | fail=1.cint 90 | 91 | param(op[0].unsafeAddr,degree.unsafeAddr, zeror[0].unsafeAddr, zeroi[0].unsafeAddr, fail.unsafeAddr) 92 | 93 | degree=10.cint 94 | rpoly(op[0].unsafeAddr,degree.unsafeAddr, zeror[0].unsafeAddr, zeroi[0].unsafeAddr, fail.unsafeAddr) 95 | 96 | echo "fail, degree:", fail, ",", degree 97 | echo zeror 98 | echo zeroi 99 | 100 | 101 | vec_1d_2d_param() 102 | test_no_desc_params() -------------------------------------------------------------------------------- /fortran/paramf90.f90: -------------------------------------------------------------------------------- 1 | ! sample params passing based on descriptors for a(:) 2 | 3 | ! descriptors not required as size is fixed 4 | subroutine parammatrix(a,b) 5 | real,intent(inout) :: a(3,3),b(3) 6 | print *,'sizeof a ,b', size(a), size(b) 7 | print *,'a,b:', a,b 8 | end subroutine parammatrix 9 | 10 | subroutine pva1d(a) 11 | real,intent(inout) :: a(:) 12 | 13 | print *,'PVA1d -> size a(:) -> ', size(a,1) 14 | write (*,'(g5.1)') a 15 | a = (/111,222,333,444,555,666/) 16 | a(7)=777 17 | 18 | end subroutine pva1d 19 | 20 | subroutine pva2d(a) 21 | real,intent(inout) :: a(:,:) 22 | 23 | print *,'PVA2d -> size a(:,:) -> ', size(a), size(a,1), size(a,2) 24 | write (*,'(g5.1)') a 25 | a(1,1)=9999 26 | a(2,1)=8888 27 | a(1,2)=7677767 28 | a(1,3)=7677767 29 | end subroutine pva2d 30 | -------------------------------------------------------------------------------- /high_precision/c128.nim: -------------------------------------------------------------------------------- 1 | # complex numers a+ib 2 | import math 3 | type c128* = object 4 | re, im : f128 5 | 6 | {.push inline.} 7 | 8 | proc newC128*:c128=c128(re:0.0, im:0.0) 9 | proc newC128*(re, im:f128):c128=c128(re:re, im:re) 10 | 11 | proc arg*(z: c128): f128 = atan2(z.im, z.re) 12 | proc sqmag*(z: c128): f128 = z.re*z.re + z.im*z.im 13 | proc abs*(z: c128): f128 = z.sqmag.sqrt 14 | 15 | proc `+`*(x, y: c128): c128 = c128(re: x.re + y.re, im: x.im + y.im) 16 | proc `-`*(x, y: c128): c128 = c128(re: x.re - y.re, im: x.im - y.im) 17 | proc `-`*(x: c128): c128 = c128(re: -x.re, im: -x.im) 18 | proc `*`*(x, y: c128): c128 = c128(re: x.re*y.re - x.im*y.im, im: x.re*y.im + x.im*y.re) 19 | proc `/`*(x, y: c128): c128 = 20 | let d = (y.re*y.re) + (y.im*y.im) 21 | result.re = (x.re*y.re)+(x.im*y.im) 22 | result.re/=d 23 | result.im = (x.im*y.re)-(x.re*y.im) 24 | result.im/=d 25 | 26 | proc `+`*(x: c128, y: float): c128 = c128(re: x.re + y, im: x.im + y) 27 | proc `-`*(x: c128, y: float): c128 = c128(re: x.re - y, im: x.im - y) 28 | proc `*`*(x: c128, y: float): c128 = c128(re: x.re * y, im: x.im * y) 29 | proc `/`*(x: c128, y: float): c128 = c128(re: x.re / y, im: x.im / y) 30 | 31 | proc `+=`*(x: var c128, y: c128) = x = x+y 32 | proc `-=`*(x: var c128, y: c128) = x = x-y 33 | proc `*=`*(x: var c128, y: c128) = x = x*y 34 | proc `/=`*(x: var c128, y: c128) = x = x/y 35 | 36 | proc `+=`*(x: var c128, y: float) = x.re+=y; x.im+=y 37 | proc `-=`*(x: var c128, y: float) = x.re-=y; x.im-=y 38 | proc `*=`*(x: var c128, y: float) = x.re*=y; x.im*=y 39 | proc `/=`*(x: var c128, y: float) = x.re/=y; x.im/=y 40 | 41 | proc sqr*(z: c128): c128 = z*z 42 | proc pow3*(z: c128): c128 = z*z*z 43 | proc pow4*(z: c128): c128 = z*z*z*z 44 | proc pow5*(z: c128): c128 = z*z*z*z*z 45 | proc pown*(z: c128, n: int): c128 = 46 | result = z 47 | for i in 1..n: result*=z 48 | 49 | proc pow*(z: c128, n: int): c128 = 50 | let 51 | rn = z.abs().pow(n) 52 | na = z.arg() * n.ito128 53 | c128(re: rn * cos(na), im: rn * sin(na)) 54 | 55 | proc pow*(s, z: c128): c128 = # s^z 56 | let 57 | c = z.re 58 | d = z.im 59 | m = pow(s.sqmag, c/2.0) * exp(-d * s.arg) 60 | 61 | result = c128(re: m * cos(c * s.arg + 0.5 * d * log(s.sqmag)), im: m * sin( 62 | c * s.arg + 0.5 * d * log(s.sqmag))) 63 | 64 | proc sqrt*(z: c128): c128 = 65 | let a = z.abs() 66 | c128(re: sqrt((a+z.re)/2.0), im: sqrt((a-z.re)/2.0) * sign(z.im).ito128) 67 | 68 | proc log*(z: c128): c128 = c128(re: z.abs.log, im: z.arg) 69 | proc exp*(z: c128): c128 = c128(re: E, im: 0.0).pow(z) 70 | 71 | proc cosh*(z: c128): c128 = c128(re: cosh(z.re) * cos(z.im), im: sinh(z.re) * sin(z.im)) 72 | proc sinh*(z: c128): c128 = c128(re: sinh(z.re) * cos(z.im), im: cosh(z.re) * sin(z.im)) 73 | proc sin*(z: c128): c128 = c128(re: sin(z.re) * cosh(z.im), im: cos(z.re) * 74 | sinh(z.im)) 75 | proc cos*(z: c128): c128 = c128(re: cos(z.re) * cosh(z.im), im: -sin(z.re) * 76 | sinh(z.im)) 77 | proc tan*(z: c128): c128 = z.sin()/z.cos() 78 | 79 | proc asinh*(z: c128): c128 = 80 | let t = c128(re: (z.re-z.im) * (z.re+z.im)+1.0, im: 2.0*z.re*z.im).sqrt 81 | (t + z).log 82 | 83 | proc asin*(z: c128): c128 = 84 | let t = c128(re: -z.im, im: z.re).asinh 85 | c128(re: t.im, im: -t.re) 86 | 87 | proc acos*(z: c128): c128 = 88 | let 89 | t = z.asin() 90 | pi_2 = 1.7514 91 | c128(re: pi_2 - t.re, im: -t.im) 92 | 93 | proc atan*(z: c128): c128 = 94 | c128( 95 | re: 0.50 * atan2(2.0*z.re, 1.0 - z.re*z.re - z.im*z.im), 96 | im: 0.25 * log((z.re*z.re + (z.im+1.0)*(z.im+1.0)) / (z.re*z.re + (z.im-1.0)*(z.im-1.0))) 97 | ) 98 | 99 | {.pop.} 100 | 101 | 102 | # end complex128 - c128 103 | -------------------------------------------------------------------------------- /high_precision/complex_std.nim: -------------------------------------------------------------------------------- 1 | # complex_std.nim 2 | # nim wrapper to std::complex 3 | 4 | # {.checks: off, optimization: speed.} 5 | 6 | import strformat 7 | # import f128 8 | 9 | # {.passC:"-std=gnu++2a".} 10 | 11 | 12 | # f128 13 | type f128* {.importcpp: "long double".} = object 14 | 15 | converter fto128*(f: float): f128 = # {.emit:[result, "=(long double)f; "].} # this mangles vsc coloring 16 | var r: f128; {.emit: "r=(long double)f; ".}; r 17 | converter ito128*(i: int): f128 = # {.emit:[result, "=(long double) i;"].} 18 | var r: f128; {.emit: "r=(long double)i; ".}; r 19 | proc `$`*(x: f128): string = 20 | var 21 | conv_buff: array[128, char] 22 | cl: cint = conv_buff.high 23 | {.emit: " cl = snprintf(conv_buff, cl, \"%Le\", x); ".} 24 | for i in 0..", importcpp: "std::complex<'0>".} = object 28 | re, im : T 29 | 30 | proc complex*[T](re, im:T):Complex[T] {.importcpp: "'0 (@)".} 31 | 32 | proc `+`*[T](a,b:Complex[T]):Complex[T] {.importcpp:"# + #".} 33 | proc `-`*[T](a,b:Complex[T]):Complex[T] {.importcpp:"# - #".} 34 | proc `-`*[T](a:Complex[T]):Complex[T] {.importcpp:"-#".} 35 | proc `*`*[T](a,b:Complex[T]):Complex[T] {.importcpp:"# * #".} 36 | proc `/`*[T](a,b:Complex[T]):Complex[T] {.importcpp:"# / #".} 37 | 38 | proc `+=`*[T](a,b:Complex[T]) {.importcpp:"# += #".} 39 | proc `-=`*[T](a,b:Complex[T]) {.importcpp:"# -= #".} 40 | proc `*=`*[T](a,b:Complex[T]) {.importcpp:"# *= #".} 41 | proc `/=`*[T](a,b:Complex[T]) {.importcpp:"# /= #".} 42 | 43 | proc `==`*[T](a,b:Complex[T]):bool {.importcpp:"# == #".} 44 | proc `!=`*[T](a,b:Complex[T]):bool {.importcpp:"# != #".} 45 | 46 | proc real*[T](z:Complex[T]):T {.importcpp: "#.real()".} 47 | proc imag*[T](z:Complex[T]):T {.importcpp: "#.imag()".} 48 | proc abs*[T](z:Complex[T]):T {.importcpp: "abs(#)".} 49 | proc arg*[T](z:Complex[T]):T {.importcpp: "std::arg(#)".} 50 | proc norm*[T](z:Complex[T]):T {.importcpp: "std::norm(#)".} 51 | proc conj*[T](z:Complex[T]):Complex[T] {.importcpp: "std::conj(#)".} 52 | proc proj*[T](z:Complex[T]):Complex[T] {.importcpp: "std::proj(#)".} 53 | proc polar*[T](r, theta:T):Complex[T] {.importcpp: "std::polar(@)".} 54 | 55 | proc exp*[T](z:Complex[T]):Complex[T] {.importcpp: "std::exp(#)".} 56 | proc log*[T](z:Complex[T]):Complex[T] {.importcpp: "std::log(#)".} 57 | proc log10*[T](z:Complex[T]):Complex[T] {.importcpp: "std::log10(#)".} 58 | 59 | proc pow*[T](z,y:Complex[T]):Complex[T] {.importcpp: "std::pow(@)".} 60 | 61 | proc sin*[T](z:Complex[T]):Complex[T] {.importcpp: "std::sin(#)".} 62 | proc cos*[T](z:Complex[T]):Complex[T] {.importcpp: "std::cos(#)".} 63 | proc tan*[T](z:Complex[T]):Complex[T] {.importcpp: "std::tan(#)".} 64 | proc asin*[T](z:Complex[T]):Complex[T] {.importcpp: "std::asin(#)".} 65 | proc acos*[T](z:Complex[T]):Complex[T] {.importcpp: "std::acos(#)".} 66 | proc atan*[T](z:Complex[T]):Complex[T] {.importcpp: "std::atan(#)".} 67 | 68 | proc sinh*[T](z:Complex[T]):Complex[T] {.importcpp: "std::sinh(#)".} 69 | proc cosh*[T](z:Complex[T]):Complex[T] {.importcpp: "std::cosh(#)".} 70 | proc tanh*[T](z:Complex[T]):Complex[T] {.importcpp: "std::tanh(#)".} 71 | proc asinh*[T](z:Complex[T]):Complex[T] {.importcpp: "std::asinh(#)".} 72 | proc acosh*[T](z:Complex[T]):Complex[T] {.importcpp: "std::acosh(#)".} 73 | proc atanh*[T](z:Complex[T]):Complex[T] {.importcpp: "std::atanh(#)".} 74 | 75 | # proc `$`*[T](z:Complex[T]):string = "(" & $(z.real()) & ", " & $(z.imag()) & ")" 76 | 77 | when isMainModule: 78 | var 79 | z = complex[f128](3,4) 80 | z1 = complex[f128](5,6) 81 | 82 | # echo "z=", z #, z.abs={z.abs}, z.arg={z.arg}" 83 | # echo fmt "z+z={z+z}" 84 | # z+=z1 85 | # echo fmt "z1={z1}, z+=z1={z}, -z={-z}, z==z1:{z==z1}, z!=z1:{z!=z1}" 86 | # echo fmt "polar(1,2)={polar(1.fto128,1.6.fto128)}" 87 | # echo "z.allfunc=", z.exp.log.sin.cos.tan.asin.acos.atan.sinh.cosh.tanh.asinh.acosh.atanh -------------------------------------------------------------------------------- /high_precision/complex_wrap.nim: -------------------------------------------------------------------------------- 1 | # complex.h wrapper 2 | # https://github.com/nim-lang/Nim/blob/6fb372d96bade748aa6cb3484fef2118b4585f26/doc/nimc.txt#L599 3 | 4 | import f128 5 | 6 | type float128=f128 7 | type SomeReal* = float32 | float64 | float128 8 | 9 | type Complex[T] {.header:"complex.h", importcpp: "Complex<'0>", nodecl.} = object 10 | re, im : T 11 | 12 | proc newComplex*[T]() : Complex[T] {.importcpp: "Complex<'*0>()", nodecl.} 13 | proc newComplex*[T](re, im:T) : Complex[T] {.importcpp: "Complex<'*0>(@)", nodecl.} 14 | proc newComplex*[T](re:T) : Complex[T] {.importcpp: "Complex<'*0>(@,0)", nodecl.} 15 | 16 | proc sqmag*[T : SomeReal] (z:Complex[T]) : T {.importcpp:"#.sqmag()"} 17 | proc arg*[T : SomeReal] (z:Complex[T]) : T {.importcpp:"#.arg()"} 18 | proc abs*[T : SomeReal] (z:Complex[T]) : T {.importcpp:"#.abs()"} 19 | 20 | proc `+`*[T : SomeReal] (a,b:Complex[T]) : Complex[T] {.importcpp:"# + #"} 21 | proc `-`*[T : SomeReal] (a,b:Complex[T]) : Complex[T] {.importcpp:"# - #"} 22 | proc `*`*[T : SomeReal] (a,b:Complex[T]) : Complex[T] {.importcpp:"# * #"} 23 | proc `/`*[T : SomeReal] (a,b:Complex[T]) : Complex[T] {.importcpp:"# / #"} 24 | 25 | import strformat 26 | proc `$`*[T](z:Complex[T]):string = fmt "({z.re}, {z.im})" 27 | 28 | when isMainModule: 29 | echo "complex# test..." 30 | var 31 | z32:Complex[float32]=newComplex[float32](3,4) 32 | z64:Complex[float64]=newComplex[float64](3,4) 33 | z128:Complex[float128]=newComplex[float128](3,4) 34 | 35 | echo "z=", z32, ", sqmag=", z32.sqmag, ", arg=", z32.arg 36 | echo "z=", z64, ", sqmag=", z64.sqmag, ", arg=", z64.arg 37 | echo "z=", z128, ", sqmag=", z128.sqmag, ", arg=", z128.arg, ", abs=", z128.abs 38 | 39 | z128 = (z128+z128) / z128 40 | echo "z=", z128, ", sqmag=", z128.sqmag, ", arg=", z128.arg, ", abs=", z128.abs 41 | z128 = z128 * z128 42 | echo "z=", z128, ", sqmag=", z128.sqmag, ", arg=", z128.arg, ", abs=", z128.abs 43 | z128 = z128 + z128 44 | echo "z=", z128, ", sqmag=", z128.sqmag, ", arg=", z128.arg, ", abs=", z128.abs 45 | z128 = z128 - z128 46 | echo "z=", z128, ", sqmag=", z128.sqmag, ", arg=", z128.arg, ", abs=", z128.abs 47 | -------------------------------------------------------------------------------- /high_precision/int128.cpp: -------------------------------------------------------------------------------- 1 | // int128 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using std::string; 10 | 11 | typedef signed __int128 int128_t; 12 | typedef unsigned __int128 uint128_t; 13 | 14 | // Return pointer to the end 15 | static char *uint128toa_helper(char *dest, uint128_t x) 16 | { 17 | if (x >= 10) 18 | { 19 | dest = uint128toa_helper(dest, x / 10); 20 | } 21 | *dest = (char)(x % 10 + '0'); 22 | return ++dest; 23 | } 24 | 25 | string int128toa(int128_t x) 26 | { 27 | string ds(41, '\0'); 28 | char *dest = (char *)ds.c_str(); 29 | 30 | if (x < 0) 31 | { 32 | *dest = '-'; 33 | *uint128toa_helper(dest + 1, (uint128_t)(-1 - x) + 1) = '\0'; 34 | } 35 | else 36 | { 37 | *uint128toa_helper(dest, (uint128_t)x) = '\0'; 38 | } 39 | return ds; 40 | } 41 | 42 | string uint128toa(uint128_t x) 43 | { 44 | string ds(41, '\0'); 45 | char *dest = (char *)ds.c_str(); 46 | 47 | *uint128toa_helper(dest, x) = '\0'; 48 | return ds; 49 | } 50 | 51 | int128_t atoint128(char *s) 52 | { 53 | int128_t x = 0, p = 1; 54 | 55 | for (int i = strlen(s) - 1; i >= 0; i--, p *= 10) 56 | { 57 | if (s[i] == '-') 58 | x = -x; 59 | else 60 | x += p * (s[i] - '0'); 61 | } 62 | return x; 63 | } 64 | 65 | uint128_t atouint128(char *s) 66 | { 67 | uint128_t x = 0, p = 1; 68 | 69 | for (int i = strlen(s) - 1; i >= 0; i--, p *= 10) 70 | { 71 | x += p * (s[i] - '0'); 72 | } 73 | return x; 74 | } 75 | 76 | int main() 77 | { 78 | uint128_t i = atouint128("170141181000009999037184105727"); 79 | // "170141183460469231731687303715884105727"; 80 | 81 | // for (auto n=0; n<128; n++) printf("shl %d=%s\n", n, uint128toa(dest, shl(i,n))); 82 | auto p = i; 83 | for (auto n = 0; n < 128; n++, p /= 2) 84 | printf("shr %3d=%s | %s (%s)\n", n, uint128toa(i >> n).c_str(), uint128toa(p).c_str(), uint128toa((i >> n) - p).c_str()); 85 | 86 | return 0; 87 | } -------------------------------------------------------------------------------- /high_precision/mpfr_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | int main (void) 7 | { 8 | unsigned int i; 9 | mpfr_t s, t, u; 10 | int precision=200; 11 | mp_rnd_t rand=MPFR_RNDD; 12 | int k=MPFR_NAN_KIND; 13 | 14 | mpfr_init2 (t, precision); 15 | mpfr_set_d (t, 1.0, rand); 16 | mpfr_init2 (s, precision); 17 | mpfr_set_d (s, 1.0, rand); 18 | mpfr_init2 (u, precision); 19 | for (i = 1; i <= 100; i++) 20 | { 21 | mpfr_mul_ui (t, t, i, MPFR_RNDU); 22 | mpfr_set_d (u, 1.0, rand); 23 | mpfr_div (u, u, t, rand); 24 | mpfr_add (s, s, u, rand); 25 | } 26 | printf ("Sum is "); 27 | mpfr_out_str (stdout, 10, 0, s, rand); 28 | putchar ('\n'); 29 | mpfr_clear (s); 30 | mpfr_clear (t); 31 | mpfr_clear (u); 32 | mpfr_free_cache (); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /llvm/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @nim c -d:danger -d:release --noMain --app:lib --out:libfuncs.so funcs 3 | @nim cpp -r -d:release -d:danger expression 4 | 5 | clean: 6 | @ rm -fr funcs.so expression -------------------------------------------------------------------------------- /llvm/expression_llvm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rforcen/nim/4feaacbf3128d170adad529228b7d35d6d0c8ce0/llvm/expression_llvm -------------------------------------------------------------------------------- /llvm/expression_llvm.nim: -------------------------------------------------------------------------------- 1 | # expression interpreter & llvm compiler 2 | 3 | import patty, strutils, nimly, tables 4 | import llvm 5 | 6 | const funcNames* = ["sin","cos","tan","log","exp"] 7 | 8 | var 9 | jit :JIT 10 | dblt : ptr Type 11 | function : ptr Function 12 | fpow : ptr Function 13 | funcTable : Table[string, ptr Function] 14 | 15 | ## lexer 16 | variant ExpressionTokens: 17 | PLUS 18 | MINUS 19 | MULTI 20 | DIVISION 21 | POWER 22 | NUM(val: float) 23 | LPAREN 24 | RPAREN 25 | FUNCTION(name : string) 26 | ARGUMENT(index : int) 27 | COMMA 28 | WAVE 29 | IGNORE 30 | 31 | niml expressionLexer[ExpressionTokens]: 32 | r"\(": LPAREN() 33 | r"\)": RPAREN() 34 | r"\+": PLUS() 35 | r"-": MINUS() 36 | r"\*": MULTI() 37 | r"/": DIVISION() 38 | r"^": POWER() 39 | r"," : COMMA() 40 | 41 | r"(\d*\.)?\d+": NUM(parseFloat(token.token)) 42 | r"wave" : WAVE() 43 | r"[a..z]+" : FUNCTION(token.token) 44 | r"$\d" : ARGUMENT(parseInt(token.token[1..^1]) - 1) # start on 1, i.e. $1, $2, ... 45 | 46 | r"\s": IGNORE() 47 | 48 | setUp: discard 49 | tearDown:discard 50 | 51 | nimy expressionParser[ExpressionTokens]: 52 | top[ptr Value]: 53 | term: 54 | result = $1 55 | discard jit.ret($1) 56 | 57 | term[ptr Value]: 58 | term PLUS factor: jit.fadd($1, $3) 59 | term MINUS factor: jit.fsub($1, $3) 60 | factor: $1 61 | 62 | factor[ptr Value]: 63 | factor MULTI power: jit.fmul($1, $3) 64 | factor DIVISION power: jit.fdiv($1, $3) 65 | power: $1 66 | 67 | power[ptr Value]: 68 | power POWER num: jit.fcall(fpow, @[$1,$3]) 69 | num : $1 70 | 71 | num[ptr Value]: 72 | LPAREN term RPAREN: $2 73 | 74 | WAVE LPAREN term COMMA term COMMA term RPAREN: 75 | jit.fmul($3, jit.fcall(funcTable["sin"], @[jit.fadd($5, $7)])) # $3 * sin($5 + $7) 76 | 77 | FUNCTION LPAREN term RPAREN : jit.fcall(funcTable[($1).name], @[$3]) 78 | 79 | NUM: jit.initDbl(($1).val) 80 | 81 | ARGUMENT: function[($1).index] # range not checked! 82 | 83 | ## 84 | proc compileLLVM*(funcName, expr:string):proc(x:float):float{.cdecl.}= 85 | jit = newJIT("expr.module") 86 | dblt = jit.getDoubleTy 87 | fpow = jit.CreateFunction(dblt, @[dblt, dblt], "pow") # pow(x,y) 88 | 89 | # create function table 90 | for f in funcNames: funcTable[f]=jit.CreateFunction(dblt, @[dblt], f.cstring) 91 | 92 | function = jit.CreateFunctionBlock(dblt, @[dblt], funcName) 93 | 94 | # compile 95 | var exprLexer = expressionLexer.newWithString(expr) 96 | exprLexer.ignoreIf = proc(r: ExpressionTokens): bool = r.kind == ExpressionTokensKind.IGNORE 97 | var parser = expressionParser.newParser() 98 | 99 | discard parser.parse(exprLexer) 100 | 101 | # func address 102 | let func_addr = jit.getFuncAddr(funcName) 103 | cast[proc(t: float):float {.cdecl.}] ( func_addr ) 104 | 105 | when isMainModule: 106 | import times, strformat 107 | 108 | proc testLlvmExpr= 109 | 110 | echo "benchmarking nimly-llvm" 111 | 112 | let 113 | expr = "((cos((log((1.24+$1))))+$1+$1*$1+7.97*$1*$1+$1*6.09))" # "1*$1+2+3*$1+4+5+6+7+8+9+1+2+3+4+5+6+7+8+9+$1" #"sin(( 2 - 3.45 * $1 ) / 4 * 34.56) ^ 4" 114 | cfunc = compileLLVM("foo",expr) 115 | 116 | jit.printIR() 117 | let 118 | t = 2.3 119 | n = 10_000_000 120 | t0 = now() 121 | 122 | for _ in 0..n: 123 | let _ = cfunc(t) 124 | 125 | echo &"llvm lap for {n}:{(now()-t0).inMilliseconds}ms, {expr}({t})={cfunc(t)}" 126 | 127 | proc testMultFunc= 128 | let f00=compileLLVM("f00","1+2*sin(34*$1)") 129 | echo f00(1.0) 130 | let f01=compileLLVM("f01","3+4/tan(sin($1*45))") 131 | echo f01(1.0) 132 | 133 | # jit.printIR() 134 | 135 | 136 | testMultFunc() 137 | # testLlvmExpr() -------------------------------------------------------------------------------- /llvm/funcs.cpp: -------------------------------------------------------------------------------- 1 | // functions included in llvm must be compiled w/ -fPIC and stored in .so 2 | 3 | // g++ -shared -o libfuncs.so -fPIC funcs.cpp 4 | 5 | #include 6 | 7 | extern "C" 8 | { 9 | double foo(double t) 10 | { 11 | return t; 12 | } 13 | 14 | double wave(double t, double a, double hz, double phase) 15 | { 16 | return a * sin(t * hz + phase); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /llvm/funcs.nim: -------------------------------------------------------------------------------- 1 | # funcs.nim 2 | import math 3 | 4 | # nim c -d:danger -d:release --noMain --app:lib --out:libfuncs.so funcs 5 | 6 | proc foo*(t:float):float {.exportc, dynlib.} = t 7 | proc wave*(x,a,hz,p:float):float {.exportc, dynlib.} = a*sin(x*hz+p) -------------------------------------------------------------------------------- /llvm/libfuncs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rforcen/nim/4feaacbf3128d170adad529228b7d35d6d0c8ce0/llvm/libfuncs.so -------------------------------------------------------------------------------- /llvm/llvm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | using namespace llvm; 41 | using namespace std; 42 | -------------------------------------------------------------------------------- /llvm/rand_expr.nim: -------------------------------------------------------------------------------- 1 | # random expression generator 2 | import random, expression, expression_llvm, strformat, math 3 | 4 | proc rand_expression(n:int):string= 5 | proc rand_const():string = 6 | if rand(1)==0: ($rand(10.0))[0..3] else: "$1" 7 | 8 | if n!=0: 9 | case rand(3): 10 | of 0: &"{rand_expression(n-1)}+{rand_expression(n-1)}" 11 | of 1: &"{rand_expression(n-1)}*{rand_expression(n-1)}" 12 | of 2: &"({rand_expression(n-1)})" 13 | of 3: &"{funcNames.sample}({rand_expression(n)})" 14 | 15 | else: "" 16 | else: rand_const() 17 | 18 | when isMainModule: 19 | import strformat 20 | proc test_expression_pcode* = 21 | randomize() 22 | for i in 0..1000: 23 | let 24 | expr = rand_expression(6) 25 | code = expr.compile() 26 | x = rand(1.0) 27 | y = code.run([x]) 28 | 29 | echo &"{expr}({x})={y}" 30 | 31 | proc test_expression_llvm* = 32 | randomize() 33 | for i in 0..100: 34 | let xpr = rand_expression(7) 35 | let 36 | cfunc = compileLLVM("func" & $i, xpr) 37 | code = xpr.compile() 38 | x = rand(1.0)*1e-10 39 | y = cfunc(x) 40 | # echo &"{xpr}({x})={y}=={code.run([x])}" 41 | if y.classify != fcNan: 42 | echo &"{i}:{y}=={code.run([x])}, {xpr}" 43 | 44 | test_expression_llvm() 45 | 46 | -------------------------------------------------------------------------------- /lpc.nim: -------------------------------------------------------------------------------- 1 | # lpc: linear predictive coding 2 | 3 | import math 4 | 5 | type LPC = object 6 | count: int 7 | delayLine, impulseResponse, coefs: seq[float] 8 | 9 | # fwds 10 | proc getOutputSample*(lpc: var LPC, inputSample: float): float 11 | proc init*(lpc: var LPC) 12 | proc getCoefficients*(lpc: var LPC, p: int, x: seq[float]): seq[float] 13 | 14 | # methods 15 | proc newLPC*(): LPC = LPC() 16 | 17 | proc filter*(lpc: var LPC, y: seq[float], n: int): seq[float] = 18 | for i in 0..= lpc.coefs.len: lpc.count = 0 49 | 50 | proc getCoefficients*(lpc: var LPC, p: int, x: seq[float]): seq[float] = 51 | var r = newSeq[float](p+1) # = new double[p + 1] # size = 11 52 | let N = x.len # size = 256 53 | for T in 0..

28 | 29 | """ 30 | 31 | for c in lsystem: 32 | case c: 33 | of 'F': 34 | let (nx, ny) = (x + fwd_len * cos(alpha), y + fwd_len * sin(alpha)) 35 | svgFile.write &"\n" 36 | (x, y) = (nx, ny) 37 | 38 | of '-': alpha-=ang 39 | of '+': alpha+=ang 40 | 41 | of '[': stack.add (x,y,alpha) 42 | of ']': (x,y,alpha) = stack.pop 43 | 44 | else: discard 45 | 46 | 47 | svgFile.write "" 48 | svgFile.close() 49 | 50 | 51 | proc lsystem*(axiom:string, rules:Table[char, string], file_name:string, angle, niters:int, size, fwd_len:float, xdiv, ydiv:float)= 52 | ltransform(axiom, rules, niters).turtle_svg(file_name, size, size/xdiv, size/ydiv, angle, fwd_len) 53 | 54 | # examples 55 | proc koch1= 56 | ltransform(axiom="F--F--F", rules={'F':"F+F--F+F"}.toTable, niters=7). 57 | turtle_svg(file_name="svg/koch1.svg", angle=6, fwd_len=0.7, xdiv=8, ydiv=4) 58 | 59 | proc koch2= 60 | ltransform(axiom="F---F---F---F", rules={'F':"-F+++F---F+"}.toTable, niters=6). 61 | turtle_svg(file_name="svg/koch2.svg", angle=12, fwd_len=8, xdiv=6, ydiv=1.5) 62 | 63 | proc dragon= 64 | ltransform(axiom="FX", rules={'F':"", 'X':"-FX++FY-", 'Y':"+FX--FY+"}.toTable, niters=15). 65 | turtle_svg(file_name="svg/dragon.svg", angle=8, fwd_len=6, xdiv=3, ydiv=3) 66 | 67 | proc peano1= 68 | ltransform(axiom="F-F-F-F", rules={'F':"F-F+F+F+F-F-F-F+F"}.toTable, niters=4). 69 | turtle_svg(file_name="svg/peano1.svg", angle=4, fwd_len=8, xdiv=3, ydiv=6.0) 70 | 71 | proc flowsnake= 72 | ltransform(axiom="FL", rules={'F':"", 'L':"FL-FR--FR+FL++FLFL+FR-", 'R':"+FL-FRFR--FR-FL++FL+FR"}.toTable, niters=5). 73 | turtle_svg(file_name="svg/flowsnake.svg", angle=6, fwd_len=12, xdiv=3, ydiv=1.1) 74 | 75 | const 76 | Lsystem_samples* = [koch1, koch2, dragon, peano1, flowsnake] 77 | Lsystem_names* = ["koch1", "koch2", "dragon", "peano1", "flowsnake"] 78 | 79 | when isMainModule: 80 | import sequtils 81 | echo "generating lsystem samples" 82 | for (l,n) in zip(Lsystem_samples, Lsystem_names): 83 | echo n 84 | l() 85 | 86 | -------------------------------------------------------------------------------- /mandel_weave.nim: -------------------------------------------------------------------------------- 1 | # mandelbrot in weave, 50% faster than mandel32.nim 2 | 3 | import weave, complex_inline, times, pixie 4 | 5 | const fire_pallete: array[256, uint32] = [0'u32, 0, 4, 12, 16, 24, 32, 36, 44, 48, 56, 64, 68, 76, 80, 6 | 88, 96, 100, 108, 116, 120, 128, 132, 140, 148, 152, 160, 164, 172, 180, 184, 192, 200, 1224, 3272, 4300, 6348, 7376, 7 | 9424, 10448, 12500, 14548, 15576, 17624, 18648, 20700, 21724, 23776, 25824, 26848, 28900, 8 | 29924, 31976, 33000, 35048, 36076, 38124, 40176, 41200, 43248, 44276, 46324, 47352, 49400, 9 | 51452, 313596, 837884, 1363196, 1887484, 2412796, 2937084, 3461372, 3986684, 4510972, 5036284, 10 | 5560572, 6084860, 6610172, 7134460, 7659772, 8184060, 8708348, 9233660, 9757948, 10283260, 10807548, 11 | 11331836, 11857148, 12381436, 12906748, 13431036, 13955324, 14480636, 15004924, 15530236, 12 | 16054524, 16579836, 16317692, 16055548, 15793404, 15269116, 15006972, 14744828, 14220540, 13 | 13958396, 13696252, 13171964, 12909820, 12647676, 12123388, 11861244, 11599100, 11074812, 14 | 10812668, 10550524, 10288380, 9764092, 9501948, 9239804, 8715516, 8453372, 8191228, 7666940, 15 | 7404796, 7142652, 6618364, 6356220, 6094076, 5569788, 5307644, 5045500, 4783356, 4259068, 16 | 3996924, 3734780, 3210492, 2948348, 2686204, 2161916, 1899772, 1637628, 1113340, 851196, 17 | 589052, 64764, 63740, 62716, 61692, 59644, 58620, 57596, 55548, 54524, 53500, 51452, 50428, 18 | 49404, 47356, 46332, 45308, 43260, 42236, 41212, 40188, 38140, 37116, 36092, 34044, 33020, 19 | 31996, 29948, 28924, 27900, 25852, 24828, 23804, 21756, 20732, 19708, 18684, 16636, 15612, 20 | 14588, 12540, 11516, 10492, 8444, 7420, 6396, 4348, 3324, 2300, 252, 248, 244, 240, 236, 232, 21 | 228, 224, 220, 216, 212, 208, 204, 200, 196, 192, 188, 184, 180, 176, 172, 168, 164, 160, 156, 22 | 152, 148, 144, 140, 136, 132, 128, 124, 120, 116, 112, 108, 104, 100, 96, 92, 88, 84, 80, 76, 23 | 72, 68, 64, 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 0, 0] 24 | 25 | type 26 | Mandelbrot* = object 27 | w*, h*, iters: int32 28 | center*, range*: Complex32 29 | image*: seq[uint32] 30 | 31 | proc newMandelbrot*(w, h, iters: int32, center, range: Complex32): Mandelbrot = 32 | Mandelbrot(w: w, h: h, iters: iters, center: center, range: range, image: newSeq[uint32](w*h)) 33 | 34 | proc size*(m:Mandelbrot):int32 = m.w * m.h 35 | 36 | proc gen_pixel*(m: var Mandelbrot, index : int) = 37 | proc do_scale(m: Mandelbrot, cr: Complex32, i: int, j: int): Complex32 {.inline.} = 38 | cr + complex32( 39 | (m.range.im - m.range.re) * i.float32 / float32(m.w), 40 | (m.range.im - m.range.re) * j.float32 / float32(m.h)) 41 | 42 | let 43 | i = index %% m.w 44 | j = index div m.w 45 | scale : float32 = 0.8 * float32(m.w) / float32(m.h) 46 | cr = complex32(m.range.re, m.range.re) 47 | c0 : Complex32 = scale * m.do_scale(cr, i, j) - m.center 48 | 49 | var 50 | z : Complex32 = c0 51 | ix = m.iters 52 | 53 | for k in 0.. 4.0'f32: 56 | ix = k 57 | break 58 | 59 | m.image[index]= 0xff00_0000'u32 or ( 60 | if ix >= m.iters: 0'u32 61 | else: fire_pallete[((fire_pallete.len * ix) div 50) %% fire_pallete.len] 62 | ) 63 | 64 | proc write_image*(m:Mandelbrot, fn:string) = 65 | let image = newImage(m.w, m.h) 66 | image.data = cast[seq[ColorRGBX]](m.image) 67 | image.writeFile(fn) 68 | 69 | when isMainModule: 70 | let 71 | w : int32= 1024*4 72 | iters :int32= 200 73 | center = complex32(0.5, 0.0) 74 | rng = complex32(-2.0, 2.0) 75 | 76 | echo "mandelbrot ", w, "x", w, " iters:", iters 77 | 78 | var mandel = newMandelbrot(w, w, iters, center, rng) 79 | var t0 = now() 80 | 81 | # st mode 82 | # for index in 0.. 0: 22 | dec extra 23 | inc last 24 | result[i] = first ..< last 25 | first = last 26 | 27 | template par_exec() = 28 | let 29 | nth = countProcessors() 30 | chunks = chunk_ranges(v.len, nth) 31 | 32 | parallel: 33 | for chunk in chunks: 34 | spawn chunk_apply(fnc, chunk, v) 35 | 36 | proc par_apply*[T](v:var seq[T], fnc:proc(i:int):T)= # single 'i' index 37 | 38 | proc chunk_apply(fnc:proc(i:int):T, chunk:Slice[int], v:var seq[T]) = 39 | for index in chunk: 40 | v[index] = fnc(index) 41 | 42 | par_exec() 43 | 44 | proc par_apply*[T](v:var seq[T], fnc:proc(t, i:int):T)= # 't' thread number, 'i' index 45 | 46 | proc chunk_apply(fnc:proc(t, i:int):T, chunk:Slice[int], v:var seq[T]) = 47 | for index in chunk: 48 | v[index] = fnc(t, index) 49 | 50 | par_exec() 51 | 52 | when isMainModule: 53 | import sugar 54 | 55 | for r in chunk_ranges(7, 3): 56 | echo r, " ", r.len 57 | 58 | # par closure sample 59 | const n=100000 60 | var v=newSeq[int](n) 61 | 62 | par_apply(v, i => i) # set all to i 63 | echo v[0..5], v[^5..^1] 64 | 65 | assert v[0..3] == @[0,1,2,3] and v[^1]==n-1 66 | 67 | v.par_apply(x => x*2) # set all to i*2 68 | echo v[0..5], v[^5..^1] 69 | -------------------------------------------------------------------------------- /pi.nim: -------------------------------------------------------------------------------- 1 | # st/mt pi calc ratio 2 | 3 | import strutils, math, times, strformat 4 | import threadpool, cpuinfo 5 | {.experimental: "parallel".} 6 | 7 | # single thread version 8 | proc term(k: float): float = 4 * math.pow(-1, k) / (2*k + 1) 9 | 10 | proc st_pi(n: int): float = 11 | var ch = newSeq[float](n+1) 12 | for k in 0..ch.high: ch[k] = term(float(k)) 13 | for k in 0..ch.high: result += ch[k] 14 | 15 | 16 | # mt version 17 | 18 | func chunk_range*(size, i, nth: int): Slice[int] = 19 | let 20 | chunk_sz = size div nth 21 | rfrom = i * chunk_sz 22 | rto = if (i+1) * chunk_sz > size: size else: (i+1) * chunk_sz 23 | rfrom.. no nothing 28 | 29 | # string transform 30 | proc transform*(p: Polyhedron, tr: string, n: int = 0, f1: float = 0.1, 31 | f2: float = 0.0, limit_vertex = 10000): Polyhedron = 32 | const equiv = {'e': "aa", 'b': "ta", 'o': "jj", 'm': "k3j", 't': "dkd", 33 | 'j': "dad", 's': "dgd", }.toTable 34 | 35 | # replace all 'tr' with equiv 36 | var (trf, trw) = ("", tr) 37 | while trf != trw: 38 | trf = trw 39 | for c in trf: 40 | if c in equiv: 41 | trw = trw.replace($c, equiv[c]) 42 | 43 | result = p 44 | for t in trw.reversed: 45 | if result.vertex.len > limit_vertex: break 46 | result.transform(t, n, f1, f2) 47 | 48 | # scan tt..tP 49 | proc transform*(s: string): Polyhedron = 50 | transform(polychar(s[^1]), s[0 .. ^2]) # last char is poly seed rest in transformation 51 | 52 | const nice_trans = "PcdPqxT,gadPkI,gHqgI,ncrHI,rrkHqlO,wcplD,HxHqI,wggkpD,xlHxqC,lqqqD,rPnPT,aPcdkpI,HlkwD,HcdC,awxaI,nrkHwO,dpaadkI,qdpnqC,PHckD,HqakrpO,rkqkI,wHgPaD,nkkrcPaO,glrHPO,nHrxHC,lqkawpC,PncPxO,alawnwrT,akqlC,xdqdlxT,HddaD,qkpPlD,nPPkwT,HgpgD,dwwaI,dqwgC,HkaxC,PdrkD,lqgalD,PcdPqxT,gadPkI,gHqgI,ncrHI,rrkHqlO,qkcxC,PqlkgD,xHPwC,kdpalI,waadI,rndPdO,cwPakkT,PPdpqO,HdgqI,pwPHD,qkPPI,knwwlO,dPPnqC,PHkwlT,pHncD,llPgI,cHcT,wwaknaT,PHddcxI,HqgaPO,rndPdO,cwPakkT,PPdpqO,HdgqI,pwPHD,qkPPI,knwwlO,dPPnqC,PHkwlT,pHncD,llPgI,cHcT,wwaknaT,kcklI,dlldI,qPxgwT,HnHqkkT,HlggkC,qpkHgC,xxrngacO,nrllkHD,wqPaD,ppHHD,HHgaI,cgcwD,nPnPdrO,lxdqPI,gdnkgpD,qxPpI,knHnrkD,PPnxlO,kkPawdI,PrPqC,PdPlD,qqqacC,PllxI,HqaaD,kHqPD,dPkkkrqT,gaqdPqD,nxrrC,PqrkgaI,nqldkdC,PlcPrD,glqPI,klpxxC,PnqxO,PPlcO,xllnqO,pdPldxkC,nrrPnD,ldHqxwO,xHkaI,kaHqkwD,aPxxwckT,kwrnHC,dPxrcT,qPrlpD,qdwwlD,qdcwI,HqqHrC,nxqqaD,wkglaI,nrccI,pagwO,aqkpD,HPprO,nnHprnC,dkqgqO,rndPdO,nHxrT,rHcwwO,qxcwO,HplnrrcD,HrHHdD,lxkwnqO,xqPndD,ndgdaD,nHnkC,qdwwlD,qqldgC,HaaqqkO,PakcO,qxrHclC,gkaPI,ddgkwlO,nqawprPO,gdPwlcD,ldwPllgC,xwgkD,clxwaqO,HacrD,kcklI,gpxnD,qndcaO,qPcrO,nddPnO,HPaaD,ndkwawlC,PanaT,arckrqaC" 53 | 54 | proc rand_preset*: string = 55 | let trs = nice_trans.split(',') 56 | result = trs[rand(trs.high)] 57 | 58 | proc rand_transform*: string = 59 | const 60 | trs = "agprdwqPkcnxlH" 61 | seeds = "TCIOD" 62 | 63 | for i in 0..3+rand(3): 64 | result &= trs[rand(trs.high)] 65 | result &= seeds[rand(seeds.high)] 66 | 67 | 68 | when isMainModule: 69 | randomize() 70 | for i in 0..10: 71 | echo rand_transform() 72 | -------------------------------------------------------------------------------- /poly/vertex.nim: -------------------------------------------------------------------------------- 1 | # Vertex 2 | 3 | import math 4 | 5 | type Vertex* = array[3, float] 6 | const zeroVertex* =[0.0, 0.0, 0.0] 7 | 8 | # vertex ops 9 | 10 | proc cross*(v0, v1: Vertex): Vertex {.inline.} = [(v0[1] * v1[2]) - (v0[2] * v1[ 11 | 1]), (v0[2] * v1[0]) - (v0[0] * v1[2]), (v0[0] * v1[1]) - (v0[1] * v1[0])] 12 | 13 | proc dot*(v0, v1: Vertex): float {.inline.} = v0[0]*v1[0]+v0[1]*v1[1]+v0[2]*v1[2] 14 | 15 | proc distance_squared*(v0, v1: Vertex): float {.inline.} = dot(v0,v1) 16 | proc distance*(v0, v1: Vertex): float {.inline.} = dot(v0, v1).sqrt 17 | 18 | proc `+`*(v0, v1: Vertex): Vertex {.inline.} = [v0[0]+v1[0], v0[1]+v1[1], v0[2]+v1[2]] 19 | proc `+`*(v0: Vertex, f:float): Vertex {.inline.} = [v0[0]+f, v0[1]+f, v0[2]+f] 20 | 21 | proc `-`*(v0, v1: Vertex): Vertex {.inline.} = [v0[0]-v1[0], v0[1]-v1[1], v0[2]-v1[2]] 22 | proc `-`*(v0: Vertex, f:float): Vertex {.inline.} = [v0[0]-f, v0[1]-f, v0[2]-f] 23 | 24 | proc `-`*(v:Vertex) : Vertex = [-v[0], -v[1], -v[2]] 25 | 26 | proc `*`*(v0: Vertex, f: float): Vertex {.inline.} = [v0[0]*f, v0[1]*f, v0[2]*f] 27 | proc `*`*(v0, v1: Vertex): float {.inline.} = v0.dot(v1) 28 | proc `**`*(v0, v1: Vertex): Vertex {.inline.} = v0.cross(v1) 29 | 30 | proc `/`*(v0: Vertex, c: float): Vertex {.inline.} = [v0[0]/c, v0[1]/c, v0[2]/c] 31 | proc `/=`*(v0: var Vertex, c: float) {.inline.} = 32 | v0[0]/=c 33 | v0[1]/=c 34 | v0[2]/=c 35 | 36 | proc `+=`*(v0: var Vertex, v1: Vertex) {.inline.} = 37 | v0[0]+=v1[0] 38 | v0[1]+=v1[1] 39 | v0[2]+=v1[2] 40 | 41 | proc max_abs*(v:Vertex):float = v[0].abs.max(v[1].abs.max(v[2].abs)) 42 | proc normal*(v0, v1, v2: Vertex): Vertex {.inline.} = cross(v1 - v0, v2 - v1) 43 | 44 | proc unit*(v: Vertex): Vertex {.inline.} = 45 | if v == [0.0, 0.0, 0.0]: v 46 | else: v / dot(v, v).sqrt 47 | 48 | proc midpoint*( vec1, vec2 : Vertex) : Vertex = (vec1 + vec2) / 2.0 49 | 50 | proc tween*(v1, v2 : Vertex, t : float) : Vertex = 51 | (v1 * (1.0 - t) ) + (v2 * t) 52 | 53 | proc oneThird*(v1, v2 : Vertex) : Vertex = 54 | tween(v1, v2, 1.0 / 3.0) -------------------------------------------------------------------------------- /poly_32/par.nim: -------------------------------------------------------------------------------- 1 | # parallel work 2 | # par.nim 3 | 4 | import threadpool, cpuinfo 5 | 6 | {.experimental: "parallel".} 7 | setMaxPoolSize(countProcessors()) 8 | 9 | # adapted from distribute 10 | proc par_ranges*(size, n : int32):seq[Slice[int32]]= # Create the result and calculate the stride size and the remainder if any. 11 | var 12 | stride = size div n 13 | first :int32= 0 14 | last :int32= 0 15 | extra = size mod n 16 | 17 | result = newSeq[Slice[int32]](n)# Use an undercounting algorithm which *adds* the remainder each iteration. 18 | 19 | for i in 0 ..< n: 20 | last = first + stride 21 | if extra > 0: 22 | dec extra 23 | inc last 24 | result[i] = first ..< last 25 | first = last 26 | 27 | proc par_ranges*[T](v:seq[T]):seq[Slice[int32]]= # seq[from..to] 28 | par_ranges(v.len.int32, countProcessors().int32) 29 | proc par_ranges*(l:int32):seq[Slice[int32]]= # seq[from..to] 30 | par_ranges(l, countProcessors().int32) 31 | 32 | template par_exec(chunk_apply, fnc, v) = 33 | let 34 | nth = countProcessors() 35 | chunks = par_ranges(v.len.int32, nth) 36 | 37 | parallel: 38 | for chunk in chunks: 39 | spawn chunk_apply(fnc, chunk, v) 40 | 41 | proc par_apply*[T](v:var seq[T], fnc:proc(i:int32):T)= # single 'i' index 42 | proc chunk_apply(fnc:proc(i:int32):T, chunk:Slice[int32], v:var seq[T]) = 43 | for index in chunk: 44 | v[index] = fnc(index) 45 | par_exec(chunk_apply, fnc, v) 46 | 47 | proc par_apply*[T](v:var seq[T], fnc:proc(t, i:int32):T)= # 't' thread number, 'i' index 48 | proc chunk_apply(fnc:proc(t, i:int32):T, chunk:Slice[int32], v:var seq[T]) = 49 | for index in chunk: 50 | v[index] = fnc(t, index) 51 | par_exec(chunk_apply, fnc, v) 52 | 53 | proc par_iter*[T](v:var seq[T], fnc:proc(v:var seq[T], r:Slice[int32]))= # 't' thread number, 'i' index 54 | proc chunk_apply(fnc:proc(v:var seq[T], r:Slice[int32]), chunk:Slice[int32], v:var seq[T]) = 55 | fnc(v, r) 56 | par_exec(chunk_apply, fnc, v) 57 | 58 | -------------------------------------------------------------------------------- /poly_32/parser.nim: -------------------------------------------------------------------------------- 1 | # transformation string parser 2 | import algorithm, tables, strutils, random 3 | import common, transform 4 | 5 | # seed char to poly 6 | proc polychar*(c: char): Polyhedron = 7 | const ptab = {'T': Tetrahedron, 'C': Cube, 'H': Hexahedron, 8 | 'I': Icosahedron, 'O': Octahedron, 'D': Dodecahedron}.toTable 9 | ptab.getOrDefault(c) 10 | 11 | # char transform to poly 12 | proc transform*(p: var Polyhedron, t: char, n: int32 = 0, f1: float32 = 0.0, 13 | f2: float32 = 0.0) = 14 | const tr_tab = {'a': ambo, 'g': gyro, 'p': propellor, 'r': reflection, 15 | 'd': dual, 'w': whirl, 'q': quinto, 'P': perspectiva1}.toTable 16 | 17 | if t in tr_tab: p = tr_tab[t](p) 18 | else: 19 | case t: 20 | of 'k': p = p.kisN # (n, f1) 21 | of 'c': p = p.chamfer # (f1) 22 | of 'n': p = p.insetN # (n, f1, f2) 23 | of 'x': p = p.extrudeN # (n) 24 | of 'l': p = p.loft # (n, f1) 25 | of 'H': p = p.hollow # (f1,f2) 26 | 27 | else: discard # error -> no nothing 28 | 29 | # string transform 30 | proc transform*(p: Polyhedron, tr: string, n: int32 = 0, f1: float32 = 0.1, 31 | f2: float32 = 0.0, limit_vertex:int32): Polyhedron = 32 | const equiv = {'e': "aa", 'b': "ta", 'o': "jj", 'm': "k3j", 't': "dkd", 33 | 'j': "dad", 's': "dgd", }.toTable 34 | 35 | # replace all 'tr' with equiv 36 | var (trf, trw) = ("", tr) 37 | while trf != trw: 38 | trf = trw 39 | for c in trf: 40 | if c in equiv: 41 | trw = trw.replace($c, equiv[c]) 42 | 43 | result = p 44 | for t in trw.reversed: 45 | if result.vertex.len > limit_vertex: break 46 | result.transform(t, n, f1, f2) 47 | 48 | # scan tt..tP 49 | proc transform*(s: string, limit_vertex :int32): Polyhedron = 50 | transform(polychar(s[^1]), s[0 .. ^2], limit_vertex = limit_vertex ) # last char is poly seed rest in transformation 51 | 52 | const nice_trans = "PcdPqxT,gadPkI,gHqgI,ncrHI,rrkHqlO,wcplD,HxHqI,wggkpD,xlHxqC,lqqqD,rPnPT,aPcdkpI,HlkwD,HcdC,awxaI,nrkHwO,dpaadkI,qdpnqC,PHckD,HqakrpO,rkqkI,wHgPaD,nkkrcPaO,glrHPO,nHrxHC,lqkawpC,PncPxO,alawnwrT,akqlC,xdqdlxT,HddaD,qkpPlD,nPPkwT,HgpgD,dwwaI,dqwgC,HkaxC,PdrkD,lqgalD,PcdPqxT,gadPkI,gHqgI,ncrHI,rrkHqlO,qkcxC,PqlkgD,xHPwC,kdpalI,waadI,rndPdO,cwPakkT,PPdpqO,HdgqI,pwPHD,qkPPI,knwwlO,dPPnqC,PHkwlT,pHncD,llPgI,cHcT,wwaknaT,PHddcxI,HqgaPO,rndPdO,cwPakkT,PPdpqO,HdgqI,pwPHD,qkPPI,knwwlO,dPPnqC,PHkwlT,pHncD,llPgI,cHcT,wwaknaT,kcklI,dlldI,qPxgwT,HnHqkkT,HlggkC,qpkHgC,xxrngacO,nrllkHD,wqPaD,ppHHD,HHgaI,cgcwD,nPnPdrO,lxdqPI,gdnkgpD,qxPpI,knHnrkD,PPnxlO,kkPawdI,PrPqC,PdPlD,qqqacC,PllxI,HqaaD,kHqPD,dPkkkrqT,gaqdPqD,nxrrC,PqrkgaI,nqldkdC,PlcPrD,glqPI,klpxxC,PnqxO,PPlcO,xllnqO,pdPldxkC,nrrPnD,ldHqxwO,xHkaI,kaHqkwD,aPxxwckT,kwrnHC,dPxrcT,qPrlpD,qdwwlD,qdcwI,HqqHrC,nxqqaD,wkglaI,nrccI,pagwO,aqkpD,HPprO,nnHprnC,dkqgqO,rndPdO,nHxrT,rHcwwO,qxcwO,HplnrrcD,HrHHdD,lxkwnqO,xqPndD,ndgdaD,nHnkC,qdwwlD,qqldgC,HaaqqkO,PakcO,qxrHclC,gkaPI,ddgkwlO,nqawprPO,gdPwlcD,ldwPllgC,xwgkD,clxwaqO,HacrD,kcklI,gpxnD,qndcaO,qPcrO,nddPnO,HPaaD,ndkwawlC,PanaT,arckrqaC" 53 | 54 | proc rand_preset*: string = 55 | let trs = nice_trans.split(',') 56 | result = trs[rand(trs.high)] 57 | 58 | proc rand_transform*: string = 59 | const 60 | trs = "agprdwqPkcnxlH" 61 | seeds = "TCIOD" 62 | 63 | for i in 0..3+rand(3): 64 | result &= trs[rand(trs.high)] 65 | result &= seeds[rand(seeds.high)] 66 | 67 | 68 | when isMainModule: 69 | randomize() 70 | for i in 0..10: 71 | echo rand_transform() 72 | -------------------------------------------------------------------------------- /poly_32/ui_gl.nim: -------------------------------------------------------------------------------- 1 | # ui_gl.nim 2 | import opengl/glut, opengl, opengl/glu 3 | 4 | const CompiledScene = 1 5 | 6 | var 7 | anglex {.global.}= 0.0 8 | angley {.global.}= 0.0 9 | iters {.global.}= 0 10 | zoom {.global.} = -4.0 11 | lastx {.global.}= 0 12 | lasty {.global.}= 0 13 | 14 | proc draw_scene()= 15 | glutWireTeapot(0.5f64) 16 | 17 | proc reshape(width: GLsizei, height: GLsizei) {.cdecl.} = 18 | if height != 0: 19 | glViewport(0, 0, width, height) 20 | glMatrixMode(GL_PROJECTION) # To operate on the Projection matrix 21 | glLoadIdentity() # Reset 22 | gluPerspective(45.0, width / height, 0.1, 100.0) 23 | 24 | proc mouseDrag(x,y:GLint) {.cdecl.} = 25 | let d = 2.0 26 | angley += (x-lastx).float32 / d 27 | anglex += (y-lasty).float32 / d 28 | 29 | lastx=x 30 | lasty=y 31 | 32 | proc mouseWheel(button, dir, x,y:GLint) {.cdecl.} = 33 | case button: 34 | of 3: zoom-=0.1 35 | of 4: zoom+=0.1 36 | else: discard 37 | 38 | proc keyhook(key:GLbyte, x,y:GLint) {.cdecl.} = 39 | case key.char: 40 | of 'q': quit(1) 41 | else: quit(1) 42 | 43 | 44 | proc display() {.cdecl.} = 45 | glClear(GL_COLOR_BUFFER_BIT or 46 | GL_DEPTH_BUFFER_BIT) # Clear color and depth buffers 47 | glMatrixMode(GL_MODELVIEW) # To operate on model-view matrix 48 | glLoadIdentity() # Reset the model-view matrix 49 | glTranslatef(0.0, 0.0, zoom) # zoom 50 | glColor3f(1.0, 1.0, 1.0) 51 | 52 | glRotatef(anglex, 1.0, 0.0, 0.0) 53 | glRotatef(-angley, 0.0, 1.0, 0.0) 54 | 55 | inc iters 56 | 57 | glCallList(CompiledScene) 58 | 59 | glutSwapBuffers() 60 | glutPostRedisplay() # animate 61 | 62 | var argc: cint = 0 63 | glutInit(addr argc, nil) 64 | glutInitDisplayMode(GLUT_DOUBLE) 65 | glutInitWindowSize(1200, 1200) 66 | glutInitWindowPosition(500, 500) 67 | discard glutCreateWindow("gl ui") 68 | 69 | 70 | glutDisplayFunc(display) 71 | glutReshapeFunc(reshape) 72 | glutKeyboardFunc(keyhook) 73 | glutMouseFunc(mouseWheel) 74 | glutMotionFunc(mouseDrag) 75 | glutPassiveMotionFunc(mouseDrag) 76 | 77 | loadExtensions() 78 | 79 | glNewList(CompiledScene, GL_COMPILE) # list 1 is scene 80 | draw_scene() 81 | glEndList() 82 | 83 | glClearColor(0.0, 0.0, 0.0, 1.0) # Set background color to black and opaque 84 | glClearDepth(1.0) # Set background depth to farthest 85 | glEnable(GL_DEPTH_TEST) # Enable depth testing for z-culling 86 | glDepthFunc(GL_LEQUAL) # Set the type of depth-test 87 | glShadeModel(GL_SMOOTH) # Enable smooth shading 88 | glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) # Nice perspective corrections 89 | 90 | glutMainLoop() 91 | -------------------------------------------------------------------------------- /poly_32/vertex.nim: -------------------------------------------------------------------------------- 1 | # Vertex 2 | 3 | import math 4 | 5 | type Vertex* = array[3, float32] 6 | const zeroVertex* =[0.0'f32, 0.0, 0.0] 7 | 8 | # vertex ops 9 | 10 | proc cross*(v0, v1: Vertex): Vertex {.inline.} = [(v0[1] * v1[2]) - (v0[2] * v1[ 11 | 1]), (v0[2] * v1[0]) - (v0[0] * v1[2]), (v0[0] * v1[1]) - (v0[1] * v1[0])] 12 | 13 | proc dot*(v0, v1: Vertex): float32 {.inline.} = v0[0]*v1[0]+v0[1]*v1[1]+v0[2]*v1[2] 14 | 15 | proc distance_squared*(v0, v1: Vertex): float32 {.inline.} = dot(v0,v1) 16 | proc distance*(v0, v1: Vertex): float32 {.inline.} = dot(v0, v1).sqrt 17 | 18 | proc `+`*(v0, v1: Vertex): Vertex {.inline.} = [v0[0]+v1[0], v0[1]+v1[1], v0[2]+v1[2]] 19 | proc `+`*(v0: Vertex, f:float32): Vertex {.inline.} = [v0[0]+f, v0[1]+f, v0[2]+f] 20 | 21 | proc `-`*(v0, v1: Vertex): Vertex {.inline.} = [v0[0]-v1[0], v0[1]-v1[1], v0[2]-v1[2]] 22 | proc `-`*(v0: Vertex, f:float32): Vertex {.inline.} = [v0[0]-f, v0[1]-f, v0[2]-f] 23 | 24 | proc `-`*(v:Vertex) : Vertex = [-v[0], -v[1], -v[2]] 25 | 26 | proc `*`*(v0: Vertex, f: float32): Vertex {.inline.} = [v0[0]*f, v0[1]*f, v0[2]*f] 27 | proc `*`*(v0, v1: Vertex): float32 {.inline.} = v0.dot(v1) 28 | proc `**`*(v0, v1: Vertex): Vertex {.inline.} = v0.cross(v1) 29 | 30 | proc `/`*(v0: Vertex, c: float32): Vertex {.inline.} = [v0[0]/c, v0[1]/c, v0[2]/c] 31 | proc `/=`*(v0: var Vertex, c: float32) {.inline.} = 32 | v0[0]/=c 33 | v0[1]/=c 34 | v0[2]/=c 35 | 36 | proc `+=`*(v0: var Vertex, v1: Vertex) {.inline.} = 37 | v0[0]+=v1[0] 38 | v0[1]+=v1[1] 39 | v0[2]+=v1[2] 40 | 41 | proc max_abs*(v:Vertex):float32 = v[0].abs.max(v[1].abs.max(v[2].abs)) 42 | proc normal*(v0, v1, v2: Vertex): Vertex {.inline.} = cross(v1 - v0, v2 - v1) 43 | 44 | proc unit*(v: Vertex): Vertex {.inline.} = 45 | if v == [0.0'f32, 0.0, 0.0]: v 46 | else: v / dot(v, v).sqrt 47 | 48 | proc midpoint*( vec1, vec2 : Vertex) : Vertex = (vec1 + vec2) / 2.0 49 | 50 | proc tween*(v1, v2 : Vertex, t : float32) : Vertex = 51 | (v1 * (1.0 - t) ) + (v2 * t) 52 | 53 | proc oneThird*(v1, v2 : Vertex) : Vertex = 54 | tween(v1, v2, 1.0 / 3.0) -------------------------------------------------------------------------------- /poly_roots_duran_kerner.nim: -------------------------------------------------------------------------------- 1 | # polyroot uses the Durand-Kerner method to find all roots (real and complex) of a polynomial of the form: 2 | # f(x) = pow(x, n) + a1*pow(x, n - 1) + a2*pow(x, n - 2) + . . . + a(n - 2)*x*x + a(n - 1)*x + a(n) 3 | # where the vector A = a1, a2, a3, . . . , a(n - 2), a(n - 1), a(n) 4 | 5 | import complex, algorithm 6 | 7 | proc eval_poly*(coeff:seq[float], x : Complex64) : Complex64 = 8 | let n = coeff.high 9 | var p = x 10 | result = complex64(coeff[n],0) 11 | for i in 1..n: 12 | result += coeff[n - i] * p 13 | p *= x 14 | 15 | proc roots*(A : seq[float]) : seq[Complex64] = 16 | proc poly(A : seq[float], x : Complex64) : Complex64 = 17 | let n = A.len 18 | var p = complex64(1,0) 19 | result = complex64(0,0) 20 | for i in 0..::epsilon() 6 | 7 | converter ftoc(f: float): Complex64 = complex64(f, 0.0) 8 | 9 | proc polarc(p:Complex64): Complex64 = complex64(p.polar.r, p.polar.phi) 10 | 11 | # real coeff 12 | proc zroots*(a: seq[float], roots: var seq[Complex64], polish: bool) = 13 | proc laguer(a: seq[Complex64], x: var Complex64, its: var int) = 14 | const 15 | MR = 8 16 | MT = 10 17 | MAXIT = MT * MR 18 | frac = [0.0, 0.5, 0.25, 0.75, 0.13, 0.38, 0.62, 0.88, 1.0] 19 | 20 | let m = a.len - 1 21 | 22 | for iter in 1..MAXIT: 23 | its = iter 24 | 25 | var 26 | b = a[m] 27 | err = b.abs 28 | d, f : Complex64 29 | abx = x.abs 30 | 31 | for j in countdown(m - 1, 0): 32 | f = x * f + d 33 | d = x * d + b 34 | b = x * b + a[j] 35 | err = b.abs + abx * err 36 | 37 | err *= EPS 38 | if b.abs <= err: return 39 | 40 | var 41 | g = d / b 42 | g2 = g * g 43 | h = g2 - 2.0 * f / b 44 | sq = ((m - 1).float * (m.float * h - g2)).sqrt 45 | gp = g + sq 46 | gm = g - sq 47 | 48 | abp = gp.abs 49 | abm = gm.abs 50 | 51 | if abp < abm: gp = gm 52 | 53 | var dx = if max(abp, abm) > 0: m.float / gp 54 | else: complex64(1 + abx, iter.float).polarc 55 | 56 | var x1 = x - dx 57 | if x == x1: return 58 | 59 | if iter %% MT != 0: x = x1 60 | else: x -= frac[iter div MT] * dx 61 | 62 | raise newException(ArithmeticDefect, "roots not found, too many iterations in laguer") 63 | 64 | var 65 | its: int 66 | m = a.len - 1 67 | ad = newSeq[Complex64](m+1) 68 | ac = a.map(x => x.ftoc) 69 | 70 | for j in 0..m: ad[j] = a[j] 71 | 72 | for j in countdown(m-1, 0): 73 | var 74 | x : Complex64 75 | ad_v = ad[0.. mx: 22 | mx = y[i] 23 | pi = i 24 | (pi.float, mx) 25 | 26 | proc index2freq(i, sample_rate:float, nfft:int) : float = 27 | i.float * (sample_rate / nfft.float) 28 | 29 | proc freq2index(freq, sample_rate : float, nfft:int) : int = 30 | freq.int div (sample_rate / nfft.float / 2).int 31 | 32 | proc db(c : Complex) : float = 33 | result = 20.0 * ((1.0 / c).abs + 1e-16).log10 # power in db 34 | if result.classify == fcNaN or result.classify == fcInf: result = 0 35 | 36 | proc peaks(v : seq[float]) : seq[Wave] = 37 | for i in 1..v.high-1: 38 | if v[i]>v[i-1] and v[i]>v[i+1]: 39 | result.add( (i.float, v[i]) ) 40 | 41 | proc peaks(v : seq[Wave]) : seq[Wave] = 42 | for i in 1..v.high-1: 43 | if v[i].pwr > v[i-1].pwr and v[i].pwr > v[i+1].pwr: 44 | result.add(v[i]) 45 | 46 | proc v2v(wav_file:string, nfft : int, npeaks : int = 30) : seq[Wave] = 47 | let wav = read_wav[float](wav_file) 48 | var 49 | fft = fft(nfft) 50 | y = newSeq[float](nfft) 51 | 52 | for i in countup(0, wav.samples.high, nfft): # acc. fft 53 | let vto = i+nfft 54 | if vto > wav.samples.len: break 55 | fft.exec(wav.samples[i.. x.pwr > 0.4 and x.freq < wav.sample_rate / 2).sorted(cmp_pwr) 75 | 76 | proc v2v(samples:seq[float], sample_rate:float):seq[Wave]= 77 | var (formants, freqresp) = formants(samples, sample_rate) 78 | formants = formants.sorted(cmp_bw).deduplicate[0..6].sorted(cmp_hz) 79 | var 80 | minpwr=formants[0].pwr 81 | maxpwr=minpwr 82 | 83 | for f in formants: 84 | maxpwr=max(maxpwr, f.pwr) 85 | minpwr=min(minpwr, f.pwr) 86 | 87 | result.add((freq : f.hz, pwr : f.pwr)) 88 | 89 | for f in result.mitems: 90 | f.pwr = ((maxpwr - f.pwr + minpwr) - minpwr) / (maxpwr - minpwr) 91 | 92 | 93 | when isMainModule: 94 | proc gen_wave(wave: seq[Wave], sample_rate: float, 95 | n_samples: int): seq[float] = 96 | result = newSeq[float](n_samples) 97 | for i, v in result.mpairs: 98 | var s = 0.0 99 | for j, w in wave.pairs: 100 | s += w.pwr * sin(2 * PI * w.freq * i.float / sample_rate) 101 | v = s / wave.len.float 102 | 103 | proc test_fft_v2v= 104 | echo "v2v" 105 | let 106 | nfft = 1024*4 107 | pks = v2v(wav_file = "test.wav", nfft = nfft, npeaks=100) 108 | 109 | for p in pks: 110 | echo p 111 | 112 | proc test_fmts_v2v= 113 | echo "v2v based on formants" 114 | let wav = read_wav[float]("test.wav") 115 | let v2v=v2v(wav.samples, wav.sample_rate.float) 116 | echo v2v 117 | echo"generating v2v.wav", write_wav[float]("v2v.wav", 1, 22050, gen_wave(v2v, 22050, 30000)) 118 | 119 | 120 | test_fmts_v2v() -------------------------------------------------------------------------------- /vec.nim: -------------------------------------------------------------------------------- 1 | #[ 2 | basic unsafe vec ptr based with len(int) at p[0] 3 | usage: 4 | var v=vec[float](100) 5 | 6 | for i, vi in v.mpairs: vi=i.float 7 | for vi in v: echo vi 8 | v.free 9 | 10 | ]# 11 | 12 | import sugar 13 | 14 | type Vec*[t] = ptr t 15 | 16 | {.push checks: off, line_dir: off, stack_trace: off, debugger: off, inline: on.} 17 | 18 | 19 | # access data item p + int.size + i*t.size 20 | proc data*[t](p: ptr t, i:int): ptr t = cast[ptr t](cast[int](p) + int.sizeof + i*t.sizeof) 21 | 22 | # indexers 23 | proc `[]`*[t](p: ptr t, i: int): t = p.data(i)[] 24 | 25 | proc `[]`*[t](p: ptr t, s: Slice[int]): seq[t] = # [a..b] 26 | collect(newSeq): 27 | for i in s: p[i] 28 | 29 | proc `[]=`*[t](p: ptr t, i: int, val: t) = cast[ptr t](cast[int](p) + int.sizeof + i*t.sizeof)[] = val 30 | 31 | # address of len, i.e. p[0] 32 | proc ptr_n[t](p: ptr t): ptr int = cast[ptr int](p) 33 | 34 | proc set_len[t](p: ptr t, n: int) = ptr_n(p)[] = n 35 | 36 | # constructor 37 | proc vec*[t](n: int): ptr t = 38 | var p = cast[ptr t](alloc0(n*t.sizeof+int.sizeof)) 39 | p.set_len n 40 | p 41 | 42 | proc len*[t](p: ptr t): int = ptr_n(p)[].int 43 | 44 | proc low*[t](p: ptr t): int = 0 45 | 46 | proc high*[t](p: ptr t): int = 47 | if p.len==0: 0 else: p.len-1 48 | 49 | proc mid*[t](p: ptr t): int = p.len div 2 50 | 51 | proc first*[t](p: ptr t, n: int): seq[t] = 52 | collect(newSeq): 53 | for i in 0..b[0]: return false 37 | if a[1]b[1]: return false 39 | if a[2] gen_pixel(i %% w, i div w, points)) 49 | 50 | proc image_bytes(v:Voronoi):int {.inline.} = v.image.len * sizeof(v.image[0]) 51 | 52 | proc write*(v: Voronoi, fn: string) = # write image to binary file 53 | var f = newFileStream(fn, fmWrite) 54 | if not f.isNil: 55 | f.writeData(v.image[0].unsafeAddr, v.image_bytes) 56 | f.close() 57 | 58 | proc write_image*(m:Voronoi, fn:string) = 59 | let image = newImage(m.w, m.h) 60 | image.data = cast[seq[ColorRGBX]](m.image) 61 | image.writeFile(fn) 62 | 63 | proc newVoronoi*(w, h, n: int): Voronoi = 64 | randomize() 65 | result = Voronoi(w: w, h: h) 66 | 67 | # generate x,y:rand(w,h), color:rand(max int32) 68 | result.points = toSeq(0.. Point(x: rand(w), y: rand(h), 69 | color: uint32(rand(0x00ff_ffff)))) 70 | 71 | # mt mode 72 | result.gen_image() 73 | 74 | 75 | when isMainModule: 76 | let 77 | w = 1000 78 | h = w 79 | n = w div 2 80 | 81 | echo fmt("Voronoi {w}x{w}x{n} with {countProcessors()} cpu...") 82 | let t0 = now() 83 | 84 | let voronoi = newVoronoi(w, h, n) 85 | 86 | echo fmt("lap:{(now()-t0).inMilliseconds()}ms") 87 | 88 | voronoi.write_image("voronoi.png") 89 | -------------------------------------------------------------------------------- /voronoi_weave.nim: -------------------------------------------------------------------------------- 1 | # voronoi using weave for parallel generation 2 | 3 | import weave, sequtils, random, sugar, times, strformat, pixie 4 | 5 | proc box[T](x: T): ref T {.inline.} = new(result); result[] = x # obj to ref conversion 6 | 7 | type 8 | Point = object 9 | x, y: int 10 | color: uint32 11 | Voronoi = object 12 | w, h: int 13 | points: seq[Point] 14 | image: seq[uint32] 15 | 16 | proc get_size(v:Voronoi):int = v.w * v.h 17 | 18 | proc newVoronoi*(w, h, n: int): Voronoi = 19 | randomize() 20 | Voronoi( 21 | w: w, h: h, 22 | image : newSeq[uint32](w*h), 23 | points : toSeq(0.. Point(x: rand(w), y: rand(h), color: uint32(rand(0x00ff_ffff))))) 24 | 25 | proc distance_sqr(x, y:int, p:Point): int = 26 | proc sqr(x:int):int = x*x 27 | sqr(x-p.x) + sqr(y-p.y) 28 | 29 | proc generate_pixel*(voronoi:var Voronoi, index:int)= 30 | let 31 | i = index %% voronoi.w 32 | j = index div voronoi.w 33 | 34 | var 35 | dist = int.high 36 | is_center = false 37 | ind = 0 38 | 39 | for p in 1..voronoi.points.high: 40 | let d = distance_sqr(i, j, voronoi.points[p]) 41 | 42 | if d < 2: 43 | is_center = true 44 | break 45 | 46 | if d < dist: 47 | dist = d 48 | ind = p 49 | 50 | voronoi.image[index]=0xff00_0000'u32 or (if is_center: 0'u32 else: voronoi.points[ind].color) 51 | 52 | proc write_image*(v:Voronoi, fn:string) = 53 | assert v.image.len==v.get_size 54 | let image = newImage(v.w, v.h) 55 | image.data = cast[seq[ColorRGBX]](v.image) 56 | image.writeFile(fn) 57 | 58 | when isMainModule: 59 | let 60 | w = 1024*2 61 | n = w div 2 62 | 63 | var voronoi = newVoronoi(w,w,n) # use a ref in parallelFor 64 | 65 | 66 | echo fmt"voronoi {w}x{w}x{n}..." 67 | 68 | Weave.init() 69 | 70 | let t0=now() 71 | 72 | let voronoi_ptr = voronoi.addr 73 | parallelFor index in 0..The information stored for each face consists of a planar 6 | * normal, a planar offset, and a doubly-linked list of three HalfEdges which surround the face in a 8 | * counter-clockwise direction. 9 | * 10 | * @author John E. Lloyd, Fall 2004 */ 11 | 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | using std::vector; 19 | using std::string; 20 | 21 | class Vertex; 22 | class HalfEdge; 23 | class Point3d; 24 | class Vector3d; 25 | class Vertex; 26 | class FaceList; 27 | 28 | class Face 29 | { 30 | #define null NULL 31 | public: 32 | HalfEdge *he0=null; 33 | 34 | double area=0; 35 | 36 | double planeOffset=0; 37 | int index=0; 38 | int numVerts=0; 39 | 40 | Face *next=null; 41 | 42 | static const int VISIBLE = 1; 43 | static const int NON_CONVEX = 2; 44 | static const int DELETED = 3; 45 | int mark = VISIBLE; 46 | 47 | Vertex *outside=null; 48 | 49 | private: 50 | Point3d *centroid=null; 51 | Vector3d *normal=null; 52 | 53 | public: 54 | Face (); 55 | ~Face (); 56 | 57 | void computeCentroid (Point3d *centroid); 58 | void computeNormal (Vector3d *normal, double minArea); 59 | void computeNormal (Vector3d *normal); 60 | void computeNormalAndCentroid(); 61 | void computeNormalAndCentroid(double minArea); 62 | static Face *createTriangle (Vertex *v0, Vertex *v1, Vertex *v2); 63 | static Face *createTriangle (Vertex *v0, Vertex *v1, Vertex *v2, 64 | double minArea); 65 | static Face *create (vector vtxArray, vector&indices); 66 | 67 | 68 | 69 | HalfEdge *getEdge(int i); 70 | HalfEdge *getFirstEdge(); 71 | HalfEdge *findEdge (Vertex *vt, Vertex *vh); 72 | double distanceToPlane (Point3d *p); 73 | Vector3d *getNormal (); 74 | Point3d *getCentroid (); 75 | int numVertices(); 76 | string getVertexString (); 77 | void getVertexIndices (vector&idxs); 78 | Face *connectHalfEdges (HalfEdge *hedgePrev, HalfEdge *hedge); 79 | void checkConsistency(); 80 | int mergeAdjacentFace (HalfEdge *hedgeAdj, vector&discarded); 81 | double areaSquared (HalfEdge *hedge0, HalfEdge *hedge1); 82 | void triangulate (FaceList *newFaces, double minArea); 83 | }; 84 | -------------------------------------------------------------------------------- /waterman/cpp/FaceList.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FaceList.cpp 3 | // WatermanPoly 4 | // 5 | // Created by asd on 10/12/2018. 6 | // Copyright © 2018 voicesync. All rights reserved. 7 | // 8 | 9 | #include "FaceList.h" 10 | #include "Face.h" 11 | 12 | FaceList::FaceList() {} 13 | 14 | void FaceList::clear() 15 | { 16 | head = tail = null; 17 | } 18 | 19 | /** 20 | * Adds a vertex to the end of this list. 21 | */ 22 | void FaceList::add(Face *vtx) 23 | { 24 | if (head == null) 25 | { 26 | head = vtx; 27 | } 28 | else 29 | { 30 | tail->next = vtx; 31 | } 32 | vtx->next = null; 33 | tail = vtx; 34 | } 35 | 36 | Face *FaceList::first() 37 | { 38 | return head; 39 | } 40 | 41 | /** 42 | * Returns true if this list is empty. 43 | */ 44 | bool FaceList::isEmpty() 45 | { 46 | return head == null; 47 | } 48 | -------------------------------------------------------------------------------- /waterman/cpp/FaceList.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Maintains a single-linked list of faces for use by QuickHull3D 3 | */ 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | class Face; 10 | 11 | class FaceList 12 | { 13 | #define null NULL 14 | 15 | Face *head = null; 16 | Face *tail = null; 17 | 18 | public: 19 | FaceList(); 20 | 21 | void clear(); 22 | void add(Face *vtx); 23 | Face *first(); 24 | bool isEmpty(); 25 | }; 26 | -------------------------------------------------------------------------------- /waterman/cpp/HalfEdge.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // HalfEdge.cpp 3 | // WatermanPoly 4 | // 5 | // Created by asd on 10/12/2018. 6 | // Copyright © 2018 voicesync. All rights reserved. 7 | // 8 | 9 | #include "HalfEdge.h" 10 | #include "Face.h" 11 | #include "Vertex.h" 12 | #include "Point3d.h" 13 | 14 | HalfEdge::HalfEdge (Vertex* v, Face* f) 15 | { 16 | vertex = v; 17 | face = f; 18 | } 19 | 20 | HalfEdge::HalfEdge () 21 | {} 22 | 23 | /** 24 | * Sets the value of the next edge adjacent 25 | * (counter-clockwise) to this one within the triangle. 26 | * 27 | * @param edge next adjacent edge */ 28 | void HalfEdge::setNext (HalfEdge *edge) 29 | { 30 | next = edge; 31 | } 32 | 33 | /** 34 | * Gets the value of the next edge adjacent 35 | * (counter-clockwise) to this one within the triangle. 36 | * 37 | * @return next adjacent edge */ 38 | HalfEdge* HalfEdge::getNext() 39 | { 40 | return next; 41 | } 42 | 43 | /** 44 | * Sets the value of the previous edge adjacent (clockwise) to 45 | * this one within the triangle. 46 | * 47 | * @param edge previous adjacent edge */ 48 | void HalfEdge::setPrev (HalfEdge *edge) 49 | { 50 | prev = edge; 51 | } 52 | 53 | /** 54 | * Gets the value of the previous edge adjacent (clockwise) to 55 | * this one within the triangle. 56 | * 57 | * @return previous adjacent edge 58 | */ 59 | HalfEdge*HalfEdge::getPrev() 60 | { 61 | return prev; 62 | } 63 | 64 | /** 65 | * Returns the triangular face located to the left of this 66 | * half-edge. 67 | * 68 | * @return left-hand triangular face 69 | */ 70 | Face*HalfEdge::getFace() 71 | { 72 | return face; 73 | } 74 | 75 | /** 76 | * Returns the half-edge opposite to this half-edge. 77 | * 78 | * @return opposite half-edge 79 | */ 80 | HalfEdge*HalfEdge::getOpposite() 81 | { 82 | return opposite; 83 | } 84 | 85 | /** 86 | * Sets the half-edge opposite to this half-edge. 87 | * 88 | * @param edge opposite half-edge 89 | */ 90 | void HalfEdge::setOpposite (HalfEdge *edge) 91 | { 92 | opposite = edge; 93 | edge->opposite = this; 94 | } 95 | 96 | /** 97 | * Returns the head vertex associated with this half-edge. 98 | * 99 | * @return head vertex 100 | */ 101 | Vertex*HalfEdge::head() 102 | { 103 | return vertex; 104 | } 105 | 106 | /** 107 | * Returns the tail vertex associated with this half-edge. 108 | * 109 | * @return tail vertex 110 | */ 111 | Vertex*HalfEdge::tail() 112 | { 113 | return prev != null ? prev->vertex : null; 114 | } 115 | 116 | /** 117 | * Returns the opposite triangular face associated with this 118 | * half-edge. 119 | * 120 | * @return opposite triangular face 121 | */ 122 | Face*HalfEdge::oppositeFace() 123 | { 124 | return opposite != null ? opposite->face : null; 125 | } 126 | 127 | /** 128 | * Produces a string identifying this half-edge by the point 129 | * index values of its tail and head vertices. 130 | * 131 | * @return identifying string 132 | */ 133 | string HalfEdge::getVertexString() 134 | { 135 | if (tail() != null) 136 | { return "" + 137 | std::to_string(tail()->index)+ "-" + 138 | std::to_string(head()->index); 139 | } 140 | else 141 | { return "?-" + std::to_string(head()->index); 142 | } 143 | } 144 | 145 | /** 146 | * Returns the length of this half-edge. 147 | * 148 | * @return half-edge length 149 | */ 150 | double HalfEdge::length() 151 | { 152 | if (tail() != null) 153 | { return head()->pnt->distance(tail()->pnt); 154 | } 155 | else 156 | { return -1; 157 | } 158 | } 159 | 160 | /** 161 | * Returns the length squared of this half-edge-> 162 | * 163 | * @return half-edge length squared 164 | */ 165 | double HalfEdge::lengthSquared() 166 | { 167 | if (tail() != null) 168 | { return head()->pnt->distanceSquared(tail()->pnt); 169 | } 170 | else 171 | { return -1; 172 | } 173 | } 174 | 175 | 176 | -------------------------------------------------------------------------------- /waterman/cpp/HalfEdge.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Represents the half-edges that surround each 3 | * face in a counter-clockwise direction. 4 | */ 5 | #pragma once 6 | 7 | #include 8 | using std::string; 9 | 10 | class Face; 11 | class Vertex; 12 | 13 | class HalfEdge 14 | { 15 | #define null NULL 16 | 17 | public: 18 | /** 19 | * The vertex associated with the head of this half-edge. 20 | */ 21 | Vertex *vertex = null; 22 | 23 | /** 24 | * Triangular face associated with this half-edge. 25 | */ 26 | Face *face = null; 27 | 28 | /** 29 | * Next half-edge in the triangle. 30 | */ 31 | HalfEdge *next = null; 32 | 33 | /** 34 | * Previous half-edge in the triangle. 35 | */ 36 | HalfEdge *prev = null; 37 | 38 | /** 39 | * Half-edge associated with the opposite triangle 40 | * adjacent to this edge. 41 | */ 42 | HalfEdge *opposite = null; 43 | 44 | /** 45 | * Constructs a HalfEdge with head vertex v and 46 | * left-hand triangular face f. 47 | * 48 | * @param v head vertex 49 | * @param f left-hand triangular face 50 | */ 51 | 52 | public: 53 | HalfEdge(Vertex *v, Face *f); 54 | HalfEdge(); 55 | void setNext(HalfEdge *edge); 56 | HalfEdge *getNext(); 57 | void setPrev(HalfEdge *edge); 58 | HalfEdge *getPrev(); 59 | Face *getFace(); 60 | HalfEdge *getOpposite(); 61 | void setOpposite(HalfEdge *edge); 62 | Vertex *head(); 63 | Vertex *tail(); 64 | Face *oppositeFace(); 65 | string getVertexString(); 66 | double length(); 67 | double lengthSquared(); 68 | }; 69 | -------------------------------------------------------------------------------- /waterman/cpp/Makefile: -------------------------------------------------------------------------------- 1 | # ConvexHull -> libconvexhull.a 2 | sources=main.cpp Face.cpp FaceList.cpp HalfEdge.cpp Point3d.cpp QuickHull3D.cpp Vector3d.cpp Vertex.cpp VertexList.cpp Waterman.cpp 3 | objs=main.o Face.o FaceList.o HalfEdge.o Point3d.o QuickHull3D.o Vector3d.o Vertex.o VertexList.o Waterman.o 4 | includes=Face.h FaceList.h HalfEdge.h Point3d.h QuickHull3D.h Vector3d.h Vertex.h VertexList.h Waterman.h 5 | 6 | wp: $(sources) $(includes) 7 | g++ -o main -g $(sources) 8 | 9 | .SILENT: lib 10 | lib: $(sources) $(includes) 11 | g++ -c -O3 $(sources) 12 | rm -f libconvexhull.a 13 | ar rsc libconvexhull.a $(objs) 14 | rm -f $(objs) 15 | 16 | .SILENT: clean 17 | clean: 18 | rm *o -------------------------------------------------------------------------------- /waterman/cpp/Point3d.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Point3d.cpp 3 | // WatermanPoly 4 | // 5 | // Created by asd on 10/12/2018. 6 | // Copyright © 2018 voicesync. All rights reserved. 7 | // 8 | 9 | #include "Point3d.h" 10 | #include "Vector3d.h" 11 | 12 | Point3d::Point3d () 13 | { 14 | } 15 | 16 | /** 17 | * Creates a Point3d by copying a vector 18 | * 19 | * @param v vector to be copied 20 | */ 21 | Point3d::Point3d (Vector3d *v) 22 | { 23 | set (v); 24 | } 25 | 26 | /** 27 | * Creates a Point3d with the supplied element values. 28 | * 29 | * @param x first element 30 | * @param y second element 31 | * @param z third element 32 | */ 33 | Point3d::Point3d (double x, double y, double z) 34 | { 35 | set (x, y, z); 36 | } 37 | -------------------------------------------------------------------------------- /waterman/cpp/Point3d.h: -------------------------------------------------------------------------------- 1 | /** 2 | * A three-element spatial point. 3 | */ 4 | 5 | #pragma once 6 | 7 | #include "Vector3d.h" 8 | 9 | class Point3d : public Vector3d 10 | { 11 | public: 12 | Point3d(); 13 | Point3d(Vector3d *v); 14 | Point3d(double x, double y, double z); 15 | }; 16 | -------------------------------------------------------------------------------- /waterman/cpp/Vector3d.h: -------------------------------------------------------------------------------- 1 | /** 2 | * A three-element vector. This class is actually a reduced version of the 3 | * Vector3d class contained in the author's matlib package (which was partly 4 | * inspired by javax.vecmath). Only a mininal number of methods 5 | * which are relevant to convex hull generation are supplied here. 6 | * 7 | * @author John E. Lloyd, Fall 2004 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using std::string; 17 | 18 | class Vector3d 19 | { 20 | public: 21 | // Precision of a double. 22 | constexpr static const double DOUBLE_PREC = 2.2204460492503131e-16; 23 | double x = 0, y = 0, z = 0; 24 | 25 | public: 26 | Vector3d(); 27 | Vector3d(Vector3d *v); 28 | Vector3d(double x, double y, double z); 29 | double get(int i); 30 | void set(int i, double value); 31 | void set(Vector3d *v1); 32 | void add(Vector3d *v1, Vector3d *v2); 33 | void add(Vector3d *v1); 34 | void sub(Vector3d *v1, Vector3d *v2); 35 | void sub(Vector3d *v1); 36 | void scale(double s); 37 | void scale(double s, Vector3d *v1); 38 | double norm(); 39 | double normSquared(); 40 | double distance(Vector3d *v); 41 | double distanceSquared(Vector3d *v); 42 | double dot(Vector3d *v1); 43 | void normalize(); 44 | void setZero(); 45 | void set(double x, double y, double z); 46 | void cross(Vector3d *v1, Vector3d *v2); 47 | void setRandom(double lower, double upper); 48 | string toString(); 49 | }; 50 | -------------------------------------------------------------------------------- /waterman/cpp/Vertex.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Vertex.cpp 3 | // WatermanPoly 4 | // 5 | // Created by asd on 09/12/2018. 6 | // Copyright © 2018 voicesync. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | 12 | 13 | #include "Face.h" 14 | #include "Point3d.h" 15 | 16 | #include "Vertex.h" 17 | 18 | Vertex::Vertex() : pnt(new Point3d) 19 | { } 20 | 21 | Vertex::~Vertex() { 22 | delete pnt; 23 | } 24 | /** 25 | * Constructs a vertex with the specified coordinates 26 | * and index. 27 | */ 28 | Vertex::Vertex (double x, double y, double z, int idx) : pnt(new Point3d) 29 | { 30 | pnt->set(x, y, z); 31 | index = idx; 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /waterman/cpp/Vertex.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents vertices of the hull, as well as the points from 3 | * which it is formed. 4 | * 5 | */ 6 | 7 | #pragma once 8 | 9 | class Face; 10 | class Point3d; 11 | 12 | class Vertex 13 | { 14 | public: 15 | /** 16 | * Spatial point associated with this vertex. 17 | */ 18 | Point3d *pnt = null; 19 | 20 | /** 21 | * Back index into an array. 22 | */ 23 | int index; 24 | 25 | /** 26 | * List forward link. 27 | */ 28 | Vertex *prev = null; 29 | 30 | /** 31 | * List backward link. 32 | */ 33 | Vertex *next = null; 34 | 35 | /** 36 | * Current face that this vertex is outside of. 37 | */ 38 | Face *face = null; 39 | 40 | /** 41 | * Constructs a vertex and sets its coordinates to 0. 42 | */ 43 | public: 44 | Vertex(); 45 | ~Vertex(); 46 | 47 | /** 48 | * Constructs a vertex with the specified coordinates 49 | * and index. 50 | */ 51 | Vertex(double x, double y, double z, int idx); 52 | }; 53 | -------------------------------------------------------------------------------- /waterman/cpp/VertexList.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // VertexList.cpp 3 | // WatermanPoly 4 | // 5 | // Created by asd on 10/12/2018. 6 | // Copyright © 2018 voicesync. All rights reserved. 7 | // 8 | 9 | #include "VertexList.h" 10 | #include "Vertex.h" 11 | 12 | VertexList::VertexList() {} 13 | 14 | void VertexList::clear() 15 | { 16 | head = tail = null; 17 | } 18 | 19 | /** 20 | * Adds a vertex to the end of this list. 21 | */ 22 | void VertexList::add (Vertex *vtx) 23 | { 24 | if (head == null) 25 | { head = vtx; 26 | } 27 | else 28 | { tail->next = vtx; 29 | } 30 | vtx->prev = tail; 31 | vtx->next = null; 32 | tail = vtx; 33 | } 34 | 35 | /** 36 | * Adds a chain of vertices to the end of this list. 37 | */ 38 | void VertexList::addAll (Vertex *vtx) 39 | { 40 | if (head == null) 41 | { head = vtx; 42 | } 43 | else 44 | { tail->next = vtx; 45 | } 46 | vtx->prev = tail; 47 | while (vtx->next != null) 48 | { vtx = vtx->next; 49 | } 50 | tail = vtx; 51 | } 52 | 53 | /** 54 | * Deletes a vertex from this list. 55 | */ 56 | void VertexList::del (Vertex *vtx) 57 | { 58 | if (vtx->prev == null) 59 | { head = vtx->next; 60 | } 61 | else 62 | { vtx->prev->next = vtx->next; 63 | } 64 | if (vtx->next == null) 65 | { tail = vtx->prev; 66 | } 67 | else 68 | { vtx->next->prev = vtx->prev; 69 | } 70 | } 71 | 72 | /** 73 | * Deletes a chain of vertices from this list. 74 | */ 75 | void VertexList::del (Vertex *vtx1, Vertex *vtx2) 76 | { 77 | if (vtx1->prev == null) 78 | { head = vtx2->next; 79 | } 80 | else 81 | { vtx1->prev->next = vtx2->next; 82 | } 83 | if (vtx2->next == null) 84 | { tail = vtx1->prev; 85 | } 86 | else 87 | { vtx2->next->prev = vtx1->prev; 88 | } 89 | } 90 | 91 | /** 92 | * Inserts a vertex into this list before another 93 | * specificed vertex. 94 | */ 95 | void VertexList::insertBefore (Vertex *vtx, Vertex *next) 96 | { 97 | vtx->prev = next->prev; 98 | if (next->prev == null) 99 | { head = vtx; 100 | } 101 | else 102 | { next->prev->next = vtx; 103 | } 104 | vtx->next = next; 105 | next->prev = vtx; 106 | } 107 | 108 | /** 109 | * Returns the first element in this list. 110 | */ 111 | Vertex *VertexList::first() 112 | { 113 | return head; 114 | } 115 | 116 | /** 117 | * Returns true if this list is empty. 118 | */ 119 | bool VertexList::isEmpty() 120 | { 121 | return head == null; 122 | } 123 | -------------------------------------------------------------------------------- /waterman/cpp/VertexList.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Maintains a double-linked list of vertices for use by QuickHull3D 3 | */ 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | class Vertex; 10 | 11 | class VertexList 12 | { 13 | 14 | #define null NULL 15 | 16 | Vertex *head = null; 17 | Vertex *tail = null; 18 | 19 | /** 20 | * Clears this list. 21 | */ 22 | public: 23 | VertexList(); 24 | 25 | void clear(); 26 | 27 | /** 28 | * Adds a vertex to the end of this list. 29 | */ 30 | void add(Vertex *vtx); 31 | /** 32 | * Adds a chain of vertices to the end of this list. 33 | */ 34 | void addAll(Vertex *vtx); 35 | 36 | /** 37 | * Deletes a vertex from this list. 38 | */ 39 | void del(Vertex *vtx); 40 | 41 | /** 42 | * Deletes a chain of vertices from this list. 43 | */ 44 | void del(Vertex *vtx1, Vertex *vtx2); 45 | 46 | /** 47 | * Inserts a vertex into this list before another 48 | * specificed vertex. 49 | */ 50 | void insertBefore(Vertex *vtx, Vertex *next); 51 | 52 | /** 53 | * Returns the first element in this list. 54 | */ 55 | Vertex *first(); 56 | 57 | /** 58 | * Returns true if this list is empty. 59 | */ 60 | bool isEmpty(); 61 | }; 62 | -------------------------------------------------------------------------------- /waterman/cpp/Waterman.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QuickHull3D.h" 4 | #include "Point3d.h" 5 | 6 | class WatermanPoly 7 | { 8 | 9 | public: 10 | QuickHull3D hull; 11 | 12 | WatermanPoly(); 13 | vector genPoly(double radius); 14 | QuickHull3D genHull(double radius); 15 | 16 | bool ok = true; 17 | }; 18 | -------------------------------------------------------------------------------- /waterman/cpp/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Waterman.h" 2 | 3 | int main() 4 | { 5 | auto wp = WatermanPoly(); 6 | auto qh = wp.genHull(45); 7 | auto faces=qh.getFaces(); 8 | auto vertices = qh.getVertices(); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /waterman/cpp/nim_interface.cpp: -------------------------------------------------------------------------------- 1 | // rust interface for convex_hull 2 | 3 | #include "QuickHull3D.h" 4 | #include "Point3d.h" 5 | 6 | extern "C" 7 | { 8 | 9 | void convex_hull(size_t n_vertices, double *vertices, size_t *n_faces, size_t *hn_vertices, int **o_faces, double **o_vertices) 10 | { 11 | vector vv; 12 | for (size_t i = 0; i < n_vertices; i++) 13 | vv.push_back(vertices[i]); 14 | QuickHull3D hull(vv); 15 | 16 | auto faces = hull.getFaces(); // faces & vertexes 17 | auto coords = hull.getVertex(); 18 | 19 | // faces list 20 | n_faces = 0; 21 | 22 | for (auto f : faces) // count faces 23 | { 24 | n_faces += f.size() + 1; 25 | } 26 | // populate o_face: |n_intems|items,.,,. 27 | 28 | auto _faces = new int[*n_faces]; 29 | 30 | size_t i = 0; 31 | for (auto f : faces) 32 | { 33 | _faces[i++] = f.size(); 34 | for (auto ix : f) 35 | _faces[i++] = ix; 36 | } 37 | 38 | // vertex list 39 | *hn_vertices = coords.size(); 40 | 41 | auto _vertices = new double[n_vertices]; 42 | i = 0; 43 | for (auto c : coords) 44 | _vertices[i++] = c; 45 | 46 | *o_vertices = _vertices; 47 | *o_faces = _faces; 48 | } 49 | 50 | void free_ch(int *o_faces, double *o_vertices) 51 | { 52 | delete[] o_faces; 53 | delete[] o_vertices; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /waterman/cpp/rust_interface.cpp: -------------------------------------------------------------------------------- 1 | // rust interface for convex_hull 2 | 3 | #include "QuickHull3D.h" 4 | #include "Point3d.h" 5 | 6 | extern "C" 7 | { 8 | void convex_hull(size_t n_vertices, double *vertices, size_t &n_faces, size_t &hn_vertices, int **o_faces, double **o_vertices) 9 | { 10 | vector vv; 11 | for (size_t i = 0; i < n_vertices; i++) 12 | vv.push_back(vertices[i]); 13 | QuickHull3D hull(vv); 14 | 15 | auto faces = hull.getFaces(); // faces & vertexes 16 | auto coords = hull.getVertex(); 17 | 18 | // faces list 19 | n_faces = 0; 20 | 21 | for (auto f : faces) // count faces 22 | { 23 | n_faces += f.size() + 1; 24 | } 25 | // populate o_face: |n_intems|items,.,,. 26 | 27 | auto _faces = new int[n_faces]; 28 | 29 | size_t i = 0; 30 | for (auto f : faces) 31 | { 32 | _faces[i++] = f.size(); 33 | for (auto ix : f) 34 | _faces[i++] = ix; 35 | } 36 | 37 | // vertex list 38 | hn_vertices = coords.size(); 39 | 40 | auto _vertices = new double[n_vertices]; 41 | i = 0; 42 | for (auto c : coords) 43 | _vertices[i++] = c; 44 | 45 | *o_vertices = _vertices; 46 | *o_faces = _faces; 47 | } 48 | void free_ch(int *o_faces, double *o_vertices) 49 | { 50 | delete[] o_faces; 51 | delete[] o_vertices; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /waterman/waterman_poly.nim: -------------------------------------------------------------------------------- 1 | # waterman poly, cpp wrapper 2 | 3 | import math, cppstl 4 | 5 | # ffi 6 | {.passL:"-L. -lconvexhull".} 7 | 8 | type 9 | Vertex* = array[3, float] 10 | Vertexes* = seq[Vertex] 11 | Face* = seq[cint] 12 | Faces* = seq[Face] 13 | 14 | proc waterman_poly*(radius: float) : seq[float] = 15 | var coords :seq[float] 16 | 17 | let (a, b, c) = (0.0, 0.0, 0.0) 18 | var (max, min) = (-float.high, float.high) 19 | var s = radius # .sqrt() 20 | let radius2 = s 21 | 22 | let (xra, xrb) = ((a - s).ceil(), (a + s).floor()) 23 | 24 | var x = xra 25 | while x <= xrb: 26 | let r = radius2 - (x - a) * (x - a) 27 | if r < 0: 28 | x += 1 29 | continue 30 | 31 | s = r.sqrt() 32 | let yra = (b - s).ceil() 33 | let yrb = (b + s).floor() 34 | var y = yra 35 | 36 | var (zra, zrb) = (0.0, 0.0) 37 | 38 | while y <= yrb: 39 | let ry = r - (y - b) * (y - b) 40 | if ry < 0: 41 | y += 1 42 | continue 43 | #case ry < 0 44 | 45 | if ry == 0 and c == c.floor(): 46 | #case ry=0 47 | if (x + y + c).mod(2) != 0: 48 | y += 1 49 | continue 50 | else: 51 | zra = c 52 | zrb = c 53 | 54 | else: 55 | # case ry > 0 56 | s = ry.sqrt() 57 | zra = (c - s).ceil() 58 | zrb = (c + s).floor() 59 | if ((x + y).mod(2)) == 0: 60 | if zra.mod(2) != 0: 61 | if zra <= c: 62 | zra = zra + 1 63 | else: 64 | zra = zra - 1 65 | else: 66 | if zra.mod(2) == 0: 67 | if zra <= c: 68 | zra = zra + 1 69 | else: 70 | zra = zra - 1 71 | 72 | var z = zra 73 | while z <= zrb: 74 | # save vertex x,y,z 75 | max = max.max(z).max(y).max(x) 76 | min = min.min(z).min(y).min(y) 77 | 78 | coords.add(x) 79 | coords.add(y) 80 | coords.add(z) 81 | z += 2 82 | 83 | y += 1 84 | 85 | x += 1 86 | 87 | coords 88 | 89 | # QuickHull3D wrapper 90 | 91 | const qhHeader="cpp/QuickHull3D.h" 92 | 93 | type QuickHull3D {.importcpp, header:qhHeader.}=object 94 | {.push importcpp, header:qhHeader.} 95 | proc getScaledVertex(qh:QuickHull3D) : CppVector[cdouble] 96 | proc getFaces(qh:QuickHull3D) : CppVector[CppVector[cint]] 97 | {.pop.} 98 | proc newQuickHull3D(coords:CppVector[cdouble]) : QuickHull3D {.importcpp:"QuickHull3D(@)", header:qhHeader.} 99 | 100 | proc waterman*(rad: float): (Faces, Vertexes) = 101 | var qh = newQuickHull3D(waterman_poly(rad).toCppVector) 102 | 103 | let vertexes = cast[Vertexes](qh.getScaledVertex().toSeq) 104 | var faces: Faces 105 | for face in qh.getFaces(): faces.add face.toSeq 106 | 107 | (faces, vertexes) 108 | 109 | 110 | when isMainModule: 111 | for i in countdown(1500, 500, 20): 112 | let (f, v) = waterman(i.float) 113 | echo i," faces/vertex:", f.len, "/", v.len 114 | 115 | -------------------------------------------------------------------------------- /wav/dr_wav.c: -------------------------------------------------------------------------------- 1 | #define DR_WAV_IMPLEMENTATION 2 | #include "dr_wav.h" -------------------------------------------------------------------------------- /wav/test.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rforcen/nim/4feaacbf3128d170adad529228b7d35d6d0c8ce0/wav/test.wav -------------------------------------------------------------------------------- /yacl.nim: -------------------------------------------------------------------------------- 1 | # yet another opencl wrapper (nvidia oriented) 2 | # yacl.nim 3 | 4 | import nimcl, opencl, times, streams 5 | 6 | type 7 | OCL* = object 8 | platform: PPlatformId 9 | device: PDeviceId 10 | context: PContext 11 | queue: PCommandQueue 12 | kernel*: PKernel 13 | program: Pprogram 14 | 15 | 16 | proc `=destroy`*(ocl: var OCL) = 17 | if not ocl.kernel.isNil: release(ocl.kernel) 18 | if not ocl.program.isNil: release(ocl.program) 19 | release(ocl.queue) 20 | release(ocl.context) 21 | 22 | proc namedDevice*(name: string, n_device: int): OCL = 23 | let 24 | platform = getPlatformByName(name) 25 | device = platform.getDevices[n_device] 26 | context = @[device].createContext 27 | queue = context.commandQueueFor(device) 28 | 29 | OCL(platform: platform, device: device, context: context, queue: queue) 30 | 31 | # nvidia specific cl init 32 | proc nvidiaDevice*(): OCL = namedDevice("NVIDIA", 0) 33 | 34 | # nvidia specific cl init 35 | proc intelDevice*(): OCL = namedDevice("Intel", 0) 36 | 37 | proc compile*(ocl: var OCL, source: string, kernel_func: string) = 38 | ocl.program = ocl.context.createAndBuild(source, ocl.device) 39 | ocl.kernel = ocl.program.createKernel(kernel_func) 40 | 41 | proc buffer*[T](ocl: OCL, buff: seq[T]): PMem = ocl.context.bufferLike(buff) 42 | 43 | proc run*(ocl: OCL, size: int) = ocl.queue.run(ocl.kernel, size) 44 | 45 | proc read*[T](ocl: OCL, v: var seq[T], gb: Pmem) = ocl.queue.read(v, gb) 46 | 47 | proc write*[T](ocl: OCL, v: var seq[T], gb: Pmem) = ocl.queue.write(v, gb) 48 | 49 | 50 | proc write_file*[T](vi: seq[T], fn: string) = # write image to binary file 51 | var f = newFileStream(fn, fmWrite) 52 | if not f.isNil: 53 | f.writeData(vi[0].unsafeAddr, vi.len * sizeof(T)) 54 | f.close() 55 | 56 | # mesh utils 57 | 58 | type float4* = object 59 | x, y, z, t: float32 60 | type Vertex* = object 61 | position, normal, color, texture: float4 62 | 63 | proc generate_faces*(n: int): seq[seq[int]] = 64 | var faces: seq[seq[int]] = @[] 65 | for i in 0..