Tutorial: Making interactive CPMs in the browser with Artistoo

7. Custom constraints and Hamiltonian terms

So far we've worked mostly with the Act-CPM, but a key strength of the CPM is that you can customize it by adding terms to the Hamiltonian. We'll now see how you can customize your models further by defining your own "constraints" in Artistoo.

Constraints in Artistoo: "hard" vs "soft" constraints

Artistoo has two sorts of constraints that you can also define yourself:

  • "soft" constraints; these add a term to ΔH to modify behavior in the CPM. They can make certain copy attempts very (un)favourable, but what happens remains stochastic and even unfavourable attempts might still occur.
  • "hard" constraints; if these are not satisfied, the copy attempt fails and the Hamiltonian is not even computed anymore. For this reason, it is good to use hard constraints when this is the behavior you want (instead of defining a "soft constraint" with ΔH = Infinity, which would do the trick but be less efficient).

Example of a custom constraint

Please open 7-hardconstraint.html in a text editor and your browser. In the browser, you should see a bunch of Act-cells that are confined by an invisible circle. This is the result of a custom HardConstraint that "forbids" copy attempts into pixels outside of this circle.

Now have a look at the code in the text editor. It should look pretty familiar, with a few notable additions:

  • We define a new "class", extending the HardConstraint to get our desired behavior (more on that below)
  • Our custom constraint is again added in setup(). Note that we leave out the CPM. prefix because this constraint is defined locally and is not part of the Artistoo library.

As you can see, the code is all pretty standard except for the definition of the constraint class itself. Inside the new class, you will find three functions (note how they are not prepended with "function" because they are not globally available but belong to the class):

  • constructor( conf ).
    This is called when you use new HiddenFigures( {...} ) to create a new constraint of this class. You can pass it a configuration object conf containing any parameters for your constraint, which is passed along to the constructor of the parent class (HardConstraint) via super(conf). The configuration will then be available from inside the constraint class under this.conf. You can also attach other properties to this here as you can see in this example.
  • withinCircle(i).
    In this specific case we have added this function to check if a given pixel is within our circle or not. There are two things to note here:
    • The input argument is a so-called index coordinate. Under the hood, Artistoo uses this for speed. See the link for more information. When you are doing stuff infrequently (e.g. only after an MCS, such as drawing or computing statistics) it is fine to use regular coordinates of the form [x,y]. But constraints are called much more often (every copy attempts), so it is worthwhile using the index coordinates instead.
    • See how we are accessing the CPM through this.C. We can do this because C.add(...) attaches the CPM to this. But since we call C.add(...) after generating a new HiddenFigures( {...} ), this means you will not be able to use this.C inside the constructor yet!
  • fulfilled(src_i, tgt_i, src_cid, tgt_cid)
    every HardConstraint must have this function with exactly these arguments, because the CPM will look for this method whenever a copy attempt is proposed.

Exercise
Can you figure out how to modify this constraint into a soft constraint, which does not "forbid" copy attempts out of the circle but instead penalizes them with some λ in ΔH?

(Hint: check out SoftConstraint. It works similar to the hard constraint version, but instead of fulfilled it needs a deltaH() function. )

Check out 7-softconstraint.html if you get stuck.

When you're done, hit "next" for the last exercise!