SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
IcarusLives
Posts: 175
Joined: 17 Jan 2016 23:55

SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#1 Post by IcarusLives » 25 Mar 2017 19:32

Hello all ^-^

Image

I have made a somewhat of a proof of concept for cellular automata :)

My only problem is that it's pretty slow :/

If anyone is familiar, how could we speed this up?

Code: Select all

@echo off & setlocal enableDelayedExpansion & color f0

call:canvas 40 40
call:rulesets

rem Try a random ruleset
REM for /l %%r in (0,1,7) do set /a "rrs=!random! %% 2" & set "ruleset=!ruleset!!rrs!,"

rem create array ruleset[]
set "arr=-1" & for %%a in (%ruleset%) do ( set /a "arr+=1" & set "ruleset[!arr!]=%%a" )

rem create 2d array for our grid m[][]
for /l %%i in (0,1,%width%) do for /l %%j in (0,1,%height%) do set "m[%%i][%%j]=0"
   
    rem place our "arbitrary" character, Line 0, "center pixel"
    set /a "wd2=width/2"
    set "m[!wd2!][0]=1"

rem ----------------------------------------------------------------------------------------------

rem %%j = %%jenerations.... lol
for /l %%j in (0,1,%height%) do (

    rem loop through the width of the screen (each "pixel") on each line.
    for /l %%i in (0,1,%width%) do (
     
        rem if our m[%%i][%%j] grid is a 1, plot a "#"
        if !m[%%i][%%j]! equ 1 call :plot %%i %%j #
       
        rem Pixel left of me
        set /a "_l=%%i - 1"
        call set "l=%%m[!_l!][%%j]%%"
        rem Pixel right of me
        set /a "_r=%%i + 1"
        call set "r=%%m[!_r!][%%j]%%"
        rem _g = generation (%%j) + 1
        set /a "_g=%%j + 1"
       
        if !l! equ 1 if !m[%%i][%%j]! equ 1 if !r! equ 1 set "m[%%i][!_g!]=%ruleset[0]%"
        if !l! equ 1 if !m[%%i][%%j]! equ 1 if !r! equ 0 set "m[%%i][!_g!]=%ruleset[1]%"
        if !l! equ 1 if !m[%%i][%%j]! equ 0 if !r! equ 1 set "m[%%i][!_g!]=%ruleset[2]%"
        if !l! equ 1 if !m[%%i][%%j]! equ 0 if !r! equ 0 set "m[%%i][!_g!]=%ruleset[3]%"
        if !l! equ 0 if !m[%%i][%%j]! equ 1 if !r! equ 1 set "m[%%i][!_g!]=%ruleset[4]%"
        if !l! equ 0 if !m[%%i][%%j]! equ 1 if !r! equ 0 set "m[%%i][!_g!]=%ruleset[5]%"
        if !l! equ 0 if !m[%%i][%%j]! equ 0 if !r! equ 1 set "m[%%i][!_g!]=%ruleset[6]%"
        if !l! equ 0 if !m[%%i][%%j]! equ 0 if !r! equ 0 set "m[%%i][!_g!]=%ruleset[7]%"

    )
    call :showCanvas
    echo ruleset = !ruleset!
)
rem ----------------------------------------------------------------------------------------------!
pause & exit


