text:
Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From \$16.50/m

# Build an AS3 Tetris Game From the Ground Up

by

In this Active Premium tutorial we'll be creating a variant of the classic Tetris game, explaining general game concepts as well as some specific to this genre.
Test the demo above, but don't play it for too long - you'll soon find out that making it can be as fun as playing it.

## Introduction

Let's start with a short history lesson for those who are not familiar with this game (even though I doubt that it's an unknown game to anyone).

Tetris is a puzzle video game from the 80s in which pieces made out of four square units (or cells) fall down in a grid (or matrix) and you have to move and rotate them until they land so that you obtain horizontal lines of units without gaps.

The pieces in the game are called tetrominoes and are geometrical shapes composed of four squares. There are five unique tetrominoes; however in the Tetris game we use two more which are reflections of two pieces from the first five.

The game was designed and programmed by Alexey Pajitnov and released in 1984 and still remains a popular game although many variations of the game were created (but using the same concept).

To read more on Tetris game, Tetrominoes, and associated topics, you can read their wiki pages: Tetris and Tetromino.

## Prerequisites

For this tutorial I'll be using FlashDevelop (see a guide to installing and using that here) but you can use whatever software you like (Flash CS3+, Flash Builder, FDT). If you don't like or you can't get FlashDevelop for whatever reason I strongly recommend that you use something other than Flash because of the weak code editor it has and because we will only be writing classes and you'll like the features that you find in a strong code editor. But if you'll only be copying and pasting Flash will do just fine.

## Step 1: Creating the Main Game Class

First of all let's create the main class of our game. For now it will only be an empty class that we'll update along the way.

Name the class Tetris and make it extend the Sprite class.

Note: If you are using Flash Professional this could be set as the document class. It could alternatively be instantiated as a simple display object on the timeline or in a class:

If you are using FlashDevelop and want to use this class as the main class you can right-click on it in the Project panel and select Always Compile from the context menu.

## Step 2: Creating the Unit Class

The Unit object is the primary object used in our game, and represents a single "block" within a tetromino. The Tetris playfield is a two dimensional array which holds references to Unit objects representing the fallen tetrominoes. Create a new class and set its name to Unit.

The Unit object will be characterized by two basic properties: the x and y position in the grid. These are both integers. The _type variable will be used to identify the type of the Tetromino in which the unit resides. We'll discuss Tetrominoes and their types in later steps.

## Step 3: Adding Getters and Setters for the Properties

Because the _x and _y properties are both declared as private we need a way to access them from outside the class. This can be accomplished by adding getters and setters:

You may be wondering why go through all this trouble just for two properties. To be short, we need to control the modifications of the coordinates as you will see later on.

## Step 4: Creating the Unit's Visual Representation

Okay. Up until now we have nothing to see so let's create a visual representation of a Unit object. This will be represented by the Box class:

As you can see the Box class has two properties, one which is private and holds the color of the box, and one which is public called SIZE. The last one is a constant and it's static because it's common to all Box objects and we'll need to use it later on when creating the grid. You can consider this as a scale of a unit's size (which is 1x1, so our units will, eventually, be 30x30px).

## Step 5: Drawing the Box

Right now the Box class does nothing. Add the following lines to the constructor of the class:

As you can see we set the _color property to the constructor's color parameter and we call two methods named draw() and addEffects() so we must create them too.

The draw() method:

Here we basically draw a 30x30 rectangle with 1 pixel border. We use the SIZE static constant to set the size of the rectangle.

In this method we create a BevelFilter and add it as a filter for our box. For this to work you will need to import the BevelFilter class also:

## Step 6: Linking the Display to the Unit

Now that we have a visual representation ready, go back into the Unit class and add a new private variable _display of type Box:

Also add a new public method called toDisplay() in which we check whether an Unit object has a visual representation and create a new one if not.

To see the result add the following lines of code in the Tetris class:

First add a new private variable _u

Then add the following lines of code in the constructor of the class:

A red beveled rectangle should appear on the stage.

Note: I've used the following line of code to set the stage size, color and frame rate:

You can add it just below the import statements in the Tetris class.

## Step 7: Moving the Created Unit

Now that we have a something displayed in the screen let's go ahead and move it. In the Tetris class add a new private variable _timer of type Timer, attach an event listener to it and call the start() method:

Also create the onTimer() event handler function; in this we will increment the y property of the Unit object created earlier:

This should result in moving the box on the screen by one unit. However if you test the movie now the box will stand still. If you didn't notice we set the y property of the Unit object which is not a display object. We have to update the position of the _display object in the Unit class which is the actual visual representation on the screen.

## Step 8: Updating the Unit's Display

To update the display of the unit we need to update the x and y setters as show below:

This will update the position of the Box object by a number of pixels equal to its size.

If you test the movie now you should get the same result as me: the box drops down each 700ms by 30 pixels.

## Milestone 2

Refresh the page if the above SWF is entirely black.)

## Step 9: The Tetromino

Okay, now that we have a unit and we can move it we will create the larger piece made out of four units. Before we actually start doing that we need to discuss the Tetromino object.

A Tetromino is a cluster of four units orthogonally attached. There are a total of seven Tetrominoes in the game although only five of them are unique combinations of units.

The seven shapes are as follow:

1. The I shape
2. The J shape
3. The L shape
4. The O shape
5. The S shape
6. The Z shape
7. The T shape

## Step 10: The TetrominoType Class

To have a quick reference to the seven types of Tetrominoes we'll create a TetrominoType class which will store all of them and give us access to them by the representing letter.

In this class we currently have added some public static constants which represent a Tetromino type, a private variable which represents the type of the TetrominoType object and the getter and setter for the _type private property. Also there is a toString() method which returns a string representation of the TetrominoType object.

Next I've added a isValidType(type) method to check whether the passed type is a valid one. This is not strictly necessary but it's good to have the highest degree of control for every possible error source.

Note: If you're not familiar with the multiple case statements without a break keyword, this is used to test multiple values and execute the same command for them all.

Also you need to update the type setter to check whether the type is valid and throw an error if not:

## Step 11: The Tetromino Class

Now that we have created the TetrominoType class for better control over the type of a Tetromino piece let's create the actual object.

As said before a Tetromino is made out of four units in seven possible combinations so we need to add four private variables representing the units and a private variable holding the type of the Tetromino object.

The getters are used to access each unit of a Tetromino later on.

## Step 12: Generating Each Shape

Next we need to group the units based on the specified type.

Note: Don't forget to add a call to the generateGroup() method in the constructor of the class just after assigning the type

The generateGroup() method uses a switch-case statement to create the shape based on the type. Each type is constructed in its own method so we need to write them next:

In each creation method we assign a new unit of some given coordinates for each unit variable in the class and set the types of those units as the type of the created tetromino.

## Step 13: Explaining the Coordinates

To better understand how we assigned the coordinates to each unit let's take a look at the following drawing made for the J shape:

Here we have a 2D coordinate system where the X axis positive direction is towards right and the Y axis positive direction is downwards. A single square represents a unit in the coordinate system and the numbers along each axis represent coordinate values for each square.

The white numbers inside each filled square represent the unit number.

So if you look at this example you'll see that the J shape has the following coordinates for its units:

• Unit 1: X = 0, Y = 0
• Unit 2: X = 0, Y = 1
• Unit 3: X = 1, Y = 1
• Unit 4: X = 2, Y = 1

The same goes for the rest of the Tetrominoes. You can use the previous drawing to check the coordinates for each Tetromino.

Note: Each unit in a Tetromino is numbered from left to right on each line.

## Step 14: Adding and Moving the Tetromino

Now that we have our piece let's see how to create it and move it. Make the following modifications to the Tetris class:

In here we have replaced the _u variable with the _t variable of type Tetromino. After creating the Tetromino we've added to the display list the visual representation of each unit in the piece. In the event handler for the TimerEvent we're incrementing the y coordinate for each unit in the Tetromino.

If you test the code now you should see a J tetromino falling down.

## Milestone 3

(Again, refresh the page if the blocks have already fallen off the bottom of the SWF.)

## Step 15: Getting a Random Shape

Right now each time we compile we will get only a J shape which is not really the only shape. We need to fix this as we want to get a random shape each time one it's created.

This can be done easily from the TetrominoType class but before going further let's take a look at the method of randomization and its rules.

I've used an implementation of Tetris's Random Generator which is briefly discussed here. To keep it short the rules say that the first spawned Tetromino should not be O, S or Z. After the first piece the game must pick some pieces and if there were recently spawned to try again for a limited amount of tries.

To achieve what we need we'll use an array holding the four most recently spawned shapes. Add the following line of code into the TetrominoType class:

## Step 16: Randomization Method

Now that we've added an array representing the history of spawned types we'll create a public static getter which will be used to return a random type:

In here a for loop is used to get a random from the ALL[] array and test if it has been recently created.

Notice that we've used a property called randomPosition which gets a random index from 0 to 6.

Also there are two more methods: the isRecent() method which tests if the current type exists in the history

and the addToHistory() method which adds the selected type to the recently spawned types array.

Last but not least we need to modify the Tetromino class so that a random type gets selected. To do this open the Tetromino class and change the following line from the constructor

into

Now before testing we need to change one more thing. If you haven't noticed the color of a unit is always red and we'll want to have certain color for each tetromino type so let's fix that.

## Step 17: Colors of Tetrominoes

For this tutorial I've chosen the following colors which are based on The Tetris Company standardization but feel free to change them to whatever you want:

• The I shape: cyan (0x00FFFF)
• The J shape: blue (0x0000FF)
• The L shape: orange(0xFF8040)
• The O shape: yellow (0xFFFF00)
• The S shape: green (0x00FF00)
• The T shape: purple (0x800080)
• The Z shape: red (0xFF0000)

After you have settled on what colors you'll use go ahead and create a class to hold this data. We'll call the class TetrominoColor.

## Step 18: The TetrominoColor Class

Create a new class, name it TetrominoColor and add a private variable in it called _color of type uint.

The type type parameter represents the type of the tetromino.

Also there's a getColor() method which is used to return the color corresponding to the specified type.

In the getColor() method we'll use a switch-case statement to get the right color code.

And to finish the class let's add two more methods (toString() and toUint) to return the color from the TetrominoColor object as a string and as an unsigned integer.

## Step 19: Random Tetromino of Corresponding Color

Now that we have modified the TetrominoType class to generate a random tetromino each time and we've created the TetrominoColor class to give us the color corresponding to each tetromino type,, we'll make some small modifications to make things work properly.

First of all in the Tetris class change the following line from the constructor:

