User Tools

Site Tools


dev:program_ulam

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
dev:program_ulam [2015/05/31 03:37] – [The 'Box' Element] xychendev:program_ulam [2016/01/14 07:13] (current) ackley
Line 18: Line 18:
 Similarly, the first letter of every variable name, and of the name of every function or method (both terms mean the same thing in ULAM), must be a **lowercase** letter.   So examples of legal variable or function names could include ''i'', ''count'', ''isInitted'', or ''cMAX_VALUE'', but not ''IsInitted'', ''Reset'', or ''MAX_VALUE'' Similarly, the first letter of every variable name, and of the name of every function or method (both terms mean the same thing in ULAM), must be a **lowercase** letter.   So examples of legal variable or function names could include ''i'', ''count'', ''isInitted'', or ''cMAX_VALUE'', but not ''IsInitted'', ''Reset'', or ''MAX_VALUE''
  
 +
 +==== EventWindow Indices ====
 +
 +{{ :dev:event-window-10.png?300|}} The image at right (click to enlarge) shows the indexing scheme used for sites within an ''EventWindow'' Both 2D 'coord' numbering and a 1D 'site number' approach are offered.  
 +
 +The ''getCoord(siteNum)'' function converts an 1D index (which is an ''Unsigned(6)'' ) to a 2D coordinate (which is a quark ''C2D''). The ''getSiteNumber(coord)'' convert ''C2D'' back to 1-d ''Unsigned(6)'' The quark ''C2D'' has ''getX()'' and ''getY()'' methods to access the //x// and //y// coordinate values individually.
 +
 +In general, when code is referring to individual fixed sites within the event window, the 1D coordinate system is used (see the 'First' element below for an example).  Two-dimensional C2D indexing is more commonly used when there is some flexibility depending on geometry or relative positions.  
  
  
Line 28: Line 36:
   EventWindow ew;   EventWindow ew;
   Void behave(){   Void behave(){
-    ew[1]=ew[0];+    ew[1]=ew[0]; // Copy self one site west
   }   }
 } }
Line 173: Line 181:
 The ''ew.changeSymmetry()'' method accepts 0,1,2,3,4,5,6,7. We use 0,1,2,3 to let the EventWindow rotate 0,90,180,270 degree to the right hand direction(clockwise). In ULAM primitive types like ''Unsigned'', we can specify any number of bits from 1 to 32. The type ''Unsigned(2)'' uses two bits and has possible values 0,1,2,3. So by giving our ''ns'' data member the type ''Unsigned(2)'' we use as few bits as possible while providing four possible states.  The ''ew.changeSymmetry()'' method accepts 0,1,2,3,4,5,6,7. We use 0,1,2,3 to let the EventWindow rotate 0,90,180,270 degree to the right hand direction(clockwise). In ULAM primitive types like ''Unsigned'', we can specify any number of bits from 1 to 32. The type ''Unsigned(2)'' uses two bits and has possible values 0,1,2,3. So by giving our ''ns'' data member the type ''Unsigned(2)'' we use as few bits as possible while providing four possible states. 
  