:rulesets
    REM set "ruleset=0,0,0,0,0,0,0,1" & rem Rule 1
    REM set "ruleset=0,0,0,1,1,1,1,0" & rem Rule 30
    REM set "ruleset=0,0,1,1,0,1,1,0" & rem Rule 54
    REM set "ruleset=0,0,1,1,1,1,0,0" & rem Rule 60
    REM set "ruleset=0,0,1,1,1,1,1,0" & rem Rule 62
    set "ruleset=0,1,0,1,1,0,1,0" & rem Rule 90
    REM set "ruleset=0,1,0,1,1,1,1,0" & rem Rule 94
    REM set "ruleset=0,1,1,0,0,1,1,0" & rem Rule 102
    REM set "ruleset=0,1,1,0,1,1,1,0" & rem Rule 110
    REM set "ruleset=0,1,1,1,1,0,1,0" & rem Rule 122
    REM set "ruleset=0,1,1,1,1,1,1,0" & rem Rule 126
    REM set "ruleset=1,0,0,1,0,1,1,0" & rem Rule 150
    REM set "ruleset=1,0,0,1,1,1,1,0" & rem Rule 158
    REM set "ruleset=1,0,1,1,0,1,1,0" & rem Rule 182
    REM set "ruleset=1,0,1,1,1,1,1,0" & rem Rule 188
    REM set "ruleset=1,0,1,1,1,1,1,0" & rem Rule 190
    REM set "ruleset=1,1,0,1,1,1,0,0" & rem Rule 220
    REM set "ruleset=1,1,0,1,1,1,1,0" & rem Rule 222
    REM set "ruleset=1,1,1,1,1,0,1,0" & rem Rule 250
    REM set "ruleset=1,1,1,1,1,1,1,1" & rem Rule 256
    REM set "ruleset=1,1,0,1,0,0,1,1" & rem Unknown Rule
    REM set "ruleset=1,0,1,1,1,0,0,1" & rem Unknown Rule
    REM set "ruleset=1,0,0,1,0,0,1,1" & rem Unknown Rule
    REM set "ruleset=0,1,0,1,1,0,1,0" & rem Unknown Rule
    REM set "ruleset=1,0,0,1,0,0,0,1" & rem Unknown Rule
    REM set "ruleset=0,1,0,0,1,1,0,1" & rem Unknown Rule
    REM set "ruleset=0,1,0,0,0,1,0,1" & rem Unknown Rule
    REM set "ruleset=1,0,1,1,0,1,1,1" & rem Unknown Rule
    REM set "ruleset=" & rem Unknown Rule
goto :eof


:canvas
        set /a "width=%~1 - 1", "height=%~2 - 1", "conWidth=width + 5", "conHeight=height + 6", "_=0"
        for /l %%a in (-2,1,%width%) do set "outerBuffer=!outerBuffer!#"
        for /l %%a in (0,1,%width%)  do set "widthBuffer=!widthBuffer! "
        call :updateCanvas
        call :cursorpos
        if exist "%temp%\cursorpos.exe" ( set "cls="%temp%\cursorpos.exe" 0 1" ) else ( set "cls=cls" )
        mode con: cols=%conWidth% lines=%conHeight%
    goto :eof
   
    :updateCanvas
        for /l %%a in (0,1,%height%) do set "_[%%a]=%widthBuffer%"
    goto :eof
   
    :showCanvas
        %cls%
        echo= %outerBuffer%
        for /l %%a in (0,1,%height%) do echo= #!_[%%a]!#
        echo= %outerBuffer%
        if "%~1" equ "/u" for /l %%a in (0,1,%height%) do set "_[%%a]=%widthBuffer%"
    goto :eof
goto :eof

:plot x y
    setlocal
        set "c=%~3"
        set /a "_y=%~2", "_x=%~1", "_x2=%~1 + 1"
        (endlocal
            set "_[%_y%]=!_[%_y%]:~0,%_x%!%c:~0,1%!_[%_y%]:~%_x2%!"
        )
goto :eof
Last edited by IcarusLives on 25 Mar 2017 22:15, edited 4 times in total.

RedEyedRocker
Posts: 19
Joined: 25 Mar 2017 12:15
Location: Nepal
Contact:

Re: Wolfram Elementary Cellular Automata

#2 Post by RedEyedRocker » 25 Mar 2017 19:35

This is created using Advanced Batch to Exe Converter which has those functions as well.

IcarusLives
Posts: 175
Joined: 17 Jan 2016 23:55

Re: Wolfram Elementary Cellular Automata

#3 Post by IcarusLives » 25 Mar 2017 19:37

RedEyedRocker wrote:This is created using Advanced Batch to Exe Converter which has those functions as well.


I'm sorry.. What?

RedEyedRocker
Posts: 19
Joined: 25 Mar 2017 12:15
Location: Nepal
Contact:

Re: Wolfram Elementary Cellular Automata

#4 Post by RedEyedRocker » 25 Mar 2017 19:42

IcarusLives wrote:
RedEyedRocker wrote:This is created using Advanced Batch to Exe Converter which has those functions as well.


I'm sorry.. What?


Sisi Puaat, Gai ko gobar chaat!

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Wolfram Elementary Cellular Automata