into

This will generate a random tetromino each time when we compile instead of creating a specific type.

The second thing we need to do is change the color of the Box object in the toDisplay() method of the Unit. Right now the color has a constant value of red (0xff0000). To get the corresponding color change the line

into

If you test the code now you should get a random tetromino with its associated color each time when you compile the project.

## Milestone 4

Okay. Up until now everything works just fine, but using just a timer to move our pieces doesn't give us much control. What we need is a class to simulate some kind of gravity in which we can register pieces to be affected by it, control the falling speed, be able to start and stop the dropping and also to unregister pieces so that they're no longer affected by it.

To do everything I've enumerated we'll make use of a class called Gravity which will encapsulate all these features.

As you can see in the Gravity class we still use a Timer to control the gravity step, but we also use a _velocity variable which will be increased with the level and that will change the timer delay so that pieces will fall faster and faster.

First of all let's add a getter and setter for the velocity.

## Step 21: Registering and Unregistering Actions

Now that our class is set we need to add some functionality which allows us to register and unregister certain actions that will be performed at each timer tick.

For this we'll use the register(action) and unregister(action) methods in which action represents the function to be executed (this will be used as an event handler for TimerEvent events).

## Step 22: Starting and Stopping

Finally we need a way to control the falling as in stopping and starting it.

To start or stop the gravity we simply call the start() or stop() methods on our timer. With this our Gravity class is complete.

## Step 23: Testing the Gravity

Now that we have a Gravity class let's make a test run. Back in the Tetris class remove the _timer variable and rename the onTimer() event handler into moveDown() and pass in null as the default parameter.

After that add the highlighted lines into the constructor and test the movie. The obtained result should be the same as the previous one. The only difference is that we've separated the gravity logic from the main class.

## Step 24: Increasing Control

So if we look over what we've accomplished up to now we can see that our game is taking shape -- but it's still far from complete. The piece we spawn is currently added right in the display list and we have no direct way of controlling the position of its units.

