### Using PATH and CONFIG Macros for File Operations Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md Demonstrates how to use the `PATH` and `CONFIG` macros to get the model configuration directory and name, respectively. These are typically used with functions like `sprint` to construct file paths for saving data. ```LSD/C++ char[500] filename; // allocate space for the file name character array (string) sprint( filename, "%s/%s", PATH, CONFIG ); // concatenate with the "/" between SAV_LAT( filename ); ``` -------------------------------- ### Initializing HOOKs in LSD (Partial) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows the beginning of code within an EQUATION to handle the initialization of dynamic hooks. It checks if COUNT_HOOK is zero (indicating hooks haven't been created or assigned yet) to perform initial setup, ensuring hooks are valid before being used to access object data. ```LSD EQUATION( "IdUsed" ) /* Id of the product used by the consumer. Look whether the product breaks down or not. In the first case choose a new product. Dynamic HOOK( 0 ) is the consumers' free pointer containing the firm used by the consumer. */ if ( COUNT_HOOK == 0 ) ``` -------------------------------- ### Adding Object Instance using ADDOBJ_EX in LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates how to use the ADDOBJ_EX macro to add a new object instance ('Firm') that is a clone of an existing one. It first searches for firms, finds the one with the maximum 'A' value, and then uses that firm as the example for creating a new instance. ```LSD cur = SEARCH( "Firm" ); v[0] = MAXS( cur, "A" ); cur = SEARCH_CND( "A", v[0] ); cur = ADDOBJ_EX( "Firm", cur ); ``` -------------------------------- ### Interactive Firm Removal Example using LSD Macros Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This example code snippet demonstrates how to iterate through 'Firm' objects, check if their 'MarketShare' is below a minimum threshold, and then use the 'INTERACTS' macro to prompt the user whether to delete the firm. The user's input determines if the 'DELETE' macro is called to remove the current firm ('cur') from the model. ```LSD/C++ Macro v[1] = V( "MinMarketShare" ); //minimum m.s. below which a firm should be removed CYCLE_SAFE( cur, "Firm" ) { //Cycle through each firm, allowing for the removal of the pointer v[0] = VS( cur, "MarketShare" ); //read the market share if ( v[0] < v[1] ) v[5] = INTERACTS( cur, "Remove this firm? (1=yes; 2=no)", v[4] ); if ( v[5] == 1 ) { //remove if the answer was 1 DELETE( cur ); v[3]++; } } ``` -------------------------------- ### Correct Hook Pointer Assignment Example in LSD CYCLE Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates the recommended way to assign sequential hook pointers within a `CYCLE` loop. The variable `i` is used as the argument to `WRITE_HOOK` and then incremented separately, ensuring it is incremented only once per iteration. ```LSD/C++ ADDHOOK( COUNT( "Firm" ) ); i = 0; CYCLE( cur, "Firm" ) { WRITE_HOOK( cur, i ); // read the number of hook pointers assigned to object ++i; } ``` -------------------------------- ### Defining LSD Variable Equation Using Macros (LSD/C++) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This example demonstrates how to define an equation for a variable named "PROF" using LSD Macros to fetch values of other variables or parameters. It uses `V("Label")` to get the current value of a variable/parameter and `VL("Label", lag)` to get a lagged value. The final calculation is performed directly within the `RESULT` macro. ```LSD Macro Language EQUATION( "PROF" ) /*************************** The equation computes the profit rate: PROF(t) = P(t) * A(t-1) - C - RIM – RIN * Inn profits per unit of capital are equal current price times lagged productivity minus the cost for research (innovative firms spend for both type of research) and fixed costs. ***************************/ RESULT( V("Price") * VL("A", 1) - V("C") - V("RIM") - V("RIN") * V("Inn") ) ``` -------------------------------- ### Declaring Global Object Pointer in LSD/C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md Demonstrates how to declare a global pointer to an LSD Object instance using standard C++ syntax before the MODELBEGIN keyword. It also shows an example of an EQUATION named "Init" which is computed once to assign the global pointer market by searching for an Object instance named "Market" using the SEARCH Macro. The PARAM Macro prevents re-computation. ```C++/LSD #include "../src/fun_head_fast.h" object *market; MODELBEGIN EQUATION( "Init" ) /* Technical initialization function. It is computed only once and then it is transformed in a parameter and never computed again. Sets the global pointer 'market' pointing to the Object Market, so to speed up the access to this object */ market = SEARCH( "Market" ); //assign the C++ object pointer "market" to point to the LSD Object Market PARAM; //optional; transform "Init" in a parameter so to not compute again this equation RESULT( 1 ) ``` -------------------------------- ### Sorting Descendant Objects using SORT in LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This example shows how to use the SORT macro within an object's equation to sort its descendant object instances labeled 'Firm'. The sorting is based on the decreasing values of their 'Q' variable. ```LSD SORT( "Firm", "Q", DOWN ); ``` -------------------------------- ### Defining Equation with Intermediate Variables - LSD C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet defines the same equation for 'Q' as the previous example but uses intermediate variables (v[0], v[1]) to store the results of VL() and V() macros before computing the final product. This approach allows for easier debugging. ```C++ EQUATION( "Q" ) /* Compute the quantity Q as the product of lagged capital K and current productivity A */ v[0] = VL( "K", 1 ); v[1] = V( "A" ); RESULT( v[0] * v[1] ) ``` -------------------------------- ### Using SEARCH and VS Macros in LSD Macro Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates how to use the SEARCH macro to find an object instance (named 'Market') starting the search from a specific relative position (GRANDPARENT of the current object). It then uses the VS macro to retrieve the value of a variable ('TotalSales') from the pointer ('cur') returned by SEARCH. ```LSD Macro cur = SEARCH( GRANDPARENT, "Market" ); v[1] = VS( cur, "TotalSales" ); ``` -------------------------------- ### Defining Basic LSD Variable Equation (LSD/C++) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows the basic structure for defining an equation for an LSD Variable or Function named "Lab". The `EQUATION("Label")` macro starts the code block, and the `RESULT(value)` macro specifies the value that the variable/function will be assigned at the current time step. Comments can be included within the block. ```LSD Macro Language EQUATION( "Lab" ) /* Normally here should be place a comment, specifying what the equation does */ RESULT( 3 ) // This Equation assigns always the value 3 to any copy of variable Lab ``` -------------------------------- ### Accessing and Modifying Data Extension Members - C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet from a Firm-level Variable Equation shows how to access (V_EXT), execute methods (EXEC_EXT), write (WRITE_EXT), and get a pointer (P_EXT) to the data extension's members. It demonstrates checking a condition based on 'num_params', clearing and repopulating the 'tech_params' vector using C++ methods via EXEC_EXT, updating 'num_params', and passing a pointer to the vector (via P_EXT) to an external function. ```C++ // refill the Firm-specific vector if it has less than 3 parameters if ( V_EXT( ext_firm, num_params ) < 3 ) // get firm’s num_params and compare { EXEC_EXT( ext_firm, tech_params, clear ); // clear the vector EXEC_EXT( ext_firm, tech_params, push_back, T ); // writes current time to 1st position // write 2 random integers between 1 and 100 in the 2nd and the 3rd positions EXEC_EXT( ext_firm, tech_params, push_back, ( int ) uniform_int( 1, 100 ) ); EXEC_EXT( ext_firm, tech_params, push_back, ( int ) uniform_int( 1, 100 ) ); WRITE_EXT( ext_firm, num_params, 3 ); // set Firm’s num_params to 3 } // call an external library function requiring a pointer to a integer vector v[1] = eval_prod( P_EXT( ext_firm ) ); // evaluate Firm productivity based on vector ``` -------------------------------- ### Incorrect Hook Pointer Assignment Example in LSD CYCLE Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows an incorrect way to assign sequential hook pointers within a `CYCLE` loop. The post-increment operator `i++` may cause the variable `i` to be incremented multiple times within a single macro call, leading to incorrect assignments and potential crashes. ```LSD/C++ ADDHOOK( COUNT( "Firm" ) ); i = 0; CYCLE( cur, "Firm" ) WRITE_HOOK( cur, i++ ); // read the number of hook pointers assigned to object ``` -------------------------------- ### Accessing Variable (Default LSD V Macro) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md Illustrates the default usage of the V (Variable) Macro to access the value of a Variable named "Price". When no specific Object instance is provided, the search starts from the current instance (THIS) and traverses the model structure, which might be less efficient than using a direct pointer if the target is distant. ```C++/LSD v[0] = V( "Price" ); ``` -------------------------------- ### Compound Assignment Operators in C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These C++ snippets show compound assignment operators, which provide a shorthand for performing an arithmetic operation and assigning the result back to the same variable. For example, `a += 32;` is equivalent to `a = a + 32;`. These can be used for addition, subtraction, multiplication, and division. ```C++ a += 32; ``` ```C++ a /= 32; ``` ```C++ a *= 32; ``` ```C++ a -= 32; ``` -------------------------------- ### Getting Pointer to LSD C++ Extension with P_EXT C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The P_EXT and P_EXTS macros return a C++ pointer to the data extension of a specified type within an LSD object. P_EXT returns a pointer for the current object (THIS), while P_EXTS returns one for 'obj'. If the extension does not exist on the target object, these macros return NULL. This is useful for checking if an extension exists before attempting to access it. ```C++ P_EXT( class ) ``` ```C++ P_EXTS( obj, class ) ``` -------------------------------- ### Using the CALLER Macro to Get Calling Object Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The `CALLER` macro returns a pointer to the object that requested the computation of the current variable or function. It is NULL if the computation was triggered by LSD itself because the variable wasn't used by another equation. It points to the same object as the predefined `c` pointer. ```LSD/C++ CALLER ``` -------------------------------- ### Accessing Variable Price via Parent - LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows how to efficiently access a variable "Price" located in the parent object (PARENT) using the VS() macro. This avoids the potentially slow default search behavior of V() by explicitly providing the target object instance (PARENT) to start the search from. Requires PARENT to point to a valid object containing "Price". ```LSD v[0] = VS( PARENT, "Price" ); ``` -------------------------------- ### Searching Objects by Variable Value (TSEARCH_CND) - C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These macros perform a turbo search within an object chain (starting from the current or specified object) for the first instance containing a variable named "Lab" with the specified numeric 'value'. They require the chain to be pre-sorted and the search initialized with INIT_TSEARCH_CND. Returns a pointer to the found object or NULL. ```C++ TSEARCH_CND( "Lab", value ) TSEARCH_CNDS( obj, "Lab", value ) ``` -------------------------------- ### Accessing Variable Price - LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates accessing a variable named "Price" using the V() macro in LSD. By default, V() searches the object hierarchy downwards from the current object (THIS) and then upwards if not found. In the example context, this means searching many Worker instances before finding Price in the Market parent object, which can be inefficient. ```LSD v[0] = V( "Price" ); ``` -------------------------------- ### Initializing Data Extensions in LSD Equation - C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This LSD Equation "Init" demonstrates how to allocate the 'ext_firm' data extension for all "Firm" objects using ADDEXTS within a CYCLE. It then uses WRITE_EXTS to initialize the 'num_params' member of the extension for each firm. The PARAMETER macro ensures this code runs only once at the beginning. ```C++ EQUATION( "Init" ) /* Initialization code, run just once in the beginning of the simulation */ CYCLE( cur, "Firm" ) { ADDEXTS( cur, ext_firm ); // adds the extension to each Firm in the CYCLE WRITE_EXTS( cur, ext_firm, num_params, 0 ); // set each Firm vector size to 0 } PARAMETER; // turns the variable "Init" into a parameter (run only once) RESULT( 1 ) ``` -------------------------------- ### Initializing and Populating Eigen MatrixXd in LSD CYCLE Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates how to add, resize, and populate an Eigen MatrixXd extension for agents within an LSD CYCLE block. It uses `ADDEXTS` to add the extension, `DO_EXTS` to call the resize method, and `EXTS` to access and populate matrix elements. ```LSD/C++ CYCLE( cur, "Firm" ) { ADDEXTS( cur, MatrixXd ); // adds an empty matrix extension to each Firm DO_EXTS( cur, MatrixXd, resize, 2, 2 ); // resize the matrix to 2x2 EXTS( cur, MatrixXd ) << 0, 0, 0, 0; // set each matrix element to 0 EXTS( cur, MatrixXd ) ( 0, 0 ) = 1; // set element a11 to 1 EXTS( cur, MatrixXd ) ( 0, 1 ) = 2; // set element a12 to 2 EXTS( cur, MatrixXd ) ( 1, 0 ) = 3; // set element a21 to 3 EXTS( cur, MatrixXd ) ( 1, 1 ) = 4; // set element a22 to 4 } ``` -------------------------------- ### Creating & Initializing New Object Instance - LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates creating a new object instance of type "Firm" using the ADDOBJ() macro and assigning its temporary address to the cur pointer. It then uses the WRITELS() macro with the cur pointer to write the value 0 into the variable "K" of that newly created "Firm" instance at time t. This is a common pattern for initializing newly added objects. ```LSD cur = ADDOBJ( "Firm" );\nWRITELS( cur, "K", 0, t ); ``` -------------------------------- ### Implementing Consumer Product Choice Logic with Hooks - LSD Macro Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This code snippet demonstrates a common pattern in LSD models for simulating a consumer choosing a product, checking if it breaks, and potentially choosing a new one, using dynamic hooks to remember the previously chosen product. It handles the initial choice when the hook is not yet set and subsequent choices where the hook is already initialized. ```LSD Macro { // executed the very first time step, when hook was not created v[0] = VL( "IdUsed", 1 ); // product used by the consumer cur = SEARCH_CND( "IdFirm", v[0] ); // find the object with IdFirm equal to my IdUsed v[2] = VS( cur, "BD" ); // read the probability of breaking the product ADDHOOK( 1 ); // create the hook pointer WRITE_HOOK( 0, cur ); // initialize the hook pointer } else v[2] = VS( HOOK( 0 ), "BD" ); // read the probability of breaking the product if ( RND < v[2] ) { // product broken cur1 = RNDDRAW_FAIRS( PARENT, "Firm" ); // choose a new firm from the father of the former firm WRITE_HOOK( 0, cur1 ); // update the hook v[1] = VS( cur1, "IdFirm" ); } else v[1] = v[0]; // product not broken, used the same product as before RESULT( v[1] ) ``` -------------------------------- ### Declaring Initialization Equation for Eigen (LSD) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows the beginning of an LSD Equation block named 'Init'. This is the standard structure for defining code that runs at specific simulation times. The context indicates this particular equation is where code using the Eigen library for matrix initialization or manipulation would be placed. ```LSD (Custom Syntax) EQUATION( "Init" ) /* ``` -------------------------------- ### Defining Sample Data Extension Class - C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This C++ code defines a simple class 'ext_firm' intended to be used as a data extension in LSD. It contains an integer 'num_params' and a standard library vector of integers 'tech_params'. This definition must be included before the MODELBEGIN directive. ```C++ #include "fun_head_fast.h" #include // include the vector container in STL class ext_firm // this is simply a declaration, nothing is allocated here { public: int num_params; vector < int > tech_params; // define an initially zero-length vector }; MODELBEGIN ... ``` -------------------------------- ### Adding New Object Instance and Setting Parameter (LSD Macro) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows how to create a new object instance using the ADDOBJ macro, which adds a "Firm" instance to the current object. It then uses the WRITES macro to set the value of the "DateBirth" parameter within the newly created object (cur) to the current simulation time T. ```LSD Macro cur = ADDOBJ( "Firm" ); WRITES( cur, "DateBirth", T ); ``` -------------------------------- ### Enabling Eigen Library Usage in LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This preprocessor directive must be placed before the `#include fun_head_fast.h` line in the equation file to enable the usage of the Eigen math library functions and types within the LSD model. ```LSD/C++ #define EIGENLIB ``` -------------------------------- ### Initializing Turbo Search (INIT_TSEARCH_CND) - C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These macros initialize the internal data structure required by the TSEARCH_CND macros for a specified variable ("Lab"). Initialization must be repeated whenever objects are added/deleted or the variable values change within a brotherhood. Returns the number of instances initialized. ```C++ INIT_TSEARCH_CND( "Lab" ) INIT_TSEARCH_CNDS( obj, "Lab" ) ``` -------------------------------- ### Using For Loop for Iteration and Array Indexing in C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet illustrates the structure and execution of a `for` loop in C++. It initializes a loop counter `i` to -2, continues as long as `i` is less than 3, and increments `i` after each iteration. Inside the loop, it demonstrates accessing and assigning values to an array `v` using the loop counter `i` as the index. ```C++ for ( i = -2; i < 3; i++ ) { /* in the execution of these lines i assumes values -2, -1, 0, 1 and 2 */ v[i] = i; } // here i equals 3, because it was the condition to exit the cycle ``` -------------------------------- ### Using SEARCH_INST Macro within CYCLE in LSD Macro Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet iterates through all instances of the 'Firm' object using the CYCLE macro, assigning the current instance pointer to `cur`. Inside the loop, it retrieves the 'IdFirm' parameter using VS and the instance number of the current object using SEARCH_INST. It then compares these two values and logs a message using LOG if they do not match. ```LSD Macro CYCLE( cur, "Firm" ) { v[1] = VS( cur, "IdFirm" ); v[2] = SEARCH_INST( cur ); if ( v[1] != v[2] ) LOG( "\n IdFirm=%g different from instance number=%g", v[1], v[2] ); } ``` -------------------------------- ### Controlling LSD Debugger with Macros Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These macros control when the LSD Debugger is enabled and when logging to `log.txt` occurs. `DEBUG_START` enables from the current point, `DEBUG_STOP` disables, and `_AT(step)` versions control the start/stop at a specific simulation step. ```LSD/C++ DEBUG_START DEBUG_START_AT( step ) DEBUG_STOP DEBUG_STOP_AT( step ) ``` -------------------------------- ### Defining Minimum LSD Equation File Structure (C++) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These lines represent the absolute minimum required structure for an LSD equation file. They include the necessary header file, markers for the main model block (`MODELBEGIN`, `MODELEND`), and a function to close the simulation. Code defining equations for variables and functions is placed between `MODELBEGIN` and `MODELEND`. ```C++ #include "../src/fun_head_fast.h" MODELBEGIN MODELEND void close_sim( ) { } ``` -------------------------------- ### C++ Multiline Comment Syntax Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates the syntax for creating multiline comments in C++. Text between /* and */ is ignored by the compiler, allowing for descriptive blocks of text to explain code sections. ```C++ /* This is a multiline comment, continuing until a sequence "star slash" is encountered */ ``` -------------------------------- ### Accessing Related Object Data via SEARCH_CND in LSD (Original) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This is the original version of an equation that determines which 'Product' ('Firm') a 'Consumer' object is using. It retrieves the product ID, searches for the corresponding 'Firm' object using SEARCH_CND, reads its 'BD' (breakdown probability) variable, and decides whether to keep the current product or draw a new one. ```LSD EQUATION( "IdUsed" ) /* Id of the product used by the consumer. Look whether the product breaks down or not. In the first case choose a new product. */ v[0] = VL( "IdUsed", 1 ); // product used by the consumer cur = SEARCH_CND( "IdFirm", v[0] ); // find the object with IdFirm equal to my IdUsed v[2] = VS( cur, "BD" ); // read the probability of breaking the product if ( RND < v[2] ) { // product broken cur1 = RNDDRAW_FAIRS( PARENT, "Firm" ); // choose a new firm from the father of the former firm v[1] = VS( cur1, "IdFirm" ); } else v[1] = v[0]; // product not broken, used the same product as before RESULT( v[1] ) ``` -------------------------------- ### Accessing Related Object Data via HOOK in LSD (Optimized) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This is an optimized version of the previous equation using a dynamic HOOK. Instead of searching for the 'Firm' object every time, it reads the 'BD' probability directly from the 'Firm' object stored in dynamic HOOK(0). If a new firm is chosen, the hook is updated using WRITE_HOOK. ```LSD EQUATION( "IdUsed" ) /* Id of the product used by the consumer. Look whether the product breaks down or not. In the first case choose a new product. Dynamic HOOK( 0 ) is the consumers' pointer containing the firm used by the consumer. */ v[2] = VS( HOOK( 0 ), "BD" ); // read the probability of breaking the product using hook if ( RND < v[2] ) { // product broken cur1 = RNDDRAW_FAIRS( PARENT, "Firm" ); // choose a new firm from the father of the former firm WRITE_HOOK( 0, cur1 ); v[1] = VS( cur1, "IdFirm" ); } else v[1] = v[0]; // product not broken, used the same product as before RESULT( v[1] ) ``` -------------------------------- ### Basic Assignment and Arithmetic in C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These C++ snippets demonstrate fundamental assignment and arithmetic operations used in LSD variable equations. Values can be assigned directly, calculated using standard operators (+, -, *, /) respecting parentheses priority, or updated based on their current value. Assignments must end with a semicolon. ```C++ a = 4.3; ``` ```C++ a = b + 3 – d / (e + g) * (h + i); ``` ```C++ a = a + 32; ``` -------------------------------- ### Adding C++ Data Extension (ADDEXT) - C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These macros add a C++ data extension of the specified 'class' type to the current (THIS) or a specified 'obj' Object. ADDEXT_INIT allows passing initializer parameters to the C++ class constructor. Each object can have only one extension; adding a new one replaces the old one of the same class type. Adding a different class requires explicit deletion first. ```C++ ADDEXT( class ) ADDEXTS( obj, class ) ADDEXT_INIT( class, initializer ) ADDEXT_INITS( obj, class, initializer ) ``` -------------------------------- ### Defining Equation with Direct Calculation - LSD C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet defines an equation for the variable 'Q'. It calculates Q as the product of the lagged variable 'K' (one period lag) and the current variable 'A' using the VL() and V() macros, and assigns the result using the RESULT() macro. ```C++ EQUATION( "Q" ) /* Compute the quantity Q as the product of lagged capital K and current productivity A */ RESULT( VL( "K", 1 ) * V( "A" ) ) ``` -------------------------------- ### Directly Accessing LSD C++ Extension with EXT C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The EXT and EXTS macros provide direct access to the C++ data extension of a specified type within an LSD object. EXT accesses the extension on the current object (THIS), while EXTS accesses it on the object pointed to by 'obj'. It is critical that the data extension exists prior to using these macros, otherwise a runtime crash will occur. ```C++ EXT( class ) ``` ```C++ EXTS( obj, class ) ``` -------------------------------- ### Declaring a Parameter in LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The `PARAMETER` keyword is used to declare a variable as a model parameter. Parameters are typically initialized once at the beginning of the simulation and are not expected to change during the simulation run. ```LSD/C++ PARAMETER; ``` -------------------------------- ### Defining Equation with RNDDRAW Macro in LSD Macro Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This code defines an equation 'DrawAFirm'. It first iterates through all 'Firm' instances, calculates a probability based on the square of their 'ms' variable, and writes it to a 'Prob' parameter using CYCLE, V, and WRITES. It then uses the RNDDRAW macro to randomly select one 'Firm' instance based on the 'Prob' values. Finally, it returns the 'IdFirm' parameter of the selected firm using VS and RESULT. ```LSD Macro EQUATION( "DrawAFirm" ) /*************************** Return the Id of a Firm chosen randomly with probability equal to the square of the market shares. ***************************/ CYCLE( cur, "Firm" ) { v[0] = V( "ms" ); WRITES( cur, "Prob", v[0] * v[0] ); } cur = RNDDRAW( "Firm", "Prob" ); RESULT( VS( cur, "IdFirm" ) ) ``` -------------------------------- ### Disabling Default Pointer Initialization in LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md Defining `NO_POINTER_INIT` disables LSD's default initialization of temporary pointers (like `cur`, `curl`) to `NULL`. This reduces simulation overhead but requires the modeler to ensure pointers are valid before use to prevent crashes. ```LSD/C++ #define NO_POINTER_INIT ``` -------------------------------- ### C++ Single-Line Comment Syntax Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows the syntax for creating single-line comments in C++. Any text following // on a line is treated as a comment and ignored by the compiler. ```C++ // this is a single line comment, ``` ```C++ // terminating at the end of the line ``` -------------------------------- ### Implementing Nested If/Else Conditional Logic in C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates how to use nested `if` and `else` statements in C++ to evaluate multiple conditions. It shows combining conditions using the logical AND (`&&`) and negation (`!`) operators to distinguish between several possible states based on the values of variables `a`, `b`, `c`, and `d`. ```C++ if (a == b && !(c == d)) { /* "a" equals "b" and "c" is different from "d" */ } else { // if the process is here, than one of the two conditions above is not true if (a == b) { /* "c" equals "d" */ } else { /* "a" is not equal to "b", but "c" may or may not equal "d" */ } } ``` -------------------------------- ### Calculating Average Income using CYCLE_LINK (LSD) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This LSD code snippet demonstrates how to iterate through all outgoing links from the current node using the CYCLE_LINK macro. It sums the 'Income' attribute of connected nodes and then calculates the average income based on the total number of outgoing links (STAT_NODE). This is typically used within an LSD Equation block. ```LSD (Custom Syntax) v[1] = 0; // reset the income accumulator CYCLE_LINK( curl1 ) // scan all network neighbors { cur = LINKTO( curl1 ); // get an object link to current neighbor v[2] = VS( cur, "Income" ); // get neighbor income v[1] += v[2]; // accumulate income } V[3] = STAT_NODE; // get current node total outgoing links v[4] = v[1] / v[3]; // calculate the average income ``` -------------------------------- ### Accessing Variable via Global Object Pointer (LSD VS Macro) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md Shows how to access the value of a Variable named "Price" from a specific LSD Object instance pointed to by the global pointer market using the VS (Variable Specific) Macro. This is presented as a more efficient method compared to searching when the target instance is frequently accessed. ```C++/LSD v[0] = VS( market, "Price" ); ``` -------------------------------- ### Using SEARCH_CND Macro in LSD Macro Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This code generates a random integer between 1 and 100 using `uniform_int` and stores it in `v[0]`. It then uses the SEARCH_CND macro to search the model for an object instance containing the parameter 'IdFirm' whose value matches the randomly generated number stored in `v[0]`. The pointer to the first found object is stored in `cur`. ```LSD Macro v[0] = uniform_int( 1, 100 ); cur = SEARCH_CND( "IdFirm", v[0] ); ``` -------------------------------- ### Accessing Eigen Matrix Properties and Elements in LSD Equation Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md Shows how to compute the determinant and access specific elements of an Eigen MatrixXd extension within an LSD Object Equation. It uses `DO_EXT` to call the determinant method and `EXT` to access elements by their zero-based indices. ```LSD/C++ v[0] = DO_EXT( MatrixXd, determinant ); // compute the determinant of matrix v[11] = EXT( MatrixXd )( 0, 0 ); // pick element in the first row and column ``` -------------------------------- ### Comparing CURRENT and VL(Var, 1) in an Equation Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This `EQUATION` snippet illustrates that within a variable's computation, accessing `CURRENT` yields the same value as accessing the variable's value from the previous time step using `VL("VarName", 1)` when the variable is defined to store past values. ```LSD/C++ EQUATION( "Up" ) /* This function returns a progressive value each time it is requested */ v[0] = CURRENT; v[1] = VL( "Up", 1 ); /* v[0] and v[1] are identical */ RESULT( v[0] ) ``` -------------------------------- ### Defining User Temporary Local Variables in LSD Equations Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The `EQ_USER_VARS` macro allows defining local C++ variables that are visible within all equations. Multiple variables are separated by semicolons, and multi-line definitions are possible using backslashes. ```LSD/C++ #define EQ_USER_VARS var1; var2; … ``` -------------------------------- ### Writing to Addressable Object in LSD C++ Extension with WRITE_ARG_EXT C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The WRITE_ARG_EXT and WRITE_ARG_EXTS macros write a 'value' to an addressable C++ object ('c_obj', e.g., vector/matrix elements) within a data extension in an LSD object, using additional arguments. WRITE_ARG_EXT operates on the current object (THIS), WRITE_ARG_EXTS on 'obj'. Additional arguments are passed after 'value'. If the extension doesn't exist, the macro does nothing. ```C++ WRITE_ARG_EXT( class, c_obj, value, … ) ``` ```C++ WRITE_ARG_EXTS( obj, class, c_obj, value, … ) ``` -------------------------------- ### Summing Variable Across Descendants - LSD C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet defines an equation for 'Q_TOT' within an Object like 'Market'. It uses the SUM() macro to find and sum all instances of the variable 'Q' located within the descendant objects of the current object (e.g., 'Firm' instances descending from 'Market'). ```C++ EQUATION( "Q_TOT" ) /* Compute the sum of all Q's in the market */ RESULT( SUM( "Q" ) ) ``` -------------------------------- ### Defining Equation with RNDDRAW_FAIR Macro in LSD Macro Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This code defines an equation 'DrawAFirm' that uses the RNDDRAW_FAIR macro to randomly select one 'Firm' instance with equal probability among all instances named 'Firm'. The pointer to the selected firm is stored in `cur`. It then retrieves and returns the 'IdFirm' parameter of the selected firm using VS and RESULT. ```LSD Macro EQUATION( "DrawAFirm" ) /*************************** Return the Id of a Firm chosen randomly with identical probabilities for each object ***************************/ cur = RNDDRAW_FAIR( "Firm" ); RESULT( VS( cur, "IdFirm" ) ) ``` -------------------------------- ### Looping Through LSD Extension Vector with CYCLE_EXT C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This C++ snippet demonstrates how to iterate over a vector contained within a C++ data extension of an LSD object using the CYCLE_EXT macro. It copies elements from the vector 'tech_params' of an 'ext_firm' extension into a temporary LSD storage array 'v'. It requires the 'ext_firm' extension to exist on the current LSD object and contain a 'tech_params' vector. ```C++ vector< int >::iterator iter; // create iterator to integer vector type i = 0; // index for v[…] array CYCLE_EXT( iter, ext_firm, tech_params ) // loop over all vector elements { v[i] = *iter; // get current vector element i++; // update v[…] index (iter is updated by CYCLE_EXT) } ``` -------------------------------- ### Declaring Local Equation Variables (LSD EQ_USER_VARS) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md Explains how to declare local C++ variables or data structures that are specific to a single EQUATION's scope using the #define EQ_USER_VARS preprocessor directive before MODELBEGIN. Multiple variables can be declared using a semicolon separator, and multiline definitions are supported with backslashes. ```C++/LSD #include "../src/fun_head_fast.h" #define EQ_USER_VARS object *this_market; \ int id_market; \ double sales_market; MODELBEGIN ``` -------------------------------- ### Returning a Result in LSD Equation Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The `RESULT(value)` macro is used within an `EQUATION` block to specify the output value for the variable being computed for the current time step. ```LSD/C++ RESULT( 1 ) ``` -------------------------------- ### Using the ABORT Macro to Stop Simulation Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The `ABORT` macro instructs LSD to stop the current simulation run at the end of the ongoing simulation step. All equations scheduled for the current step will still be evaluated before termination. ```LSD/C++ ABORT ``` -------------------------------- ### Counting Object Instances using LSD Macros Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These macros count instances of the specified 'obj_Lab' object type among descendants. 'COUNT' and 'COUNTS' count within the first group under THIS or 'obj', respectively. 'COUNT_ALL' and 'COUNT_ALLS' count all instances under THIS or 'obj'. Conditional variants ('_CND', '_CNDL') filter instances based on a condition applied to 'Lab', 'lop', and 'value', with optional 'lag'. Returns the count or 0 if no objects/instances are found or satisfy the condition. ```LSD/C++ Macro COUNT( "obj_Lab" ), COUNTS( obj, "obj_Lab" ) ``` ```LSD/C++ Macro COUNT_CND( "obj_Lab", "Lab", "lop", value ), COUNT_CNDS( obj, "obj_Lab", "Lab", "lop", value ) ``` ```LSD/C++ Macro COUNT_CNDL( "obj_Lab", "Lab", "lop", value, lag ), COUNT_CNDLS( obj, "obj_Lab", "Lab", "lop", value, lag ) ``` ```LSD/C++ Macro COUNT_ALL( "obj_Lab" ), COUNT_ALLS( obj, "obj_Lab" ) ``` ```LSD/C++ Macro COUNT_ALL_CND( "obj_Lab", "Lab", "lop", value ), COUNT_ALL_CNDS( obj, "obj_Lab", "Lab", "lop", value ) ``` ```LSD/C++ Macro COUNT_ALL_CNDL( "obj_Lab", "Lab", "lop", value, lag ), COUNT_ALL_CNDLS( obj, "obj_Lab", "Lab", "lop", value, lag ) ``` -------------------------------- ### Defining LSD Equation Using Temporary Storage (LSD/C++) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows how to use LSD's temporary numeric storage array `v[n]` within an equation. Values fetched using LSD Macros (`V`, `VL`) are stored in temporary variables (`v[0]` to `v[999]`) before being used in the final calculation within the `RESULT` macro. This improves code readability and facilitates debugging. ```LSD Macro Language EQUATION( "PROF" ) /*************************** The equation computes the profit rate: PROF(t) = P(t) * A(t-1) - C - RIM – RIN * Inn profits per unit of capital are equal current price times lagged productivity minus the cost for research (innovative firms spend for both type of research) and fixed costs. ***************************/ v[0] = V( "Price" ); v[1] = VL( "A",1 ); v[2] = V( "C" ); v[3] = V( "RIM" ); v[4] = V( "RIN" ); v[5] = V( "Inn" ); RESULT( v[0] * v[1] - v[2] - v[3] - v[4] * v[5] ) ``` -------------------------------- ### Iterating Nested Objects and Summing Variables (LSD Macro) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates how to use the CYCLE and CYCLES macros to iterate through instances of nested objects ('Market' containing 'Firm'). It calculates the sum of the 'Profit' variable for all 'Firm' objects within each 'Market', accumulating the total in v[0]. Pointers cur and cur1 are used to reference the current objects during iteration. ```LSD Macro v[0] = 0; // set to v[0] to be initially 0 CYCLE( cur, "Market" ) { // for each market CYCLES( cur, cur1, "Firm" ) { // for each firm, contained in cur v[1] = VS( cur1, "Profit" ); v[0] = v[0] + v[1]; } } // from here v[0] contains the cumulated profits ``` -------------------------------- ### Executing Method on LSD C++ Extension with DO_EXT C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The DO_EXT and DO_EXTS macros execute a method ('meth') defined by the top-level class/struct of a C++ data extension within an LSD object. DO_EXT works on the current object (THIS), while DO_EXTS works on 'obj'. Arguments for the method are included after 'meth'. The macro returns the method's return value. It cannot directly invoke methods of inner classes; use EXEC_EXT for that. ```C++ DO_EXT( class, meth, … ) ``` ```C++ DO_EXTS( obj, class, meth, … ) ``` -------------------------------- ### Writing to Variable in LSD C++ Extension with WRITE_EXT C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The WRITE_EXT and WRITE_EXTS macros write a 'value' to a specified C++ variable ('var') within a data extension in an LSD object. WRITE_EXT writes to the current object (THIS), while WRITE_EXTS writes to 'obj'. The 'value' type must match 'var'. If the extension does not exist, the macro does nothing. Errors occur if the variable is missing or types are incompatible. ```C++ WRITE_EXT( class, var, value ) ``` ```C++ WRITE_EXTS( obj, class, var, value ) ``` -------------------------------- ### Sorting Objects on Two Variables using SORT2 in LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet demonstrates the SORT2 macro to sort object instances labeled 'Market'. It first sorts by increasing values of variable 'X', and then uses variable 'Y' as a secondary sorting key for instances with equal 'X' values. ```LSD SORT2( "Market", "X", "Y", UP ); ``` -------------------------------- ### Aggregating Multiple Statistics using LSD Macros Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These macros compute a set of descriptive statistics for 'Lab' or 'Lab1' among descendant objects. They behave like SUM() but calculate count, average, variance, maximum, minimum, median, and standard deviation, storing them in temporary variables v[0] through v[6]. 'STATL' and 'STATLS' include a 'lag'. '_CND' and '_CNDS' add a condition based on 'Lab2', 'lop', and 'value'. The 'S' variants operate on descendants of 'obj'. The macro itself returns the number of instances (v[0]). Returns NAN for statistics (v[1]-v[6]) and 0 for count (v[0]) if no instances are found or satisfy the condition. ```LSD/C++ Macro STAT( "Lab" ), STATS( obj, "Lab" ) ``` ```LSD/C++ Macro STATL( "Lab", lag ), STATLS( obj, "Lab", lag ) ``` ```LSD/C++ Macro STAT_CND( "Lab1", "Lab2", "lop", value ), STAT_CNDS( obj, "Lab1", "Lab2", "lop", value ) ``` ```LSD/C++ Macro STAT_CNDL( "Lab1", "Lab2", "lop", value, lag ), STAT_CNDLS( obj, "Lab1", "Lab2", "lop", value, lag ) ``` -------------------------------- ### Cycling through Data Extension Container Elements - C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These macros allow iterating over elements within a C++ container ('c_obj') that is part of an LSD data extension of type 'class' hosted in the current (THIS) or specified 'obj' Object. The modeler must provide an iterator variable 'iter' which is updated by the macro. Requires the target Object to have the specified data extension. ```C++ CYCLE_EXT( iter, class, c_obj ) CYCLE_EXTS( obj, iter, class, c_obj ) ``` -------------------------------- ### Calculating Next Time Step in LSD (C++) Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This code snippet demonstrates how to check if the current simulation time step (T) is before the last configured time step (LAST_T) and, if so, calculate the next time step (T + 1) and assign it to a model variable (v[9]). This is typically used within an equation or function block in an LSD model to control time-dependent logic or update state variables based on the simulation step. It relies on the LSD macros T and LAST_T. ```C++ if( T < LAST_T ) v[9] = T + 1; ``` -------------------------------- ### Interrupting Simulation with Interactive Debugger in LSD Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These macros interrupt the simulation run and open the LSD Debugger window, displaying a 'Comment'. The debugger focuses on the object containing the call or the specified 'obj'. It presents a numeric field initialized with 'value'. The user can modify this value, and the macro returns the user's input, allowing simulation flow to be influenced interactively. ```LSD/C++ Macro INTERACT( "Comment", value ), INTERACTS( obj, "Comment ", value ) ``` -------------------------------- ### Increment and Decrement Operators in C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md These C++ snippets illustrate the increment (++) and decrement (--) operators, which increase or decrease a variable's value by 1. They can be used before (prefix) or after (postfix) the variable, affecting the order of operation in expressions where the variable's value is used before being modified. ```C++ a++; ``` ```C++ ++a; ``` ```C++ a = 3; b = a++; c = ++a; ``` -------------------------------- ### Using the CURRENT Macro to Access Variable Value Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The `CURRENT` macro provides access to the current value of the variable being computed, regardless of when it was last calculated. This is equivalent to using `VL("VarName", 0)` or `VL("VarName", 1)` depending on context and definition. ```LSD/C++ CURRENT ``` -------------------------------- ### Disabling Pointer Initialization/Checking - C++ Preprocessor Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md This snippet shows the C++ preprocessor directives used in LSD models to disable the default initialization of temporary object pointers (like cur, cur1). Disabling initialization also implicitly disables pointer checking, potentially improving performance after a model is debugged, but increasing the risk of crashes if pointers are used incorrectly. These lines must appear before the main include file. ```C++ Preprocessor #define NO_POINTER_INIT\n#include fun_head_fast.h ``` -------------------------------- ### Executing Method on Inner Object in LSD C++ Extension with EXEC_EXT C++ Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The EXEC_EXT and EXEC_EXTS macros execute a method ('meth') of a specific C++ object ('c_obj') residing within a C++ data extension in an LSD object. EXEC_EXT works on the current object (THIS), while EXEC_EXTS works on 'obj'. Arguments for the method follow 'meth'. This macro is used for invoking methods of inner objects within the extension, unlike DO_EXT which calls methods of the top-level class. ```C++ EXEC_EXT( class, c_obj, meth, … ) ``` ```C++ EXEC_EXTS( obj, class, c_obj, meth, … ) ``` -------------------------------- ### Setting Default Result for Failed Equations Source: https://github.com/emmanueltsallis/lsd/blob/main/lsd_macros.md The `DEFAULT_RESULT( value )` macro allows specifying a default value that an `EQUATION` will return if it fails to produce a valid result using `RESULT` or `END_EQUATION`. The standard default is 0. ```LSD/C++ DEFAULT_RESULT( value ) ```