# Core Functions¶

## move¶

If the person is not dead, then

```        if(states[current_person_id] != DEAD)
```

First, the function randomly picks whether the person moves left or right or does not move in the x dimension.

The code uses (random() % 3) - 1; to achieve this. (random() % 3) returns either 0, 1, or 2. Subtracting 1 from this produces -1, 0, or 1. This means the person can move to the right, stay in place (0), or move to the left (-1).

then the function randomly picks whether the person moves up or down or does not move in the y dimension. This is similar to movement in x dimension.

```            // The thread randomly picks whether the person moves left
// or right or does not move in the x dimension
x_move_direction = (random() % 3) - 1;

// The thread randomly picks whether the person moves up
// or down or does not move in the y dimension
y_move_direction = (random() % 3) - 1;
```

Next, If the person will remain in the bounds of the environment after moving, then

We check this by making sure the person’s x location is greater than or equal to 0 and less than the width of the environment and that the person’s y location is greater than or equal to 0 and less than the height of the environment. In the code, it looks like this:

```            if((x_locations[current_person_id] + x_move_direction >= 0)
&& (x_locations[current_person_id]
+ x_move_direction < environment_width)
&& (y_locations[current_person_id]
+ y_move_direction >= 0)
&& (y_locations[current_person_id]
+ y_move_direction < environment_height))
```

Finally, The function moves the person

```                x_locations[current_person_id]
+= x_move_direction;
y_locations[current_person_id]
+= y_move_direction;
```

The function is able to achieve this by simply changing values in the x_locations and y_locations arrays.

## susceptible¶

For each people, the function to do the following

```    for(current_person_id = 0; current_person_id
<= global->number_of_people - 1; current_person_id++)
```

If the person is susceptible,

```        if(states[current_person_id] == SUSCEPTIBLE)
```

For each of the infected people or until the number of infected people nearby is 1, the function does the following

```            for(my_person = 0; my_person <= global->num_infected - 1
&& num_infected_nearby < 1; my_person++)
```

If the person is within the infection radius, then

```                if((x_locations[current_person_id]
&& (x_locations[current_person_id]
&& (y_locations[current_person_id]
&& (y_locations[current_person_id]
```

Finally, the function increments the number of infected people nearby

```                    num_infected_nearby++;
```

This is where a large chunk of the algorithm’s computation occurs. Each susceptible person must be computed with each infected person to determine how many infected people are nearby each person. Two nested loops means many computations. In this step, the computation is fairly simple, however. The function simply increments the num_infected_nearby variable.

Note in the code that if the number of infected nearby is greater than or equal to 1 and we have SHOW_RESULTS enabled, we increment the num_infection_attempts variable. This helps us keep track of the number of attempted infections, which will help us calculate the actual contagiousness of the disease at the end of the simulation.

If there is at least one infected person nearby, and a random number less than 100 is less than or equal to the contagiousness factor, then

```            if(num_infected_nearby >= 1 && (random() % 100)
<= contagiousness_factor)
```

Recall that the contagiousness factor is the likelihood that the disease will be spread. We measure this as a number less than 100. For example, if there is a 30% chance of contagiousness, we use 30 as the value of the contagiousness factor. To figure out if the disease is spread for any given interaction of people, we find a random number less than 100 and check if it is less than or equal to the contagiousness factor, because this will be equivalent to calculating the odds of actually spreading the disease (e.g. there is a 30% chance of spreading the disease and also a 30% chance that a random number less than 100 will be less than or equal to 30).

The function changes the state to infected

```                states[current_person_id] = INFECTED;
```

```                // The thread updates the counters
global->num_infected++;
global->num_susceptible--;
```

These steps are as simple as updating the states array by states[my_current_person_id] = INFECTED, incrementing the num_infected variable, and decrementing the num_susceptible variable.

Note in the code that if the infection succeeds and we have SHOW_RESULTS enabled, we increment the num_infections variable. This helps us keep track of the actual number of infections, which will help us calculate the actual contagiousness of the disease at the end of the simulation.

## infected¶

For each people, the function to do the following

```    for(current_person_id = 0; current_person_id
<= global->number_of_people - 1; current_person_id++)
```

If the person is infected and has been for the full duration of the disease, then

```        if(states[current_person_id] == INFECTED
&& num_days_infected[current_person_id]
== duration_of_disease)
```

Note in the code that if we have SHOW_RESULTS enabled, we increment the num_recovery_attempts variable. This helps us keep track of the number of attempted recoveries, which will help us calculate the actual deadliness of the disease at the end of the simulation.

```            stats->num_recovery_attempts++;
```

If a random number less than 100 is less than the deadliness factor, then

```            if((random() % 100) < deadliness_factor)
```

The function changes the person’s state to dead

```                states[current_person_id] = DEAD;
```

```                // The thread updates the counters
global->num_infected--;
```

This step is effectively the same as function susceptible, considering deadliness instead of contagiousness. The difference here is the following step:

Otherwise,

The function changes the person’s state to immune

```                states[current_person_id] = IMMUNE;
```

```                // The thread updates the counters
global->num_immune++;
global->num_infected--;
```

If deadliness fails, then immunity succeeds.

Note in the code that if the person dies and we have SHOW_RESULTS enabled, we increment the num_deaths variable. This helps us keep track of the actual number of deaths, which will help us calculate the actual deadliness of the disease at the end of the simulation.

```                // The thread updates stats counter
#ifdef SHOW_RESULTS
stats->num_deaths++;
#endif
```

## update_days_infected¶

For each people, the function to do the following

```    for(current_person_id = 0; current_person_id
<= global->number_of_people - 1; current_person_id++)
```

If the person is infected, then

```        if(states[current_person_id] == INFECTED)
```

Increment the number of days the person has been infected

```            num_days_infected[current_person_id]++;
```

This is achieved by incrementing each member of the num_days_infected array, which can be done as follows: num_days_infected[my_current_person_id]++