The Tetris playboard is composed out of a grid (well, matrix) of 20 lines and 10 columns in which the moving piece can move. To add this bounds we will use a two dimensional array (or matrix in which we'll store the units of the landed pieces.

In this class we have three private variables. The first two, _lines and _columns, obviously hold the number of lines and columns of the grid, and the third one is an array which will hold every element from the grid.

The constructor accepts two parameters representing the number of columns and lines, as you may want to have more (or less) than 10 columns or 20 lines.

The createGrid() method creates the two dimensional array (or matrix) by creating an array with the same number of elements as the number of columns (representing one line) and adding it to each element in the _grid array which obviously has the same length as the number of lines.

Beside the getters for the number of lines and columns we also have a method called getUnitAt(x, y) to return a unit from the grid at a specified position.

## Step 25

The only thing we need to have to do now is add a couple of methods: one to check whether a unit exists at a specified place in the grid and one to set a unit in the grid at its location. The isUnitAt(x, y) and setUnit(unit) methods do what we need.

In the isUnitAt() method first checks whether the y coordinate of the unit is negative (meaning that the unit is outside the grid being freshly spawned), after which it checks whether the x and y coordinates are contained by the grid and returns true if that location is occupied or false otherwise. Lastly if the other conditions are not fulfilled it means the specified position is outside the grid (meaning left, right or under the grid -- places where a unit can't be).

Also add another method to the class which will clear all elements in the grid.

We'll use this method much later in the tutorial when we'll want to stop the game.

## Step 26: Discussing Movement

Now that we have a grid to contain our pieces and have defined some bounds for it we need to further extend our game by adding a class to control the left, right, down movement and the rotation of a piece.

And so we'll create the MotionManager class but before we go there let's discuss how things are moved in tetris.

Left, right and down movements are obvious. A piece can only move left or right if none of its units is obstructed by a wall or another unit. The same goes for down movements, the only difference being that when the pieces hit the ground or are on top of another piece these are landed and cannot be moved further, another piece is spawned.

Rotations are a bit tricky to obtain but basically they are the same. We can only rotate a piece if it's not obstructed by the wall (the left or right edges) or by another unit. Also a tetromino rotates around a central point which is considered to be one of its four units (or, better said, three out of four units rotate by ±90 degrees relative to the other unit which is fixed). To simplify the rotation method I've considered that all tetrominoes rotate around their third unit. Study the following image to better understand the concept.

In this picture you can see the four possible positions of each tetromino rotated by 90 degrees clockwise. The only tetromino that doesn't rotate is the O tetromino.

## Step 27: The MotionManager Class

The constructor of this class takes the game grid as a parameter which is also referenced by the _grid private variable. The private static constant PI represents the value of Math.PI and will be used in later calculations.

## Step 28: Moving Down

To begin with let's take a look at the method used to move the tetromino down.

Important! If you copy and paste the code you must make the necessary imports in the class.

Tip: If you're using FlashDevelop you can click on the class name you want to import anywhere in the code and pres Ctrl+Shift+1 to automatically insert the import statement.

First of all in this method we check whether each unit is not on the last line then we test if there are any units at the new locations. The new locations are calculated as the current locations in which we add 1 to the y coordinate. If the locations in the grid are not occupied by any other landed unit and it's between bounds we move each unit by 1 on y else the method returns false and the tetromino has landed.

## Testing the MotionManager

Now that we've added our first method to the MotionManager class let's test it along with the Grid class.

In the Tetris class add two new private variables _m of type MotionManager and _grid of type Grid.

Next add the highlighted lines below to the constructor. These define a new 20x10 grid and the motion manager which is making use of that grid.

And to make use of the MotionManager change the moveDown() method like so:

Test the movie and if everything is ok you should see the same result as the previous one, the only difference being that the MotionManager class controls the downward movement and the tetromino will stop when it hits the bottom of the stage (if you've used the metatag that I've talked about in Step 23) meaning that the tetromino has hit the bottom of the grid.

## Milestone 6

Next we'll take a look at moving the piece left and right.

## Step 29: Moving Left and Right

Now let's create a method to move the tetromino to the left.

This method is similar to the downward movement method only that now we move the tetromino on the x axis thus we're using the x coordinate from which we subtract 1. Also we test that each unit isn't out of bounds meaning that they don't pass the left wall.

Moving the tetromino to the right is identically like moving it to the left the only difference being that we add 1 to the x coordinate and check that the units aren't passing their right bound (the right wall).

You can add some keyboard events in the Tetris class to test the left and right movement but I'll suggest that you wait until after we've wrapped up the MotionManager class by adding rotation capability.

## Step 30: Distance and Orientation

Before we start doing the actual rotation we'll define two methods, getDistance(x1, y1, x2, y2) and getOrientation(x1, y1, x2, y2), which we'll use to calculate the distance and orientation between two points using their coordinates.

## Step 31: Rotation Method

Now that we have defined the necessary methods to provide the distance and orientation between two points we can start creating the rotation method. This method will apply for all tetrominoes except the O tetromino.

Okay. I know this looks hard and geeky but it is basic trigonometry so let me explain.

First of all we calculate the distance and orientation between the fixed unit (unit 3) and the other units (units 1, 2 and 4).

Note: The orientation represents the angle between the positive direction of the X axis and the direction between two points measured counter clockwise.

Then we add/subtract 90 degrees to/from the current orientation of each two units, obtaining the new orientation.

After which we calculate the new coordinates of each unit (unit 1, 2 and 4) using the distance and orientation and round them up so that we obtain integer values.

Note: The coordinates of a point are calculated using the distance and orientation using the following formula:

in which D represents the distance and θ (pronounced "theta") represents the orientation.

And finally we test if the new positions are empty in the grid and move the units accordingly. If any of the three positions are occupied the method returns false and rotation doesn't happen.

## Step 32: Testing Sideways Movement and Rotation

Now that we've finished our class adding all necessary capabilities (moving down, sideways and rotating) let's give it a test run and see how our game is growing more and more.

In the Tetris class add the following code on the last line of the constructor:

Then create the onKeyDown() event handler in which we use a switch-case statement to test what key was pressed and do the corresponding action.

Run the project and see the result. Now you should be able to move the tetromino left and right and rotate it. As you can see it will remain between the bounds of the defined grid meaning that a unit can only move 10 spaces maximum to the left or right and it will not cross over the bottom line.

## Step 33: Encapsulating the Playfield

Now that our game is growing we need to separate the playfield from the rest of the game. By this mean the grid in which the pieces are added. The GameCanvas class will represent the playfield separating it from the other game elements which we'll add later (scoreboard, piece preview, buttons).

The first thing we need to do in the GameCanvas class is to associate a grid to it.

With the drawCanvas() we'll draw an actual grid on the playfield using the drawing API and set a glow filter on it.

The addMask() method creates the mask for the playfield which is used to mask two grid lines in which the newly added piece resides.

## Step 34: Grouping Features

Now that we've created the canvas the next step is to add all the features previously created like gravity and motion. We'll start off by creating the variable which will hold the corresponding classes.

After this we'll create a new method called init() in which we'll instantiate all the necessary elements (for now only the _gravity and _moManager() objects and the addMask() method).

Notice that we've passed the previously created grid as an argument when creating the MotionManager object.

Also we'll need to call the init() method from within the constructor.

The last thing we need to add for now is a tetromino and a tetromino holder so let's do that right now. Add three new variables called _currentPiece, _nextPiece and _pieceHolder.

Next add the highlighted lines in the init() method:

## Step 35: Testing the Canvas

Before going any further let's test our canvas and see if everything goes as expected. Clear the Tetris class and add only one private variable in it of type GameCanvas named _gameCanvas. After which create the addCanvas() method in which we instantiate the canvas object and add it to the display list.

If all your code is similar to mine then you should see a bluish 20x10 grid on the screen. This is the canvas or playfield where the pieces will appear and move.

## Milestone 8

Next let's add the rest of the functionality.

## Step 36: Adding the Current Piece

What we should do next is create the current tetromino and add it to the canvas.

First of all write the createPieces() method which will be used to generate a new random tetromino.

Next create the addNew() which adds the visual representations of the tetrominos units in the display list, precisely in the _pieceHolder sprite created in Step 34.

We will want to remove the units from the _pieceDisplay sprite eventually when a new piece is generated so we'll add another method which does exactly the opposite.

Last thing we'll want to do is wrap the whole process into one method which we'll call updateView(). This method will be used to render the pieces at each movement.

## Step 37: Offsetting the Units

If you add the createPieces() and updateView() method calls after the last line inside init() you should see a random tetromino appearing on the stage. The only problem is the position of this piece being next to the left wall on the first two lines.

We want these pieces to appear two lines above the first line (being masked) and in the middle of the grid.

The offsetPiece() method will have the purpose of moving the piece two lines above the first line and in the middle of the grid. The I tetromino will start from the fourth column (x = 3) and only at a line above the top one (y = -1). Any other piece will start from the fifth column (x= 4) and from two lines above the first one (y = -2).

To achieve the desired effect we simply add/subtract the required values from the coordinates of each unit in the current piece after using an if-else statement to check the tetromino type.

The last thing we need to do is change the createPieces() method accordingly.

If you test the movie now you should only see the grid as in the previous milestone. Remove these two lines from the init() method and let's go forth.

## Step 38: Start, Stop, Pause, Resume

Before diving deeper into the code let's add two more variables to our GameCanvas class.

• _clearedLines will hold the total number of cleared lines in a level
• _level will hold the current level of the game

## Starting the game

First of all let's take a look at the start() method.

As you can see I've added the movePiece() method for moving the tetromino down and registered it to the gravity. There's a e:TimerEvent = null parameter because the gravity class requires it and it's set to null as we may need to call it without a TimerEvent being fired.

## Stopping the game

The stop() method is really easy to understand. In it we simply stop the gravity, unregister the associated action and set the current piece to null.

## Pausing and resuming the game

By pausing and resuming the game we only need to stop and respectively start the gravity. The highlighted lines contain two methods that we'll discuss next.

## Step 39: Keyboard Functionality

The last thing we need to do before adding extra features to the game is restore keyboard functionality, which is basically the same as in Step 32 with only minor differences.

Start off by creating two methods used to register and unregister the keyboard events. These are just adding and removing the KeyboardEvent.KEY_DOWN events on the stage and give us a shortcut so that we don't have to write too long lines of code.

Now in the onKeyPress(e:KeyboardEvent) event handler we use a switch-case statement in order to check what key was pressed and execute the corresponding function.

We unregister the keys so that the event isn't fired continuously and we also add an event listener for KEY_UP events.

Before going to the next step add the following blank method. We will discuss each one of them separately.

## Step 40: Moving Left, Right and Rotating

In the moveLeft() and moveRight() methods we just use the motion manager to move the current tetromino left or right.

The rotate() method is just as simple the only difference being that we check whether the argument says "left" or "right" and rotate the piece appropriately.

## Step 41: Quick Drop

Dropping refers to moving a tetromino down at a higher speed when holding a button down.

In Tetris there are two types of drops: soft drop and hard drop as explained next.

• Soft drop – a piece is moved downwards at a higher speed when holding a specific button down
• Hard drop – a piece is instantly moved down on the floor when a specific button is pressed

We are going to use the first kind of drop in our game and we're going to refer to it as "quick drop". For this some minor modifications must be made to the Gravity class.

First we're going to add a constant in it that represents the quick drop rate (the smaller the number the faster the drop). The number represents the number of milliseconds that a tetromino takes to go down by one unit.

Next we'll have to add a setter to the class, which we can use to change the timer delay from normal to quick and vice versa.

Also we'll add a getter which can be used to see if the gravity is in quick drop mode or not.

Now that the gravity class is complete we need to add the rest of the logic back in the GameCanvas class. Add the highlighted lines to the quickDrop() method to finish the implementation.

The unregisterKeys() method is used because we want to restrict any other movement while in quick drop.

## Step 42: Completing and Testing Movement

The last method that we want to complete in our GameCanvas class is the event handler for KEY_UP events. When the user releases a key we need to subscribe for KEY_DOWN events once again and if in quick drop mode to return into normal gravity mode.

Lastly we need to register the keys right when the game starts (back into the start() method).

If you test the movie right now nothing would happen and you'd only see the grid on the stage. That's because the game isn't started. To start the game go back into the Tetris class and add the highlighted line in the addCanvas() method.

## Step 43: Landing a Piece

Until now we can do most of the actions required in a basic Tetris game but we only have a tetromino spawned and when it lands nothing happens. Next we'll need to add some action for when a tetromino touches the ground (or another tetromino) in which we want to spawn the next piece for now. Later we'll further extend the game by checking for full lines or end the game when a piece lands.

Before creating the actual method to land a piece we need to add another variable which will be the sprite that holds the landed pieces.

Also instantiate the _mainHolder in the init() method and add it to the display list.

In the landPiece we simply move all the units from the _pieceHolder into the _mainHolder

However this is not enough, after we land the piece we need to create a new one. To achieve this we need to modify the movePiece() a bit.

In here we test if the piece can move down and if not we first land it and then we create a new one.

## Step 44: Setting Units in the Grid

If you test the movie now a new piece will be spawned as the old one hits the ground. however there's a glitch: the pieces blend together. To fix this we need to set the units of the landed piece into the grid.

The setUnits() method checks whether all the units have positive y coordinates so that we won't get an error if the tetromino is outside the grids bounds. Then we simply set in the grid each of the four units from the current piece.

And lastly we need to execute the setUnits() method from within landPiece().

Now you can test the movie and see how pieces are spawned and landed.

## Milestone 10

Note: If you keep the down button pressed even after the current piece has landed the newly spawned piece will also be quick dropping. If you don't want this behavior simply set the quickDropMode property of the _gravity object to false inside the if-statement from the movePiece() method.

## Step 45: Removing Filled Lines

Next step in creating our Tetris game is adding methods which remove full lines and compress the remaining empty lines.

We're going to start by adding a method to the Grid class which removes the lines from the actual grid so open up the class and add the clearFullLines() method.

This method uses two for loops to check whether any line is filled with units and removes the lines that are after which it adds a new empty line at top. Also the method returns the number of removed lines.

## Step 46: Removing Lines From Canvas

Now that we defined a method to remove filled lines from the grid let's use it in the canvas and remove the lines from there also.

Back in the GameCanvas class add a new method called removeFullLines():

This method calls upon another method updateMain(). The updateMain() method removes all units from the canvas including those that are no longer part of the grid using removeAllFromMain() after which adds the remaining units from the grid back to the display list.

If we don't update the units from the main holder then the filled lines would be removed from the grid but not from the canvas and the well would be filled with units that are no longer part of the grid.

Only thing we have to do now is to call the removeFullLines() method each time a piece lands (meaning in the landPiece() method).

also we'll call this method whenever a new game is started.

## Step 47: Fixing It!

If you test the movie now you should see that whenever a piece land and lines are filled these lines are removed. However there's a problem; the remaining lines don't shift down. Actually they shift the _grid object but the remaining units need to have their coordinates updated also.

To fix the positioning problem go back into the Grid class and add the following method:

By doing this we go through each position in the grid and if a unit is set at the corresponding coordinates we update that unit's position.

And to make this work we need to add a call to this method right after the return statement in the clearFullLines() method.

Press Ctrl+Enter or F5 on the keyboard (if using FlashDevelop) to run the project and see how every filled line is disappearing.

## Step 48: Scoring

We are done with all the game logic for the moment. However, our game currently misses an essential piece in any game: score.

Next we'll focus on creating a score display widget which will display the score and the current level as well.

Create a new class ScoreDisplay which extends the Sprite class.

In this class we have the following variables:

• _scoreField and _levelField are the text fields for displaying the score and respectively the level
• _score will hold the actual score points. We set it to 0 because initially the game score is zero
• _level will hold the current level which is an unsigned integer and is set initially to 1

... and a method draw() which draws an invisible rectangle surrounding the score widghet.

## Step 49: Configuring the Text Fields

Because we have two text fields which will look the same let's create a method which sets up a text field to look like a digital board. This is what addField(textField) method does.

And to set up the two fields add the highlighted lines to the class constructor:

Note: On the third line of the addField() method we assign a font called 'Digital'. This font is actually named DS-Digital and we'll be embedding it later in our game.

## Step 50: Adding the Text to the Fields

Right now both the text fields are empty so let's add some text to them. For this we'll use two methods: one for the score field and one for the level field.

In the setScoreText() method we use multiple if-else statements to add leading zeros to the score text depending on how large the score is.

For the level field we only have to append the level number to the "Level:" text.

And to update the text in the fields from the beginning add the highlighted lines in the constructor:

In the third highlighted line we position the level field below the score field.

## Step 51: Resetting

Whenever the game is ended/stopped we need to reset the score and the level in the widget. For this we'll use the reset() method shown below:

Simple as that!

## Step 52: Adding the Widget to the Game

Okay. We've created the widget so let's add it to our Tetris class.

First open the Tetris class and add a private variable to reference the score widget.

Then write the following method to instantiate and add the ScoreDisplay object to the display list.

Also add a call to this method within the constructor just after the addCanvas() line.

If you test the movie now you won't be able to see anything because the font used for the fields does not exist.

## Step 53: Embedding Fonts and Testing

First go to this webpage http://www.dafont.com/ds-digital.font and download the DS-Digital font (or whatever font you want for that matter). We we'll only use the normal and bold-italic font faces -- meaning the DIGI.TTF and DIGIT.TTF files -- so place them inside your project folder. I have copied mine inside the lib folder created by default in FlashDevelop.

Then add the next two lines in the Tetris class just before the variables declaration block to embed the fonts in your game:

Note: The source attribute defines the file path to the font files. You will have to replace it with your own file path.

The pieces of code I've commented out (embedAsCFF) are used when embedding fonts in Flash CS5/Adobe Flash Builder (using Flash Player 10.1) using the new Text Layout Framework (TLF) engine meaning that the font will be embedded as Compact File Format.

By testing the game you should see the scoreboard appear but the score won't update.

## Step 54: Game Events

Right now it's time to write our first event for the game. We'll use this event for various actions: updating the score, updating the level and updating the piece preview.

Start by adding a new event in the project:

The highlighted lines represent what I've added to the basic custom event class.

The private variables represent the level passed to the event, the number of cleared lines when the event is fired, and the piece type when a new piece is spawned. The _params object will hold all the parameters passed through the constructor. We pass the parameters within an object so that we won't be forced to pass all of the every time.

The static constants represent the three possible event types:

• LEVEL_INCREASE event will be fired every time when the level is increased
• SCORE_UPDATE event will be fired whenever the score is updated (lines are cleared)
• PIECE_UPDATE event will be triggered each time when a new piece is spawned

## Step 55: Scoring System

Before going further let's talk a bit about the game's scoring system.

In accordance with the Tetris Wiki we will use an implementation of the original Nintendo scoring system in which line clearings are scored by combos. The following table defines the scoring method:

I think this is simple enough and quite fair for this type of game. You can implement whatever scoring system you want by using a timer, the number of spaces you've quick dropped a piece, and so on and so forth.

## Step 56: Scoreboard

Now that we have our event ready to be fired and we have a basic understanding of how score points should be earned we'll modify the score display widget to change the score and level based on the parameters passed through this event. Open the ScoreDisplay class and add the following two methods:

As you can see this method uses a switch-case statement to calculate the score based on the number of lines and level.

Updating the level is just as simple as incrementing the current level by one.

## Step 57: Dispatching...

In order for everything to work first we'll add a new method in the GameCanvas class...

... and call it whenever 10 lines have been cleared more precisely in the removeFullLines() method:

Here we also dispatch a SCORE_UPDATE event for notifying listeners that the score has changed.

The other places where we should add event dispatchers are:

- when creating a new piece. This will be used to update the piece preview later on.

- and when starting the game

## Step 58: ... and Listening

Now we only have to add event listeners for the corresponding events back in the Tetris class...

... and their corresponding event handler functions:

Note: I've moved the line _gameCanvas.start(); from the addCanvas() method to the constructor of the class so that it won't throw an error upon compiling.

You can now test the game and see the result.

## Step 59: Previewing Next Piece

As the title of this step says now we're going to create yet another widget which will display the next piece in queue.

If you haven't noticed in Step 57 I've made the following modifications to the createPieces() method:

By doing this two pieces are created at a time: the current one and the next one.

Our new class which instance will display the next piece to be spawned will be called PieceDisplay:

In this class we have a _label which is the text that says "Next piece" and two methods draw() and setLabel().

## Step 60: Setting the New Piece

To display a tetromino in the preview widget we'll need to add its corresponding units to the display list.

The highlighted line is used to call a method to offset the tetromino by a certain amount so that it's displayed centered.

To remove a tetromino we'll have to remove all children of the tetromino that are units.

Lastly we define a setter to set the new piece:

We made this method public because we may want to access it from outside the class.

## Step 61: Updating the Tetris Class

Last thing we need to do is update the Tetris class by adding the PieceDisplay widget to it.

Open the class and add a new private variable private var _pieceDisplay:PieceDisplay; then add the widget to the game through the addPieceDisplay() method:

and finally update the widget in the event handler for PIECE_UPDATE events.

Test the game and see how it runs.

## Step 62: DigitalButton Class

To complete our game we need to add one last thing which is fundamental to any game: Start, Pause and Resume buttons.

For the purpose of this tutorial I've made a custom button class which creates a button that resembles a digital button from a old console game. I will not explain how I've created it because it's outside the scope of this tutorial and it's only basic programming. Here's the button class:

The class is commented so you can guide yourself through it.

## Step 63: Adding the Buttons

Back in the Tetris class add three variables that will reference our buttons.

Next write the addButtons() method in which we instantiate each button, position them, and register event listeners on them.

The method will be executed from within the constructor

Notice that I've removed the _gameCanvas.start(); line once again because this time we'll start the game whenever the start() button is pressed.

And the onStartClick(), onPauseResumeClick() event handlers are:

## Step 64: Final Touch

The last thing we need to do is add an event to notify listeners that the game is over.

First add a new event type in the TetrisGameEvent event by adding a new public static constant.

Then open the GameCanvas class and modify the setUnits() class like so:

The logic here is, whenever a piece has units with negative y coordinates the well (grid) has filled up and so the game has finished.

Then add an event listener for this type of event in the Tetris class:

and create the handler for the listener:

This was the last thing we had to add before wrapping up this tutorial.

Now you are ready to play! Test the game and see how much you can score but don't waste too much time on playing ;)

## Conclusion

This ends the tutorial on how to create one of the most popular old school games: Tetris. Remember that whenever you want to recreate something or build your own game using other concepts you have to document yourself as best as possible.

Start creating piece by piece as this may be the best way to achieve a good result while having a constant overview of the progress.

I hope you enjoyed following tutorial at least as much as I did writing it.


text:
NEWS R Documentation

## NEWS file for the rpart package

### Changes in version 4.1-14

• Changed example data solder to solder.balance. The full version of the data is available in the survival package.

### Changes in version 4.1-10

• Rpart would fail with a formula having ~. - x on the right hand side. A simple bookkeeping error in creating an index.

• Added a section to the vignette on user written functions, which explains why and when one can avoid checking all 2^k splits for a categorical predictor with k levels.

### Changes in version 4.1-0

• The C and R code has been reformatted for legibility.

• The old compatibility function rpconvert() has been removed.

• The cross-validation functions allow for user interrupt at the end of evaluating each split.

• Variable Reliability in data set car90 is corrected to be an ordered factor, as documented.

• Surrogate splits are now considered only if they send two or more cases with non-zero weight each way. For numeric/ordinal variables the restriction to non-zero weights is new: for categorical variables this is a new restriction.

• Surrogate splits which improve only by rounding error over the default split are no longer returned. Where weights and missing values are present, the splits component for some of these was not returned correctly.

### Changes in version 4.0-3

• A fit of class ‘"rpart"’ now contains a component for variable ‘importance’, which is reported by the summary() method.

• The text() method gains a minlength argument, like the labels() method. This adds finer control: the default remains pretty = NULL, minlength = 1L.

• The handling of fits with zero and fractional weights has been corrected: the results may be slightly different (or even substantially different when the proportion of zero weights is large).

• Some memory leaks have been plugged.

• There is a second vignette, ‘longintro.Rnw’, a version of the original Mayo Tecnical Report on rpart.

### Changes in version 4.0-2

• Added dataset car90, a corrected version of the S-PLUS dataset car.all (used with permission).

• This version does not use paste0{} and so works with R 2.14.x.

### Changes in version 4.0-1

• Merged in a set of Splus code changes that had accumulated at Mayo over the course of a decade. The primary one is a change in how indexing is done in the underlying C code, which leads to a major speed increase for large data sets. Essentially, for the lower leaves all our time used to be eaten up by bookkeeping, and this was replaced by a different approach. The primary routine also uses .Call{} so as to be more memory efficient.

• The other major change was an error for asymmetric loss matrices, prompted by a user query. With L=loss asymmetric, the altered priors were computed incorrectly – they were using L' instead of L. Upshot – the tree would not not necessarily choose optimal splits for the given loss matrix. Once chosen, splits were evaluated correctly. The printed “improvement” values are of course the wrong ones as well. It is interesting that for my little test case, with L quite asymmetric, the early splits in the tree are unchanged – a good split still looks good.

• Add the return.all argument to xpred.rpart().

• Added a set of formal tests, i.e., cases with known answers to which we can compare.

• Add a ‘usercode’ vignette, explaining how to add user defined splitting functions.

• The class method now also returns the node probability.

• Add the stagec data set, used in some tests.

• The plot.rpart routine needs to store a value that will be visible to the rpartco routine at a later time. This is now done in an environment in the namespace.

### Changes in version 3.1-55

• Force use of registered symbols in R >= 2.16.0

• Update Polish translations.

• Work on message formats.

### Changes in version 3.1-53

• rpart, rpart.matrix: allow backticks in formulae.

• tests/backtick.R’: regession test

### Changes in version 3.1-52

• src/xval.c’: ensure unused code is not compiled in.

### Changes in version 3.1-51

• Change description of ‘margin’ in ?plot.rpart as suggested by Bill Venables.

format: plain


text:
### More Efficient Commitments from Structured Lattice Assumptions

Carsten Baum, Ivan Damgård, Vadim Lyubashevsky, Sabine Oechsner, and Chris Peikert

##### Abstract

We present a practical construction of an additively homomorphic commitment scheme based on structured lattice assumptions, together with a zero-knowledge proof of opening knowledge. Our scheme is a design improvement over the previous work of Benhamouda et al. in that it is not restricted to being statistically binding. While it is possible to instantiate our scheme to be statistically binding or statistically hiding, it is most efficient when both hiding and binding properties are only computational. This results in approximately a factor of 4 reduction in the size of the proof and a factor of 6 reduction in the size of the commitment over the aforementioned scheme.

Note: Improved version with configurable binding and hiding, better comparison with previous work.

Available format(s)
Publication info
Published elsewhere. 11th Conference on Security and Cryptography for Networks (SCN 2018)
Keywords
Lattice-based cryptographycommitmentszero-knowledge
Contact author(s)
carsten baum @ biu ac il
History
2018-06-21: last of 3 revisions
See all versions
Short URL
https://ia.cr/2016/997

CC BY

BibTeX

@misc{cryptoeprint:2016/997,
author = {Carsten Baum and Ivan Damgård and Vadim Lyubashevsky and Sabine Oechsner and Chris Peikert},
title = {More Efficient Commitments from Structured Lattice Assumptions},
howpublished = {Cryptology ePrint Archive, Paper 2016/997},
year = {2016},
note = {\url{https://eprint.iacr.org/2016/997}},
url = {https://eprint.iacr.org/2016/997}
}

Note: In order to protect the privacy of readers, eprint.iacr.org does not use cookies or embedded third party content.


text:
Beam-Energy Dependence of Directed Flow of $Λ$ , $Λ¯$ , $K±$ , $Ks0$ , and $ϕ$ in $Au+Au$ Collisions
Authors:
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; more »
Award ID(s):
Publication Date:
NSF-PAR ID:
10275508
Journal Name:
Physical Review Letters
Volume:
120
Issue:
6
ISSN:
0031-9007


text:
Experimental study of mutual information in a Maxwell Demon

# Experimental study of mutual information in a Maxwell Demon

## Abstract

We validate experimentally a fluctuation relation known as generalized Jarzynski equality (GJE) governing the work distribution in a feedback-controlled system. The feedback control is performed on a single electron box analogously to the original Szilard engine. In GJE, mutual information is treated on an equal footing with the thermodynamic work. Our results clarify the role of the mutual information in thermodynamics of irreversible processes.

The second law of thermodynamics gives the inevitable upper bound of the available work that we can extract from fuels and heat baths. Information has been recognized as another kind of thermodynamic fuel that can be converted into work with measurement and feedback control. The relation between information and thermodynamics is a topic of long-standing interest in the field of statistical physics, dating back to the thought experiments of “Maxwell demon” (1); (2); (3). Relatively recent progress with universal nonequilibrium equalities applying to irreversible processes, known as fluctuation theorems (4); (5); (6); (7); (8); (9), has brought renewed attention to this problem. In particular, the second law of thermodynamics and nonequilibrium equalities have been generalized to irreversible processes that involve information treatment, such as measurement, feedback control, or information erasure (10); (11); (12); (13); (14); (15); (16); (17); (18); (19); (20); (21); (22); (23). A Maxwell demon is an object that measures the microscopic state of a system, and drives it to extract work or store energy with the aid of the measurement outcome. A crucial element for the fidelity of this operation is mutual information . It characterizes the correlation between the state of the measured thermodynamic system and the measurement outcome stored into the memory of the measurement device, and as such describes the efficiency of the measurement. Several recent experiments have illustrated the relation between information and thermodynamics (24); (25); (26); (27), however none have yet demonstrated the role of mutual information in irreversible feedback processes.

In this Letter, we study experimentally the mutual information in a feedback-controlled device. When the state of a generic thermodynamic system in state is measured with an outcome , the stochastic mutual information (15); (17); (18); (21); (23) is defined as

 I(m,n):=lnP(n|m)−lnP(n), (1)

where is the initial probability of the state being , whereas is the probability that it is under the condition that the measurement outcome is . Jarzynski equality (JE) (5),

 ⟨e−(W−ΔF)/kBT⟩=1, (2)

has been generalized to systems with measurement and feedback control (15); (16) to

 ⟨e−(W−ΔF)/kBT−I⟩=1, (3)

where is the applied work, is the change in free energy, is the temperature of the thermal reservoir, and is the Boltzmann constant. Equation (3) further reproduces the second law of thermodynamics as

 ⟨W⟩−ΔF≥−kBT⟨I⟩, (4)

where mutual information (28) is the expectation value of the stochastic mutual information. As is maximized in the ideal limit of the measurement correlating perfectly with the actual state, i.e. , the magnitude of describes the efficiency of the measurement, providing the upper limit to how much work can be extracted from the system for the given information. We further define

 ηf:=−(⟨W⟩−ΔF)kBT⟨I⟩≤1 (5)

to describe the efficiency of the feedback control. If , the feedback control is perfect and thermodynamically reversible, where all of the mutual information is extracted as work. The condition to achieve the reversible feedback has been discussed in Ref. (20).

We perform the following experiment in a feedback-controlled two-state system. Our device is a single-electron box (29); (30); (31) (SEB), illustrated in Fig. 1 (a), which connects two metallic islands by a junction, permitting electron transport between the two by tunneling. The SEB is placed in a dilution cryostat, and the experiments are performed at mK. The two islands have a mutual capacitance , such that tunneling electrons change the charge of this capacitor by elemetary charge per electron. The charging energy of an SEB is

 E(n,ng)=EC(n−ng)2, (6)

where is the energy required to charge the capacitor with a charge equal to a single electron, and is the charge of the right island, induced by electrons that have tunneled from the left island. Our SEB has eV. Consequently, charge conservation requires that the charge of the right island is . The electron tunneling is controlled by a nearby gate, accumulating a charge equal to to the gate capacitor. The gate voltage is modulated to drive the SEB with being the stochastic state that changes by electron tunneling. The state naturally favours the energy minimum given by Eq. (6), but can also change to a higher energy state due to thermal excitations. The islands of the SEB are few m long, providing a sufficiently small at sub-kelvin temperatures to achieve . This diminishes the probability of higher energy states, practically limiting the SEB to be a two-state system with either or if we operate in the range . While the SEB is modulated by the gate, a nearby single electron transistor (SET) monitors . The measured trajectories of then determine the applied work .

An SEB can be driven and monitored to test thermodynamic relations in a two-state system, and has already been used to verify various fluctuation relations (32); (33). It can also be operated (27) as a Szilard engine (2), ideally extracting of work per feedback cycle. The steps of the operation follow the description introduced in Ref. (20). The initial energies of states and are equal by setting . In this degeneracy point, follows the distribution with equal probabilities . The state is measured with the SET, providing an outcome . As feedback control, the gate is rapidly driven to , where is a pre-determined parameter set to for the present experiment, sign is used for , and sign for . This drive causes the state to have lower energy by than the other state. Finally, is slowly brought back to degeneracy, extracting net work from concurrent thermal excitations of . As this is a closed cycle with equal initial and final , the free energy difference over the whole cycle is zero, , and we only need to consider .

The mutual information is defined for our device as follows. Let be the error rate of the measurement, which is assumed to be equal for measuring and ; we obtain an incorrect outcome with probability for , while for . If , the measurement is error-free and holds. The joint probability is given by . The probability of the detector measurement outcome is then written as , and the probability of conditioned on as . At degeneracy, , implying that the Shannon information written in the memory is . Just after the measurement, and are correlated, which is quantified by the mutual information . By direct insertion to Eq. (1), we obtain stochastic mutual information for , and for . The average of over all possible and produces the mutual information:

 ⟨I⟩=∑nmP(n,m)I(n,m)=ln2+(1−ε)ln(1−ε)+εlnε, (7)

which is the difference between the unconditional Shannon entropy and the conditional one . Since the conditional entropy is not greater than the unconditional one, the mutual information is nonnegative. It is also known that the mutual information is not greater than the Shannon information of the outcome; holds in our setup, where the equality is achieved if the measurement is error-free (i.e., ). The mutual information created by the measurement vanishes after the feedback control; if the feedback control is succesful, the mutual information is converted into useful work. We note that in order to complete the whole feedback cycle, the Shannon information written in the memory must be erased (25).

To introduce the measurement error in the experiment, we change the cut-off frequency of the numerical low-pass filter applied to the detector signal for each measurement. The signal for reading is subject to noise; increasing the cut-off frequency enhances noise in the filtered readout, as shown in Fig. 1(b). This way, the probability to measure the state incorrectly is different for each cut-off frequency. In the analysis, for determining the trajectory of at the time of the measurement and during the foregoing feedback control, we filter the data with a low cut-off frequency (50 Hz), such that signal-to-noise ratio is high, and apply threshold detection as in Fig. 1(c). The tunneling rate at degeneracy, Hz, remains lower than the cut-off frequency of the filter and thus all the relevant transitions of are detected. The error probability is extracted by counting the number of process cycles, where . The feedback protocol is unchanged for each measurement.

Next we focus on feedback control. Ideally, is driven instantly after the measurement to obtain the energy difference between the states such that the initial state is at energy minimum. The work done in the fast drive is determined by the energy difference of Eq. (6), . After the fast response, the consequent slow return back to degeneracy practically starts from thermal equilibrium, as the rate of equilibriation is significantly faster than the rate of the drive. Let be the probability distribution for applied work for an ideal fast feedback response followed by slow return to degeneracy. The slow drive satisifies JE (2), and since the fast feedback response produces a fixed , the distribution satisfies , where is the free energy difference over the drive back to degeneracy, and denotes averaging over . This condition allows us to determine the extracted work as , where is determined by the drive rate and has a value between and .

An error in the measurement produces an incorrect feedback response, making the distribution of work deviate from . However, measurement errors are not the only contribution to incorrect feedback responses. There is a finite delay of few ms between initiating the measurement, and triggering the feedback, which we call . During this delay, the distribution of the states of the SEB evolves naturally, and the probability for the state to be different by the time the feedback takes place is . In the presented experiment, ms. If either the measurement result is incorrect or the state has changed after the measurement, an additional work is paid as illustrated in Fig. 1 (d). These incidences thus follow a work distribution of . On the other hand, if measurement is incorrect and the state changes after the measurement, the distribution again follows , and we obtain

 P(W)=((1−ε)(1−δ)+εδ)P0(W)+(ε(1−δ)+(1−ε)δ)P0(W−ΔE), (8)

matching the measured distributions shown in Figs. 2 (a) - (c). Incidences with correct and incorrect measurement results have different values for , and the resulting distribution modified by mutual information is

 P(¯W≡W+kBTI)=(1−ε)(1−δ)P0(¯W−kBTln(2(1−ε)))+ε(1−δ)P0(¯W−ΔE−kBTln(2ε))+(1−ε)δP0(¯W−ΔE−kBTln(2(1−ε)))+εδP0(¯W−kBTln(2ε)), (9)

which follows the generalized JE (3). The measured distributions shown in Figs. 2 (d) - (f) match Eq. (9). In Fig. 2 (f), the four peaks in the distribution are numbered in the order listed in Eq. (9).

The average extracted work given by the distribution of Eq. (8) is

 −⟨W⟩=rkBTln(21+e−ΔE/kBT)−εFΔE, (10)

where is the probability for incorrect feedback. The extracted work is maximized by setting such that

 ΔE/kBT=ln(r/εF−1), (11)

with which, in the limits of and , Eq. (10) becomes an equality with Eq. (4), as has been demonstrated in (20). For any other , or , the extracted work is smaller in agreement with the second law of thermodynamics. In the ideal limit of , , , and correspondingly , we obtain as is the case for the conventional Szilard engine.

The generalized JE has also another form, which is given by (15)

 ⟨e−(W−ΔF)/kBT⟩=γ. (12)

Here is a parameter that quantifies the efficiency of both the measurement and feedback. While this equality has been verified in a colloidal system (24), the present work is the first test of the generalized JE that connects thermodynamics and the mutual information, Eq. (3). The distribution of Eq. (8) produces

 ⟨e−W/kBT⟩=21+e−ΔE/kBT−2εFtanh(ΔE2kBT). (13)

Figure 3 shows the measured expectation values discussed above as a function of measurement error. As one approaches the low-error regime, the incidences of incorrect feedback response become increasingly rare, and the average extracted work tends to approximately , as shown in Fig. 3 (a). We find that the feedback efficiency given by Eq. (5) remains almost constant for the lowest and the extracted work primarily depends on measurement efficiency. For higher , the feedback protocol should be changed for a better . The protocol could be optimized by correspondingly reducing the applied energy difference in accordance with Eq. (11). Figure 3 (b) shows the results for the test of the generalized JE. We see that Eq. (3) remains valid within measurement errors.

In conclusion, our experiments illustrate the role of mutual information in the performance of a Maxwell demon. We show that our device follows generalized Jarzynski equality when under feedback control similar to that of a Szilard engine. With a fixed feedback protocol, we show that the efficiency of the feedback changes with the measurement efficiency.

This work has been supported in part by Academy of Finland (project no. 139172) and its LTQ (project no. 250280), the National Doctoral Programme in Nanoscience, NGS-NANO (V.F.M.), the European Union Seventh Framework Programme INFERNOS (FP7/2007-2013) under grant agreement no. 308850, and JSPS KAKENHI Grant Nos. 25800217 and 22340114 (T.S.). We thank O.-P. Saira for useful discussions. We acknowledge OMN, Micronova Nanofabrication Centre and the Cryohall of Aalto University for providing the processing facilities and technical support.

### Footnotes

Solid State Physics Laboratory, ETH Zürich, 8093
Zürich, Switzerland

### References

1. J. C. Maxwell, Theory of Heat (Appleton, London, 1871).
2. L. Szilard, Z. Phys. 53, 840 (1929).
3. Maxwell’s Demon, Ed. by H.S. Leff and A.F. Rex, (IOP Publishing, 2003).
4. G. N. Bochkov and I. E. Kuzovlev, Sov. Phys. JETP 45, 125. (1977).
5. C. Jarzynski, Phys. Rev. Lett. 78, 2690 (1997).
6. J. Kurchan, J. Phys. A. Math. Gen. 31, 3719 (1998).
7. G. E. Crooks, Phys. Rev. E 60, 2721 (1999).
8. C. Jarzynski, J. Stat. Phys. 98, 77 (2000).
9. U. Seifert, Phys. Rev. Lett. 95, 040602 (2005).
10. K. Shizume, Phys. Rev. E 52, 3495 (1995).
11. B. Piechocinska, Phys. Rev. A 61, 062314 (2000).
12. R. Kawai, J. M. R. Parrondo, and C. Van den Broeck, Phys. Rev. Lett. 98, 080602 (2007).
13. M. Esposito and C. Van den Broeck, Europhys. Lett. 95, 40004 (2011).
14. H. Touchette and S. Lloyd, Phys. Rev. Lett. 84, 1156 (2000).
15. T. Sagawa and M. Ueda, Phys. Rev. Lett. 104, 090602 (2010).
16. T. Sagawa and M. Ueda, Phys. Rev. E 85, 021104 (2012).
17. T. Sagawa and M. Ueda, Phys. Rev. Lett. 109, 180602 (2012).
18. T. Sagawa and M. Ueda, New. J. Phys. 15, 125012 (2013).
19. J. M. Horowitz and S. Vaikuntanathan, Phys. Rev. E 82, 061120 (2010).
20. J. M. Horowitz and J. M. R. Parrondo, Europhys. Lett. 95, 10005 (2011).
21. D. Abreu and U. Seifert, Phys. Rev. Lett. 108, 030601 (2012).
22. J. M. Horowitz, T. Sagawa, and J. M. R. Parrondo, Phys. Rev. Lett. 111, 010602 (2013).
23. S. Ito and T. Sagawa, Phys. Rev. Lett. 111, 180603 (2013).
24. S. Toyabe, T. Sagawa, M. Ueda, E. Muneyuki, and M. Sano, Nature Physics 6, 988 (2010).
25. A. Bérut, A. Arakelyan, A. Petrosyan, S. Ciliberto, R. Dillenschneider, and E. Lutz, Nature 483, 187 (2012).
26. A. Bérut, A. Petrosyan, and S. Ciliberto, Europhys Lett. 103 60002 (2013).
27. J. V. Koski, V. F. Maisi, J. P. Pekola, and D. V. Averin, arXiv:1402.5907
28. T. M. Cover and J. A. Thomas, Elements of Information Theory. John Wiley and Sons, New York (1991).
29. D. V. Averin and K. K. Likharev, J. Low Temp. Phys. 62, 345 (1986).
30. M. Büttiker, Phys. Rev. B 36, 3548 (1987).
31. P. Lafarge, H. Pothier, E. R. Williams, D. Esteve, C. Urbina, and M. H. Devoret, Z. Phys. B 85, 327 (1991).
32. O.-P. Saira, Y. Yoon, T. Tanttu, M. Möttönen, D. V. Averin, and J. P. Pekola , Phys. Rev. Lett. 109, 180601 (2012).
33. J. V. Koski, T. Sagawa, O-P. Saira, Y. Yoon, A. Kutvonen, P. Solinas, M. Möttönen, T. Ala-Nissila, J. P. Pekola, Nature Physics 9, 644 (2013).
You are adding the first comment!
How to quickly get a good reply:
• Give credit where it’s due by listing out the positive aspects of a paper before getting into which changes should be made.
• Be specific in your critique, and provide supporting evidence with appropriate references to substantiate general statements.
• Your comment should inspire ideas to flow and help the author improves the paper.

The better we are at sharing our knowledge with each other, the faster we move forward.
The feedback must be of minumum 40 characters


text:
## Algebra 1

Write a proportion. $\frac{actual\ fly}{actual\ wingspan}=\frac{model\ fly}{model\ wingspan}\longrightarrow$ substitute given values $\frac{0.2}{0.5}=\frac{27}{w}\longrightarrow$ cross multiply $0.2w=(0.5)(27)\longrightarrow$ multiply $0.2w=13.5\longrightarrow$ divide both sides by 0.2 $0.2w\div0.2=13.5\div0.2\longrightarrow$ divide $w=67.5$


text:
# Substitution in delayed evaluation function [duplicate]

I am trying to do the the following: precomputing an expression and then making a function out of it. It has to be delayed evalution, because some of the parameters are only known when the function is called. A simplified example (the real expression is much more convoluted), is:

expr=x^2+y^2
test[y_]:=FindMinimum[expr,{x,1}]

What we get:

test[3]
FindMinimum::nrlnum: The function value {1.41421,1.41421 y} is not a list of real numbers with dimensions {2} at {x} = {1.}.
FindMinimum[expression, {x, 1}]

What I expected is

test[3]
{9,x->0}

If I remove delayed evaluation, it tries to run FindMinimum immediately and fails. Usually, Evaluate works, but here, it does not. If I both use immediate assignment = and Evaluate, it also tries minimizing before y is ready.

There numerous threads on this SE that almost work, but not for FindMinimum. I tried With, Block and others. If I missed the true answer, please point me to it.

It seems this type of converting expressions into functions should be straight forward. I usually resort to copy-pasting expressions into functions, but this is cumbersome and may lead to many mistakes when expressions are recomputed and the change must be propagated downstream.

• @xzczd Thank you, this indeed helped, I didn't expect this problem to have such an obscure solution. Better remember this one for the future, it happens a lot also with Manipulate, Plot and others. – orion Nov 11 '19 at 14:32

## 1 Answer

(test[y_] := FindMinimum[#, {x, 1}]) &@expr


text:
# Why would my vote totals for the day not be adding up?

The Vox Populi vote meter says I have cast 34 votes, but I'm being barred from further voting today because I've used all 40. Is this a 24 hours versus UTC thing or what is the reason for this behaviour?

This badge is a bit complicated because you get some votes that you can only use in a certain timeframe and only on questions. This is a feature to encourage people to vote on questions and not only on answers. If you only vote on answers for some days you at some point get a message that should discourage that behaviour a bit and that goes something like

You haven't voted on questions in a while. Questions need votes, too!

The daily vote limit is a little arcane. From this post on Meta.SE:

• The exact number of votes available depends on your voting behavior for the day. Concretely, there are three upper limits to respect at the same time to be able to vote.
• 40 post votes per day per user.
• 5 post votes after you got your first "5 votes remaining" warning of the day. If you reach 25 answer votes at time t of the day, given q(t) as the number of question votes cast by time t, the total post votes limit will be no more than 30 + q(t). If you cast less than 25 answer votes, ignore this point.

So, basically, you get 10 votes specifically for questions, but you need to use them early. Once you get close to the limit of 30 unrestricted votes, you can't claim all 10 of the others any more.

No, I don't know why. I suspect it's a limitation in how voting was implemented (the 10 extra votes for questions were a later addition), rather than an intentional design decision.

This behaviour has nothing to do with the UTC time.

Vote on 600 questions and 25% or more of total votes are on questions.

Voting on questions is important and these badges aim to encourage this behaviour.

• Won't let me do anything with votes as far as I can tell, ah I think I must have exceeded the votes before warning bit.
– Ash
Sep 5, 2017 at 19:46
• @Ash You should have been warned about your daily usage. It always starts with "You have 5 votes left for the day". It may take a moment for the box to appear. And the message I cited first only appears when you have been using all your votes on answers for a day or two. A little tip for you badge hunter: there is another badge where you need to have 25% of all your votes on questions. Sep 5, 2017 at 19:52
• Aggravatingly enough I ran out on a Question vate too.
– Ash
Sep 5, 2017 at 19:59
• @Ash As has been explained in the linked post there is a time limit for voting on these questions. So, basically, you get 10 votes specifically for questions, but you need to use them early. Once you get close to the limit of 30 unrestricted votes, you can't claim all 10 of the others any more. Just try it tomorrow and focus on questions first if you want the badge Sep 5, 2017 at 20:04
• Not that worried about the badge really but since I was close anyway...
– Ash
Sep 6, 2017 at 10:18
• @Ash To answer the question you asked in the comment before deleting your question together with my answer: There is a difference between WorldBuilding Meta (which is basically here) and Meta StackExchange, which is a whole SE-site dedicated to governing SE. It's the only Meta site with reputation and it has a lot of interesting information about why things are as they are network wide. There are similar proposals to yours but they don't come up here, because it's a different site. Sep 6, 2017 at 12:23
• Every time I thing I have a handle on the overall structure of this page... Working on putting the salient bit back up as a new question.
– Ash
Sep 6, 2017 at 12:29
• @Ash I don't quite get what you are trying to say. If you have any questions about the site or the network in general feel free to come to the chat. There's not much going on right now. In a few hours most American regular chat users will probably come online. Sep 6, 2017 at 12:32
• While I thank you for the suggestion I can't even manage to post a basic comment on the chat boards so... yeah.
– Ash
Sep 6, 2017 at 13:00
• @Ash Let us continue this discussion in chat. Sep 6, 2017 at 13:04

I suspect that you need to vote more on questions.

See Vote Up privilege in the help center.

You get 30 votes per day to use as you please, plus 10 per day that are reserved specifically for questions. In order to meet the criteria for Vox Populi (vote 40 times in a day) you need to use all of your question-specific votes as well.


text:
# In fission reactions, what causes the parent atom to divide in Different Proportions", for example Uranium divides into Barium and Krypton, why it does not divide into two atoms with same mass (118) or any other atoms other than Ba and Kr ?

Sep 16, 2015

#### Answer:

it can divide into many products as experimentally 42 radioactive elements products have been discovers

#### Explanation:

First of all, the uranium in the fission reaction reaks due to the unstable heavy nucleus which cant hold the proton-proton interactions with
proton-neutron interactions

Secondly, your assumption of uranium breaking into krypton and barium is wrong it can break into any two atoms of similar mass and whose binding energy is near to after iron (since iron has maximum binding energy)


text:
•   Wikis

# Branch (graph theory): Wikis

Note: Many of our articles have direct quotes from sources you can cite, within the Wikipedia article! This article doesn't yet, but we're working on it! See more info or our list of citable articles.

# Encyclopedia

In mathematics, especially mathematical logic and set theory, a branch of a tree T is a map f such that ∀n : f (n) ∈ T.

By a tree on a product set κ1 ×···× κp we mean here a subset of the union of κ1i×···×κp i for all i < ω,

$T\subseteq\bigcup_{i<\omega} \kappa_1^i\times\cdots\times\kappa_p^i ~,$

closed under initial segments, and the set of branches of such a tree is then more explicitly the set

$[T]=\{ (f_1,...,f_p)\mid\forall n\in\omega: (f_1(n),...,f_p(n))\in T\} ~.$

This is a closed set for the usual product topology (see AD plus).


text:
# Partial derivative of a point - is that a vector?

I'm reading a graphics book and this passage is unclear to me (I'm relatively a newbie with linear algebra so I might miss some notions)

Basically the problem here is: I have a transformation and a left-handed coordinate system. This transformation might flip the Z axis thus rendering the left-handed system to a right-handed one. This is bad because we have a vector (the normal vector to a surface) that ends up to be flipped because we calculate it as the cross product between the derivative of the point p we are considering on the surface with respect to the u parametric coordinate of the surface and the derivative of the point p with respect to the v parametric coordinate.

There are some things I don't understand: what does it mean in the formula S(1,1,-1) dp/du ? Is it applying the transformation to the partial derivative or what? And how can I calculate the cross product between two partial derivatives of a point with respect to a coordinate? Is the derivative of a point a vector?

Edit: I figured out that S(1,1,-1) is a simple scale matrix, but I can't understand the passage and where does the S(-1,-1,1) come

The notation $S(1,1,-1)$ is being used to denote a transformation matrix, in this case a scale matrix that (should) be represented by $\begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & -1\end{pmatrix}$.

When multiplying this by the vector $\frac{\partial p}{\partial u}$, you get another vector (i.e. matrix-vector multiplication yields a vector).

They're basically showing that applying the scale transform to each vector $\frac{\partial p}{\partial u}, \frac{\partial p}{\partial v}$, you have to account for it twice when computing your normal!

So if normally your normal vector is

$$n = \frac{\partial p}{\partial u} \times \frac{\partial p}{\partial u},$$

the normal from the scaled vectors is

\begin{align*} n &= \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & -1\end{pmatrix}\frac{\partial p}{\partial u} \times \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & -1\end{pmatrix}\frac{\partial p}{\partial u} \\ &= \begin{pmatrix} -1 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & 0 & 1\end{pmatrix} \frac{\partial p}{\partial u} \times \frac{\partial p}{\partial u} \end{align*}

(Note, we use the cross product property that $(Ax)\times (Ay) = \det A \cdot (A^T)^{-1} x\times y$.)

• Thank you!! The last cross product property totally wasn't known to me, thanks!! – Marco A. Feb 22 '13 at 11:42


text:
# Measurement of the transverse polarization of electrons emitted in neutron decay – nTRV experiment

### Submission summary

 As Contributors: Kazimierz Bodek Preprint link: scipost_202103_00021v2 Date submitted: 2021-06-08 13:27 Submitted by: Bodek, Kazimierz Submitted to: SciPost Physics Proceedings Proceedings issue: DIS2021 Academic field: Physics Specialties: Nuclear Physics - Experiment Approach: Experimental

### Abstract

This paper recalls the main achievements of the nTRV experiment which measured two components of the transverse polarization ($\sigma_{T_{1}}$, $\sigma_{T_{2}}$) of electrons emitted in the $\beta$-decay of polarized, free neutrons and deduced two correlation coefficients, $R$ and $N$, that are sensitive to physics beyond the Standard Model. The value of time-reversal odd coefficient $R$, 0.004$\pm$0.012$\pm$0.005, significantly improved limits on the relative strength of imaginary scalar coupling constant in the weak interaction. The value obtained for the time-reversal even correlation coefficient $N$, 0.067$\pm$0.011$\pm$0.004, agrees with the Standard Model expectation, providing an important sensitivity test of the electron polarimeter. One of the conclusions of this pioneering experiment was that the transverse electron polarization in the neutron $\beta$-decay is worth more systematic exploring by measurements of yet experimentally not attempted correlation coefficients such as $H$, $L$, $S$, $U$ and $V$. This article presents a brief outlook on that questions.

###### Current status:
Editor-in-charge assigned

The article is meant to recall the essential results of the pioneering experiment nTRV as a base for a new project. This is why several description parts taken from original publications were only slightly modified. Figure reproduction rights were checked. The abstract has been rewritten for the most and all the Reviewer's suggestions were addressed both in the text, in figures and in the Bibliography. One more citation was added. One major question concerning the Mott vertex position distribution was answered, too.

### List of changes

1. Abstract got a new formulation.
2. The structure of the article remains unchanged.
3. Appropriate citations have been added in all reproduced Figures.
4. In Figure 1, the Mott scattering vertex was drawn in red.
5. A new citation has been added in order to clarify Figure 15.5.


text:
Math Vectors Vector length (or magnitude)

# Vector length (or magnitude)

For determining the vector length (or magnitude) of a vector $|\vec{v}|$ we use the Pythagorean theorem.

The vector length (or magnitude) of $\vec{v}=\begin{pmatrix}v_1\\v_2\end{pmatrix}$ is:

$|\vec{v}|=\left|\begin{pmatrix}v_1\\v_2\end{pmatrix}\right|=\sqrt{v_1^2+v_2^2}$

In three-dimensional space:

$|\vec{v}|=\left|\begin{pmatrix}v_1\\v_2\\v_3\end{pmatrix}\right|=\sqrt{v_1^2+v_2^2+v_3^2}$
!

### Remember

The vector length (or magnitude) is the length of its arrow and corresponds to the distance between initial point and terminal point.

For determining the length of the arrow (and thus the magnitude of the vector), think of the following triangle. Using the Pythagorean theorem you will find the length of the arrow.

### Examples

Determine the vector length $\vec{a}=\begin{pmatrix}3\\4\end{pmatrix}$

$|\vec{a}|=\sqrt{3^2+4^2}=\sqrt{25}=5$

Determine the vector length $\vec{a}=\begin{pmatrix}2\\3\\6\end{pmatrix}$

$|\vec{a}|=\sqrt{2^2+3^2+6^2}=\sqrt{49}$ $=7$


text:
find the sequence of roots through a given root of a semi-simple Lie algebra - Maple Programming Help

Home : Support : Online Help : Mathematics : DifferentialGeometry : LieAlgebras : DifferentialGeometry/LieAlgebras/RootString

LieAlgebras[RootString] - find the sequence of roots through a given root of a semi-simple Lie algebra

Calling Sequences

RootString(${\mathbf{α}}$, ${\mathbf{β}}$, ${\mathbf{Δ}}$, option)

Parameters

$\mathrm{α}$       - a vector, defining a root vector for a semi-simple Lie algebra

$\mathrm{β}$       - a vector, defining a root vector for a semi-simple Lie algebra

$\mathrm{Δ}$       - a list of vectors, defining a list of root vectors for a semi-simple Lie algebra and containing $\mathrm{α}$ and $\mathrm{β}$

option       - the keyword argument output = "stringlengths"

Description

 • Let $\mathrm{𝔤}$ be a semi-simple Lie algebra, $\mathrm{𝔥}$ a Cartan subalgebra, and the associated set of roots. If then the $\mathrm{α}$-string through $\mathrm{β}$ is the maximal sequence of roots of the form

where $p,q$ are non-negative integers.

 • The calling sequence RootString(${\mathbf{α}}$, ${\mathbf{β}}$, ${\mathbf{Δ}}$) returns the $\mathrm{α}$-string of roots through $\mathrm{β}$. The calling sequence RootString(${\mathbf{α}}$, ${\mathbf{β}}$, ${\mathbf{Δ}}$, output = "stringlengths") returns the list of non-negative integers .

Examples

 > with(DifferentialGeometry): with(LieAlgebras):

Example 1.

We initialize the split real form of the exceptional Lie algebra ${g}_{2}$ and retrieve the root space decomposition and the list of all roots. We then calculate some root strings. The structure equations for ${g}_{2}$ are obtained using SimpleLieAlgebraData.

 > LD := SimpleLieAlgebraData("g(2,Split)", g2);
 ${\mathrm{LD}}{:=}\left[\left[{\mathrm{e1}}{,}{\mathrm{e3}}\right]{=}{2}{}{\mathrm{e3}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e4}}\right]{=}{-}{3}{}{\mathrm{e4}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e5}}\right]{=}{-}{\mathrm{e5}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e6}}\right]{=}{\mathrm{e6}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e7}}\right]{=}{3}{}{\mathrm{e7}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e9}}\right]{=}{-}{2}{}{\mathrm{e9}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e10}}\right]{=}{3}{}{\mathrm{e10}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e11}}\right]{=}{\mathrm{e11}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e12}}\right]{=}{-}{\mathrm{e12}}{,}\left[{\mathrm{e1}}{,}{\mathrm{e13}}\right]{=}{-}{3}{}{\mathrm{e13}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e3}}\right]{=}{-}{\mathrm{e3}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e4}}\right]{=}{2}{}{\mathrm{e4}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e5}}\right]{=}{\mathrm{e5}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e7}}\right]{=}{-}{\mathrm{e7}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e8}}\right]{=}{\mathrm{e8}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e9}}\right]{=}{\mathrm{e9}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e10}}\right]{=}{-}{2}{}{\mathrm{e10}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e11}}\right]{=}{-}{\mathrm{e11}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e13}}\right]{=}{\mathrm{e13}}{,}\left[{\mathrm{e2}}{,}{\mathrm{e14}}\right]{=}{-}{\mathrm{e14}}{,}\left[{\mathrm{e3}}{,}{\mathrm{e4}}\right]{=}{\mathrm{e5}}{,}\left[{\mathrm{e3}}{,}{\mathrm{e5}}\right]{=}{2}{}{\mathrm{e6}}{,}\left[{\mathrm{e3}}{,}{\mathrm{e6}}\right]{=}{-}{3}{}{\mathrm{e7}}{,}\left[{\mathrm{e3}}{,}{\mathrm{e9}}\right]{=}{-}{\mathrm{e1}}{,}\left[{\mathrm{e3}}{,}{\mathrm{e11}}\right]{=}{-}{3}{}{\mathrm{e10}}{,}\left[{\mathrm{e3}}{,}{\mathrm{e12}}\right]{=}{-}{2}{}{\mathrm{e11}}{,}\left[{\mathrm{e3}}{,}{\mathrm{e13}}\right]{=}{\mathrm{e12}}{,}\left[{\mathrm{e4}}{,}{\mathrm{e7}}\right]{=}{-}{\mathrm{e8}}{,}\left[{\mathrm{e4}}{,}{\mathrm{e10}}\right]{=}{-}{\mathrm{e2}}{,}\left[{\mathrm{e4}}{,}{\mathrm{e11}}\right]{=}{\mathrm{e9}}{,}\left[{\mathrm{e4}}{,}{\mathrm{e14}}\right]{=}{\mathrm{e13}}{,}\left[{\mathrm{e5}}{,}{\mathrm{e6}}\right]{=}{-}{3}{}{\mathrm{e8}}{,}\left[{\mathrm{e5}}{,}{\mathrm{e9}}\right]{=}{3}{}{\mathrm{e4}}{,}\left[{\mathrm{e5}}{,}{\mathrm{e10}}\right]{=}{-}{\mathrm{e3}}{,}\left[{\mathrm{e5}}{,}{\mathrm{e11}}\right]{=}{-}{\mathrm{e1}}{-}{3}{}{\mathrm{e2}}{,}\left[{\mathrm{e5}}{,}{\mathrm{e12}}\right]{=}{2}{}{\mathrm{e9}}{,}\left[{\mathrm{e5}}{,}{\mathrm{e14}}\right]{=}{\mathrm{e12}}{,}\left[{\mathrm{e6}}{,}{\mathrm{e9}}\right]{=}{2}{}{\mathrm{e5}}{,}\left[{\mathrm{e6}}{,}{\mathrm{e11}}\right]{=}{-}{2}{}{\mathrm{e3}}{,}\left[{\mathrm{e6}}{,}{\mathrm{e12}}\right]{=}{-}{2}{}{\mathrm{e1}}{-}{3}{}{\mathrm{e2}}{,}\left[{\mathrm{e6}}{,}{\mathrm{e13}}\right]{=}{-}{\mathrm{e9}}{,}\left[{\mathrm{e6}}{,}{\mathrm{e14}}\right]{=}{-}{\mathrm{e11}}{,}\left[{\mathrm{e7}}{,}{\mathrm{e9}}\right]{=}{-}{\mathrm{e6}}{,}\left[{\mathrm{e7}}{,}{\mathrm{e12}}\right]{=}{\mathrm{e3}}{,}\left[{\mathrm{e7}}{,}{\mathrm{e13}}\right]{=}{-}{\mathrm{e1}}{-}{\mathrm{e2}}{,}\left[{\mathrm{e7}}{,}{\mathrm{e14}}\right]{=}{-}{\mathrm{e10}}{,}\left[{\mathrm{e8}}{,}{\mathrm{e10}}\right]{=}{-}{\mathrm{e7}}{,}\left[{\mathrm{e8}}{,}{\mathrm{e11}}\right]{=}{-}{\mathrm{e6}}{,}\left[{\mathrm{e8}}{,}{\mathrm{e12}}\right]{=}{\mathrm{e5}}{,}\left[{\mathrm{e8}}{,}{\mathrm{e13}}\right]{=}{\mathrm{e4}}{,}\left[{\mathrm{e8}}{,}{\mathrm{e14}}\right]{=}{-}{\mathrm{e1}}{-}{2}{}{\mathrm{e2}}{,}\left[{\mathrm{e9}}{,}{\mathrm{e10}}\right]{=}{\mathrm{e11}}{,}\left[{\mathrm{e9}}{,}{\mathrm{e11}}\right]{=}{2}{}{\mathrm{e12}}{,}\left[{\mathrm{e9}}{,}{\mathrm{e12}}\right]{=}{-}{3}{}{\mathrm{e13}}{,}\left[{\mathrm{e10}}{,}{\mathrm{e13}}\right]{=}{-}{\mathrm{e14}}{,}\left[{\mathrm{e11}}{,}{\mathrm{e12}}\right]{=}{-}{3}{}{\mathrm{e14}}\right]$ (2.1)