#5 Post by ShadowThief » 25 Mar 2017 23:07

RedEyedRocker wrote:
IcarusLives wrote:
RedEyedRocker wrote:This is created using Advanced Batch to Exe Converter which has those functions as well.


I'm sorry.. What?


Sisi Puaat, Gai ko gobar chaat!

Wat

Sounak@9434
Posts: 100
Joined: 16 Dec 2016 22:31

Re: Wolfram Elementary Cellular Automata

#6 Post by Sounak@9434 » 26 Mar 2017 00:44

RedEyedRocker wrote:
IcarusLives wrote:
RedEyedRocker wrote:This is created using Advanced Batch to Exe Converter which has those functions as well.


I'm sorry.. What?


Sisi Puaat, Gai ko gobar chaat!


Is it hindi? I'm not sure though, not my language.

RedEyedRocker
Posts: 19
Joined: 25 Mar 2017 12:15
Location: Nepal
Contact:

Re: Wolfram Elementary Cellular Automata

#7 Post by RedEyedRocker » 26 Mar 2017 04:34

Sounak@9434 wrote:
RedEyedRocker wrote:
IcarusLives wrote:
I'm sorry.. What?


Sisi Puaat, Gai ko gobar chaat!


Is it hindi? I'm not sure though, not my language.


Nope, it's nothing. Lol!

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#8 Post by penpen » 26 Mar 2017 10:26

If you (IcarusLives) want to speed up, then you should avoid creating and accessing unneccessary variables.

Example:
Instead of using an algorithm working on a (simulated) 2d-field, you could implement a sweep algorithm (north to south):
So you could get rid of the 2d array for the field ("map[i][j]"), only needing a 1d field stored in a single variable.

If it is faster, then don't seperate data and visualization (although this is considered as bad programming style in common).


Here is my exemplary implementation of the Wolfram Elementary Cellular Automaton:

Code: Select all

@echo off

:: Your (==IcarusLives) initial example, but with optimal width
cls
call :weca "generations=128" "rule=90"


:: skip wolfram examples
goto :next

:: wolfram examples, see: http://mathworld.wolfram.com/ElementaryCellularAutomaton.html
cls
call :weca "generations=21" "rule=30"
pause

for %%a in (
    30  54  60
    62  90  94
   102 110 122
   126 150 158
   182 188 190
   220 222 250
) do (
   cls
   call :weca "generations=16" "rule=%%~a"
   pause
)

for /l %%a in (0, 1, 255) do (
   cls
   call :weca "generations=16" "rule=%%~a"
   pause
)

:next
goto :eof


:wolframElementaryCellularAutomaton
:weca
:: %~1, %~2  in:
::  - optional rule (default: random)
::  - optional generations (<= 512) see "!line!" (default: 21)
:: format:
::  "<option>=<integer term>"
setlocal enableExtensions enableDelayedExpansion
:: set defaults: rule, amount of generations and characters to display
set "rule=^!random^! %% 256"
set "generations=21"
set "characters= Û"

:: load user defined
for %%a in (%*) do if not "%%~a" == "" set "%%~a"
set /a "rule=%rule%, generations=%generations%"

:: set optimal width
set /a "width=2*generations+1"

:: cell states:
set /a "DEAD=0, LIVING=1"
set "states=%DEAD%, %LIVING%"

:: Display characters:
set "c[%DEAD%]=!characters:~%DEAD%,1!"
set "c[%LIVING%]=!characters:~%LIVING%,1!"

:: states in characters:
for %%a in (%states%) do ^
for %%b in (%states%) do ^
for %%c in (%states%) do ^
for /f %%d in ('set /a "(%%~a<<2)|(%%~b<<1)|%%~c"') do ^
set "state[%%~d]=!c[%%~a]!!c[%%~b]!!c[%%~c]!"

:: mapping
for /l %%a in (0, 1, 7) do ^
for /f %%b in ('set /a "(rule>>%%~a)&0x1"') do ^
set "map[!state[%%~a]!]=!c[%%~b]!"

:: 512 minus characters
set "line=--------"
set "line=!line:-=%line:-=--------%!"