-===== Provider, Signal and Request ===== +===== Interaction between three Elements ===== 
-We have tried several elements. Here we implemented a game played by three elements: ''Provider'',''Signal'' and ''Request''. The ''Request'' atoms diffuse around. Whenever they see ''Provider'' atoms, they are consumed by ''Provider'' atoms. The ''Providers'' send out ''Signals'' to attract ''Requests''. A ''Signal'' atom can catch a ''Request'' atom by a gradient check rule. The gradient refers to the number of ''Signals'' observed both by ''Signals'' and by ''Requests''+We have tried several elements above. Here we implemented a game involves three elements: ''Provider'', ''Signal'' and ''Request''. The Requests diffuse around. Whenever they see Providers, they disappear. The Providers send out Signals to attract Requests. A Signal can catch a Request by a gradient check rule. The gradient here refers to the number of Signals observed by Signals and by Requests respectively
 <code - Provider.ulam> <code - Provider.ulam>
 /** /**
Line 314: Line 322:
 } }
 </code> </code>
 +
 +===== Node Elements =====
 +We have some cool features in the new MFM simulator. One of them is that an Atom can change its color dynamically. We made this little ''Node'' element to simulate a neuron node. When a ''Node'' is triggered by its //left neighbors// within its ''EventWindow'', it fires. We let a ''Node'' to display various colors as long as it is trigger. If it doesn't fire, it remains dark. 
 +
 +{{:dev:node_init.png?250|}}  
 +<code - Node.ulam>
 +/**
 +  Node is a demo element.
 +  \color #986
 +  \symbol Nd
 +  \symmetries normal
 +*/
 +element Node{
 +  typedef Unsigned(6) SiteNum;
 +  typedef Int(16) Coord;
 +  typedef Unary(1) FireFlag;
 +  typedef Int(4) Weight;
 +  typedef Unsigned(8) ARGB[4];
 +  typedef Unsigned(8) ColorValue;
 +
 +  DebugUtils du;
 +  EventWindow ew;
 +  Once oc;
 +  AtomUtils au;
 +  Weight wa;
 +  Weight wm;
 +  Weight wb;
 +  FireFlag fire;
 +  Weight thresh;
 +  ColorValue red;
 +  ColorValue grn;
 +  ColorValue blu;
 +
 +  Int getSum(){
 +    Int sum;
 +    C2D mcd;
 +    WindowServices ws;
 +    ws.reset(1,4);
 +    for(Int slot=ws.next();slot>=0;slot=ws.next()){
 +      if(ew[slot] is Node){
 + Atom a=ew[slot];
 + Node you=(Node) a;
 + mcd=ew.getCoord((SiteNum)slot);
 + Coord mx=mcd.getX();
 + Coord my=mcd.getY();
 + if(mx<0){
 +   if(my<0){
 +     sum=sum+wa*you.fire;
 +   }else if(my==0){
 +     sum=sum+wm*you.fire;
 +   }else if(my>0){
 +     sum=sum+wb*you.fire;
 +   }
 + }
 +      }
 +    }
 +    return sum;
 +  }
 +  FireFlag getFire(Int s){
 +    if(s>=thresh){
 +      return 1;
 +    }
 +    return 0;
 +  }
 +  Void initSelf(){
 +    Random rd;
 +    Weight w;
 +    wa=(Weight)rd.between((Int)w.minof,(Int)w.maxof);
 +    wm=(Weight)rd.between((Int)w.minof,(Int)w.maxof);
 +    wb=(Weight)rd.between((Int)w.minof,(Int)w.maxof);
 +    thresh=(Weight)rd.between((Int)w.minof,(Int)w.maxof);
 +  }
 +  Void changeColor(){
 +    Random rd;
 +    red=rd.between(0,3)*80+rd.between(0,16);
 +    grn=rd.between(0,3)*80+rd.between(0,16);
 +    blu=rd.between(0,3)*80+rd.between(0,16);
 +  }
 +  ARGB getColor(Unsigned selector){
 +    ColorUtils cu;
 +    ARGB ret=cu.color(0xff00ff00u);
 +    if(fire==1){
 +      ret[1]=red;
 +      ret[2]=grn;
 +      ret[3]=blu;
 +    }else{
 +      ret=cu.color(0xff090806u);
 +    }
 +    return ret;
 +  }
 +  Void behave(){
 +    Int msum;
 +    if(oc.new()){
 +      initSelf();
 +      du.printContext();
 +    }
 +    msum=getSum();
 +    fire=getFire(msum);
 +    changeColor();
 +  }
 +}
 +</code>
 +
 +We use a ''Once'' quark to call the ''initSelf()'' //once//. We have used a lot of quarks before without realizing that. The ''EventWindow'', ''DebugUtils'', ''Random'', ''AtomUtils'' are all quarks. It's the same thing here to use a ''Once'': instantiate ''Once oc'', then use ''oc.new()'' to decide if this is the first time of a call. 
 +
 +In the ''changeColor()'' of this ''Node'' element, we use ''ARGB getColor()'' to give new color values. This ''getColor()'' returns a array with Four values: //Opacity//, //Red//, //Green// and //Blue//.  
 +
 +Like other Neurons, our ''Node'' will be fired by neighbors. In this simplified case, only the //left neighbors// can trigger our ''Nodes''. This time we need to scan the whole ''EventWindow''. To decide which neighbors are located to the left we use C2D coordinate. Those Atoms with negative x coordinate are to the left of our ''Node''
 +
dev/program_ulam.1433043424.txt.gz · Last modified: 2015/05/31 03:37 by xychen