Initialize the Lie algebra with DGsetup.

 > DGsetup(LD);
 ${\mathrm{Lie algebra: g2}}$ (2.2)

The root space decomposition is retrieved, without calculation, using SimpleLieAlgebraProperties

 > P := SimpleLieAlgebraProperties(g2):

Here is the root space decomposition and the list of all positive roots.

 > RSD := eval(P["RootSpaceDecomposition"]);
 ${\mathrm{RSD}}{:=}{\mathrm{table}}\left(\left[\left[{-}{1}{,}{1}\right]{=}{\mathrm{e5}}{,}\left[{-}{3}{,}{2}\right]{=}{\mathrm{e4}}{,}\left[{0}{,}{1}\right]{=}{\mathrm{e8}}{,}\left[{3}{,}{-}{1}\right]{=}{\mathrm{e7}}{,}\left[{2}{,}{-}{1}\right]{=}{\mathrm{e3}}{,}\left[{1}{,}{0}\right]{=}{\mathrm{e6}}{,}\left[{0}{,}{-}{1}\right]{=}{\mathrm{e14}}{,}\left[{-}{2}{,}{1}\right]{=}{\mathrm{e9}}{,}\left[{-}{3}{,}{1}\right]{=}{\mathrm{e13}}{,}\left[{3}{,}{-}{2}\right]{=}{\mathrm{e10}}{,}\left[{-}{1}{,}{0}\right]{=}{\mathrm{e12}}{,}\left[{1}{,}{-}{1}\right]{=}{\mathrm{e11}}\right]\right)$ (2.3)
 g2 > Delta := LieAlgebraRoots(RSD);
 ${\mathrm{Δ}}{:=}\left[\left[\begin{array}{r}{-}{1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{-}{3}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{3}\\ {-}{1}\end{array}\right]{,}\left[\begin{array}{r}{2}\\ {-}{1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {-}{1}\end{array}\right]{,}\left[\begin{array}{r}{-}{2}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{-}{3}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{3}\\ {-}{2}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {-}{1}\end{array}\right]\right]$ (2.4)

Define two roots and $\mathrm{β}$.

 g2 > alpha := <2, -1>;
 ${\mathrm{α}}{:=}\left[\begin{array}{r}{2}\\ {-}{1}\end{array}\right]$ (2.5)
 g2 > beta := <-3, 2>;
 ${\mathrm{β}}{:=}\left[\begin{array}{r}{-}{3}\\ {2}\end{array}\right]$ (2.6)

Calculate the $\mathrm{α}$-string through $\mathrm{β}.$

 g2 > RootString(alpha, beta, Delta);
 $\left[\left[\begin{array}{r}{-}{3}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{3}\\ {-}{1}\end{array}\right]\right]$ (2.7)

With the optional keyword argument output = "stringlengths", we obtain the lengths of the $\mathrm{α}$-string through in the negative and positive directions.

 g2 > RootString(alpha, beta, Delta, output = "stringlengths");
 $\left[{0}{,}{3}\right]$ (2.8)

Thus the $\mathrm{α}$-string through $\mathrm{β}$ in (2.7) is given explicitly by.

 g2 > [beta, beta + alpha, beta +2*alpha, beta + 3*alpha];
 $\left[\left[\begin{array}{r}{-}{3}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{3}\\ {-}{1}\end{array}\right]\right]$ (2.9)

Example 2.

Here is another example of a root string for the exceptional Lie algebra ${g}_{2}$.

 g2 > alpha := <2, -1>;
 ${\mathrm{α}}{:=}\left[\begin{array}{r}{2}\\ {-}{1}\end{array}\right]$ (2.10)
 g2 > beta := <1, 0>;
 ${\mathrm{β}}{:=}\left[\begin{array}{r}{1}\\ {0}\end{array}\right]$ (2.11)

The root $\mathrm{α}$-string through $\mathrm{β}$ is now

 g2 > RootString(alpha, beta, Delta);
 $\left[\left[\begin{array}{r}{-}{3}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{3}\\ {-}{1}\end{array}\right]\right]$ (2.12)

and the string lengths are

 g2 > RootString(alpha, beta, Delta, output = "stringlengths");
 $\left[{2}{,}{1}\right]$ (2.13)

Thus, the root string (2.12) is explicitly given by

 g2 > [beta -2*alpha, beta - alpha, beta, beta + alpha];
 $\left[\left[\begin{array}{r}{-}{3}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{3}\\ {-}{1}\end{array}\right]\right]$ (2.14)

Example 3.

Root strings can also be calculated for abstract roots systems, that is, a set of vectors satisfying the standard axioms of a root system and not explicitly defined from the root space decomposition of a semi-simple Lie algebra. The positive roots of an abstract root systems can be calculated with the PositiveRoots command.

 g2 > AbstractRoots := PositiveRoots("B", 3);
 ${\mathrm{AbstractRoots}}{:=}\left[\left[\begin{array}{r}{1}\\ {0}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {0}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {1}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {2}\\ {2}\end{array}\right]\right]$ (2.15)
 g2 > Delta := [seq(-v, v = AbstractRoots), seq(v, v = AbstractRoots)];
 ${\mathrm{Δ}}{:=}\left[\left[\begin{array}{r}{-}{1}\\ {0}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {-}{1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {0}\\ {-}{1}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {-}{1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {-}{1}\\ {-}{1}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {-}{1}\\ {-}{1}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {-}{1}\\ {-}{2}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {-}{1}\\ {-}{2}\end{array}\right]{,}\left[\begin{array}{r}{-}{1}\\ {-}{2}\\ {-}{2}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {0}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {0}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {1}\\ {2}\end{array}\right]{,}\left[\begin{array}{r}{1}\\ {2}\\ {2}\end{array}\right]\right]$ (2.16)

Here are are 2 roots and their root string.

 g2 > alpha := Delta[12];
 ${\mathrm{α}}{:=}\left[\begin{array}{r}{0}\\ {0}\\ {1}\end{array}\right]$ (2.17)
 g2 > beta := Delta[11];
 ${\mathrm{β}}{:=}\left[\begin{array}{r}{0}\\ {1}\\ {0}\end{array}\right]$ (2.18)
 g2 > RootString(alpha, beta, Delta);
 $\left[\left[\begin{array}{r}{0}\\ {1}\\ {0}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\\ {1}\end{array}\right]{,}\left[\begin{array}{r}{0}\\ {1}\\ {2}\end{array}\right]\right]$ (2.19)