:: initial generation: -inf DEAD, center mid LIVING, +inf DEAD
set "border=+!line:~-%generations%!-!line:~-%generations%!+"
set "line=!c[%DEAD%]!!line:~-%generations%!!c[%LIVING%]!!line:~-%generations%!!c[%DEAD%]!"
for %%a in ("!c[%DEAD%]!") do set "line=!line:-=%%~a!"


:: draw result
echo Rule %rule%
echo(!border!
echo(:!line:~1,-1!:
for /l %%a in (2, 1, %generations%) do (
   set "old=!line!"
   for %%b in ("!old:~0,1!") do (
      set "line=!map[%%~b%%~b%%~b]!"
   )
   for /l %%b in (0, 1, %width%) do (
      for %%c in ("!old:~%%~b,3!") do (
         set "line=!line!!map[%%~c]!"
      )
   )
   for %%b in ("!old:~-1!") do set "line=!line!!map[%%~b%%~b%%~b]!"
   echo(:!line:~1,-1!:
)
echo(!border!

endlocal
goto :eof
Note: I've skipped some of the tests given at wolfram.

Sidenote:
Your implementation is not fully correct: You ignore the cell values towards +/-inf.

penpen

pieh-ejdsch
Posts: 240
Joined: 04 Mar 2014 11:14
Location: germany

Re: SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#9 Post by pieh-ejdsch » 26 Mar 2017 11:52

this is only to Screen this
i think it only double all previos lines to left an right side and set the provious lines to one.

Code: Select all

@echo off
setlocal enabledelayedexpansion
mode 177
 rem linelength
for /f tokens^=3 %%l in ('mode con^|find  "  "^|find /n "  "^|find "[2]"')do set /a LL=%%l-2
set /a center=LL/2-2, one=LL%%2, pre=LL-center-3-one, half=pre
set "space= "
for /l %%l in (0 1 12) do set "space=!space!!space!"
set "cell.m= "
set "cell.1=#"
echo +!space:~-%pre%!%cell.1%!space:~-%pre%!+
set /a counter=2
set /a x=1
:printline
set /a pre-=x
for /l %%X in (1 1 %X%) do for %%c in ("!counter!") do (
  set cell.%%~c=!cell.%%X!!cell.m!!cell.%%X!
  if %pre% geq 0 echo +!space:~-%pre%!!cell.%%X!!cell.m!!cell.%%X!!space:~-%pre%!+
  if %pre% lss 0 echo +!cell.%%X:~-%half%!!cell.m!!cell.%%X:~0,%half%!+
  set cell.%%X=!space:~-%x%!!cell.%%X!!space:~-%X%!
  set /a counter+=1, X+=1
)

if %x% lss %center% goto :printline
pause
Last edited by pieh-ejdsch on 26 Mar 2017 13:28, edited 1 time in total.

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#10 Post by Aacini » 26 Mar 2017 12:31

EDIT 2017/03/27: I slightly modified the way to give the rule; it now directly accepts the rule number instead of the bits.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set /P "rule=Enter the *rule number* to use (i.e. 90): "
rem http://mathworld.wolfram.com/ElementaryCellularAutomaton.html
set /P "lines=Enter the number of lines: "

rem Convert the rule into individual mapping elements
set "char= #"
for %%a in ("   "  "  #"  " # "  " ##"  "#  "  "# #"  "## "  "###" ) do (
   set /A "bit=rule&1, rule>>=1"
   for /F %%b in ("!bit!") do set "rule[%%~a]=!char:~%%b,1!"
)

set "spaces="
for /L %%i in (1,1,59) do set "spaces=!spaces! "

mode con cols=122 lines=250
echo #%spaces: =#%#%spaces: =#%#

set "lineN=%spaces%#%spaces%"

:nextLine
echo #%lineN%#
set "lineN+1="
for /L %%i in (0,1,119) do (
   for /F "delims=" %%j in ("!lineN:~%%i,3!") do (
      set "lineN+1=!lineN+1!!rule[%%j]!"
   )
)
set "lineN= %lineN+1% "
set /A lines-=1
if %lines% gtr 0 goto nextLine

PS - I don't understand the rules numeration: may someone explain why 30 = 0 0 0 1 1 1 1 0? TIA

Antonio

IcarusLives
Posts: 175
Joined: 17 Jan 2016 23:55

Re: SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#11 Post by IcarusLives » 26 Mar 2017 13:01

Oh wow! All of your examples are insane! I need to take some time to read code thoroughly, but I've ran them all, and they're beautiful!

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#12 Post by penpen » 26 Mar 2017 14:03

Aacini wrote:PS - I don't understand the rules numeration: may someone explain why 30 = 0 0 0 1 1 1 1 0? TIA
It's just binary enumeration used twice.
1) The decimal rule number 30 represented as a binary is 00011110.
2) Then you look at the exponent (in binary) of the 2-adic representation (b: binary, else decimal; ^= to the power of: sum_from_{i=0}to{7} (b_i * b^i)):
30 == 0*2^111b + 0*2^110b + 0*2^101b + 1*2^100b + 1*2^011b + 1*2^010b + 1*2^001b + 0*2^000b


This gives you the mapping of the rule (using the code 0: '░'; 1 := '█' for binary digits of both "i" and "b_i"):

Code: Select all

Rule 30 mapping:
 111 110 101 100 011 010 001 000
 ███ ██░ █░█ █░░ ░██ ░█░ ░░█ ░░░   old generation (relative positioning)
  ░   ░   ░   █   █   █   █   ░    new generation (positioning anchor)
  0   0   0   1   1   1   1   0
 
Rule 90 mapping:
 111 110 101 100 011 010 001 000
 ███ ██░ █░█ █░░ ░██ ░█░ ░░█ ░░░   old generation
  ░   █   ░   █   █   ░   █   ░    new generation
  0   1   0   1   1   0   1   0


penpen

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#13 Post by Aacini » 26 Mar 2017 15:17

penpen wrote:
Aacini wrote:PS - I don't understand the rules numeration: may someone explain why 30 = 0 0 0 1 1 1 1 0? TIA
It's just binary enumeration used twice.
1) The decimal rule number 30 represented as a binary is 00011110.
2) Then you look at the exponent (in binary) of the 2-adic representation (b: binary, else decimal; ^= to the power of: sum_from_{i=0}to{7} (b_i * b^i)):
30 == 0*2^111b + 0*2^110b + 0*2^101b + 1*2^100b + 1*2^011b + 1*2^010b + 1*2^001b + 0*2^000b

