Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: zz-x2580
Introduction
Opinion dynamics aims to understand how views spread through a population- how long does it take for everyone to like a certain song or settle on a side in a political debate? Simple models of opinion dynamics can be developed using ODEs, or as discrete models on a grid. However, these structures do not capture the complex social relationships people have (i.e most of us interact with more than 4 people!). Better models of opinion dynamics instead used networks to model these social relationships, allowing us to understand how opinions spread through a human population. In this assignment, you will work as a group to implement a number of models for understanding how opinions spread through a population, allowing you to identify the effect of key parameters.
The assignment will assess your ability to:
1. Translate from a description of a mathematical model into working code for simulating that model.
2. Write Python code that adheres to a given specification, in part validated by automatic test functions.
3. Work with a group to develop code that is not only correct, but also easy to read.
4. Make effective use of version control tools such as Git.
Submission
This assignment is to be completed in groups of four. You should work together to produce a single codebase, but each person should contribute some individual parts to the code. The core assignment has 5 sections, and the first four of these can be completed independently of each other- you may want to assign each of these tasks to one group member. The final part will require you to integrate these bits of code, and is best tackled as a group. Also note, that you are expected to work together- if one team member is struggling, you are expected to work together to help them out!
Each member of your group should submit your work via Blackboard. Submission should consist of:
1. Code (submitted as a single .zip file)
2. Reflection report (submitted individually)
3. A readme.txt, explaining what you've implemented, how to run it, and including a link to a shared Github repo.
The deadline for this assessment is 1pm, May 2nd. Each person should expect to spend 12-15 hours on this assignment (including the 6 hours available during lab sessions).
Assessment
Each of the five tasks has been allocated a number of points (totalling 100). For each task, half the points are allocated for correctness, and half allocated for readability. We will evaluate correctness by running the tests functions we have provided you with, by running the test functions we have asked you to write (and checking that they cover all the cases we would expect), and by comparing whether the output is as described in the "What we expect to see section". We will evaluate readability based on your use of functions to organise code, your use of comments, variables names and function names to make it clear how your code works, and your use of Git (i.e consistently making commits with informative commit messages).
Task 1: The Ising Model (15 points)
The first model we’ll consider involves a population of people who can hold opinions either for or against an issue- we'll model this by assigning them a value, , equal to +1 (for) or –1 (against). The key assumption we'll make in this model is that people want to hold similar opinions to there neighbours, and are more likely to change their opinion if everybody around them disagrees. We can capture this principle by calculating, the agreement, , the amount that person, , agrees with their immediate neighbours:
where represents the neighbours of person . In this model, we'll initially model our population using a numpy array, and assume that each person's neighbours are those immediately adjacent in the grid (i.e we count those above, below, left and right, but not connected diagonally). In the image below, the neighbours of the cell in blue are shown in red.
If a person agrees with a neighbour, then the product will be positive. If a person disagrees, the signs of and will be different and so the product will be negative. This suggests the first approach we can use for understanding how opinions spread through a population- we can repeatedly pick a random person and then calculate . If is positive, then that person agrees with a majority of their neighbours and shouldn't change their opinion. If is negative, then they should flip their opinion.
This simple model can be extended in two ways. First, we can introduce the fact that although people generally want to agree with their neighbours, they won't always do so- some people will stand for their principles even in the face of disapproval of their neighbours. We can introduce this by sometimes flipping an opinion even when is positive. In this model, we choose to accept flips that reduce agreement with probability . This captures that flips that only reduce by a small amount are more likely than those that increase it by a large amount.
The variable represents how tolerant a society is of those who disagree with their neighbours- if is large, then the fraction will be small, regardless of the value of . As is close to 1 for values for close to 0, large will lead to a high probability of flips- this society is tolerant of those who disagree. As is reduced, the chance of a flip reduces.
Secondly, we can introduce the effect of an external pull on opinions (representing, for example, a prevailing opinion in the media). We can include this by adding a term to the equation for calculating disagreement, H, where H represents the strength of the external opinion. The equation for then becomes:
The code given in "FCP_assignment.py" partially implements this model- we've written the main function and some code for plotting the grid. However, the function for calculating the change in "agreement" has not been implented (currently it just returns a random value), nor have the two extensions been implemented. Your task is to complete the code by implementing the function calculate_agreement and updating the main function to include flips that increase disagreement.
How you'll know your code is correct
We've included the test function, test_ising that we'll use to make sure your code is correct. I should be able to run this function by running your code with the flag test_ising. If the overall model is correct, then you should see that for small values of , large islands of a particular opinion coalesce over time. As you increase , the size of these islands should decrease, until the system remains disordered throughout the simulation. Increasing the external opinion in either direction should bias the model towards that direction. Note that as this is a stochastic (i.e using randomness) model, your output won't be exactly the same as shown here, but the general trend should be observed.
What I expect to see when I assess your code
I should be able to run this model from the command line by calling your program with the flag -ising_model . Your code should default to using a value of H=0, unless I also include the flag -external . Your code should default to using a value of alpha=1, unless I also include the flag -alpha . When ran, your code should solve the model, displaying an animation of the opinion as it evolves.
$ python3 assignment.py -ising_model #This should run the ising model with default parameters
$ python3 assignment.py -ising_model -external -0.1 #This should run the ising model with default temperature and an external inf
$ python3 assignment.py -ising_model -alpha 10 #This should run the ising model with no external influence but with a temperature
$ python3 assignment.py -test_ising #This should run the test functions associated with the model.
Task 2: Defuant Model. (20 points)
The second model we'll consider represents opinions on a continous scale, [0, 1]. Here, we again use the principle that people want to agree with their neighbours, but we'll also limit that agreement to people whose opinion is within some distance of ours- essentially, people don't want to listen to somebody whose opinion is radically different to their own. We'll model this by repeatedly choosing a random person, and then a random neighbour of that person. If the two selected people have a difference of opinion greater than a threshold, nothing happens. If their difference of opinion is less than the threshold, then we update both people's opinions, by moving them towards the mean opinion. Mathematically, we can describe this as:
if |xi(t) − xj(t)| < T
where , is the threshold for interaction, and is a coupling parameter- if is large, then each update will cause both neighbours to adjust their opinions strongly towards the mean. If is small, each update will only cause small changes towards the mean. Your task is to implement this model on a 1D grid. This means each person in the population only has two possible neighbours- one to the left and one to the right. You should include some plotting to solution of the model and some test functions to make sure your code is working correctly.
How you'll know your code is correct
You should include a function test_defuant to check whether your model is correctly updating opinions. Make sure to cover the basic behaviour of the model and any edge cases. I should be able to call your test function by running your code with the flags -test_defuant . If the overall model is correct, I should see an initially random distribution of opinions begin to separate into distinct clusters. Increasing the value of should increase the rate at which these clusters form, while decreasing the threshold should increase the number of clusters. For a threshold around 0.5, I would expect to see the model evolve to a single cluster (i.e everybody converges to a single opinion). As the threshold is reduced, I should see more clusters begin to emerge.
In these plots, the first is simply a histogram of the population for the last timestep. The second plot has the timestep on the x-axis, and the value of each member of the population at that timestep on the y axis.