. . .

penpen


Mmmm... What I want to know is if is there a way to convert the 30 into 0 0 0 1 1 1 1 0, or the 90 into 0 1 0 1 1 0 1 0. If this is not possible, then IMHO the "30" and "90" are just decorative names that have no practical use (from my engineering view of point). :mrgreen:

Antonio

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#14 Post by penpen » 26 Mar 2017 17:38

It is just the binary representation of the rule number:

Code: Select all

@echo off
setlocal enableExtensions enableDelayedExpansion
if /i "%~1" == "all" ( set "all=/l" ) else set "all="
for %all% %%a in (0, 1, 255, 30, 90) do (
   for /l %%b in (0, 1, 7) do set /a "bit[%%b]=(%%~a>>%%~b)&1"
   set "line=!bit[7]! !bit[6]! !bit[5]! !bit[4]! !bit[3]! !bit[2]! !bit[1]! !bit[0]!"
   set "mapping=!line:1=  Û!"
   set "mapping=!mapping:0=  °!"


   echo(rule %%~a = "!line!"
   echo(
   echo(Rule %%~a mapping:
   rem    7   6   5   4   3   2   1   0    bit index used to store the mapping  == exponent of in 2-adic representation
   echo( 111 110 101 100 011 010 001 000   bit index in binary
   echo( ÛÛÛ ÛÛ° Û°Û Û°° °ÛÛ °Û° °°Û °°°   old generation ^(relative positioning^)
   echo(!mapping!    new generation ^(positioning anchor^)
   echo(  !line: =   !    value of the bit ^(at bit index^)
   echo(
   echo(
)
endlocal
goto :eof


penpen

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: SLOW- Possible to speed this up? Wolfram Elementary Cellular Automata

#15 Post by Aacini » 27 Mar 2017 10:14

penpen wrote:It is just the binary representation of the rule number:

. . .

penpen


Ok, I got it! :D

I modified my solution above so it directly accepts the rule number (instead if the bits).

Antonio

Post Reply