import Pkg
Pkg.activate(@__DIR__)
Pkg.instantiate()
BEE 4750 Homework 1: Introduction to Using Julia
If you are enrolled in the course, make sure that you use the GitHub Classroom link provided in Ed Discussion, or you may not be able to get help if you run into problems.
Otherwise, you can find the Github repository here.
Overview
Instructions
- Problem 1 consist of a series of code snippets for you to interpret and debug. You will be asked to identify relevant error(s) and fix the code.
- Problem 2 gives you some code that works as intended; your goal is to identify the code’s purpose by following its logic.
- Problem 3 asks you to write code to generate a random vector and subtract off its mean, using a Julia syntax called broadcasting.
- Problem 4 asks you to convert a verbal description of a wastewater treatment system into a Julia function, and then to use that function to explore the impact of different wastewater allocation strategies.
- Problem 5 (5750 only) asks you to use more advanced Julia techniques.
Load Environment
The following code loads the environment and makes sure all needed packages are installed. This should be at the start of most Julia scripts.
Standard Julia practice is to load all needed packages at the top of a file. If you need to load any additional packages in any assignments beyond those which are loaded by default, feel free to add a using
statement, though you may need to install the package.
using Random
using Plots
using GraphRecipes
using LaTeXStrings
# this sets a random seed, which ensures reproducibility of random number generation. You should always set a seed when working with random numbers.
Random.seed!(1)
TaskLocalRNG()
Problems (Total: 50/60 Points)
Problem 1 (15 points)
The following subproblems all involve code snippets that require debugging.
For each of them:
- identify and describe the logic and/or syntax error;
- write a fixed version of the function;
- use your fixed function to solve the problem.
Problem 1.1
You’ve been tasked with writing code to identify the minimum value in an array. You cannot use a predefined function. Your colleague suggested the function below, but it does not return the minimum value.
function minimum(array)
= 0
min_value for i in 1:length(array)
if array[i] < min_value
= array[i]
min_value end
end
return min_value
end
= [89, 90, 95, 100, 100, 78, 99, 98, 100, 95]
array_values @show minimum(array_values);
minimum(array_values) = 0
Problem 1.2
Your team is trying to compute the average grade for your class, but the following code produces an error.
= [89, 90, 95, 100, 100, 78, 99, 98, 100, 95]
student_grades function class_average(grades)
= mean(student_grades)
average_grade return average_grade
end
@show average_grade;
UndefVarError:
UndefVarError: `average_grade` not defined
Stacktrace:
[1] macro expansion
@ show.jl:1181 [inlined]
[2] top-level scope
@ ~/Teaching/BEE4750/website/hw/hw01/hw01.qmd:184
Problem 1.3
Your team wants to know the expected payout of an old Italian dice game called passadieci (which was analyzed by Galileo as one of the first examples of a rigorous study of probability). The goal of passadieci is to get at least an 11 from rolling three fair, six-sided dice. Your strategy is to compute the average wins from 1,000 trials, but the code you’ve written below produces an error.
function passadieci()
# this rand() call samples 3 values from the vector [1, 6]
= rand(1:6, 3)
roll return roll
end
= 1_000
n_trials = zero(n_trials)
outcomes for i = 1:n_trials
= (sum(passadieci()) > 11)
outcomes[i] end
= sum(outcomes) / n_trials # compute average number of wins
win_prob @show win_prob;
MethodError:
MethodError: no method matching setindex!(::Int64, ::Bool, ::Int64)
Stacktrace:
[1] top-level scope
@ ~/Teaching/BEE4750/website/hw/hw01/hw01.qmd:215
Problem 2 (5 points)
You’ve been handed some code to analyze. The original coder was not very considerate of other potential users: the function is called mystery_function
and there are no comments explaining the purpose of the code. It appears to take in an array and return some numbers, and you’ve been assured that the code works as intended.
function mystery_function(values)
= []
y for v in values
if !(v in y)
append!(y, v)
end
end
return y
end
= [1, 2, 3, 4, 3, 4, 2, 1]
list_of_values @show mystery_function(list_of_values);
mystery_function(list_of_values) = Any[1, 2, 3, 4]
In this problem:
- Explain the purpose of
mystery_function
. - Add comments to the code, explaining why and how it works. Refer to “Best Practices for Writing Code Comments”, and remember that bad comments can be just as bad as no comments at all. You do not need to add comments to every line (in fact, this is very bad practice), but you should note the purpose of every “section” of code, and add comments explaining any code sequences that you don’t immediately understand.
- Is there a built-in Julia function that does the same thing as
mystery_function
? If so, what is it? Use it to do the same thing as the code above.
Problem 3 (10 points)
You’re interested in writing some code to remove the mean of a vector.
In this problem:
- Write a function
compute_mean(v)
which sums all of the elements of a vectorv
using afor
loop and computes the mean. - Make a random vector
random_vect
of length 10 using Julia’srand()
function. Use yourcompute_mean()
function to calculate its mean and subtract it fromrandom_vect
without a loop (using a Julia technique called broadcasting; feel free to consult the Julia documentation and search as necessary). Check that the new vector has mean zero.
Problem 4 (20 points)
Cheap Plastic Products, Inc. is operating a plant that produces \(100 \text{m}^3\text{/day}\) of wastewater that is discharged into Pristine Brook. The wastewater contains \(1 \text{kg/m}^3\) of YUK, a toxic substance. The US Environmental Protection Agency has imposed an effluent standard on the plant prohibiting discharge of more than \(20 \text{kg/day}\) of YUK into Pristine Brook.
Cheap Plastic Products has analyzed two methods for reducing its discharges of YUK. Method 1 is land disposal, which costs \(X_1^2/20\) dollars per day, where \(X_1\) is the amount of wastewater disposed of on the land (\(\text{m}^3\text{/day}\)). With this method, 20% of the YUK applied to the land will eventually drain into the stream (i.e., 80% of the YUK is removed by the soil).
Method 2 is a chemical treatment procedure which costs $1.50 per \(\text{m}^3\) of wastewater treated. The chemical treatment has an efficiency of \(e= 1 - 0.005X_2\), where \(X_2\) is the quantity of wastewater (\(\text{m}^3\text{/day}\)) treated. For example, if \(X_2 = 50 \text{m}^3\text{/day}\), then \(e = 1 - 0.005(50) = 0.75\), so that 75% of the YUK is removed.
Cheap Plastic Products is wondering how to allocate their wastewater between these three disposal and treatment methods (land disposal, chemical treatment, and direct disposal) to meet the effluent standard while keeping costs manageable.
The flow of wastewater through this treatment system is shown in Figure 1. Modify the edge labels (by editing the edge_labels
dictionary in the code producing Figure 1) to show how the wastewater allocations result in the final YUK discharge into Pristine Brook. For the edge_label
dictionary, the tuple \((i, j)\) corresponds to the arrow going from node \(i\) to node \(j\). The syntax for any entry is (i, j) => "label text"
, and the label text can include mathematical notation if the string is prefaced with an L
, as in L"x_1"
will produce \(x_1\).
= [0 1 1 1;
A 0 0 0 1;
0 0 0 1;
0 0 0 0]
= ["Plant", "Land Treatment", "Chem Treatment", "Pristine Brook"]
names # modify this dictionary to add labels
= Dict((1, 2) => "", (1,3) => "", (1, 4) => "",(2, 4) => "",(3, 4) => "")
edge_labels =[:hexagon, :rect, :rect, :hexagon]
shapes= [0, -1.5, -0.25, 1]
xpos = [1, 0, 0, -1]
ypos
= graphplot(A, names=names,edgelabel=edge_labels, markersize=0.15, markershapes=shapes, markercolor=:white, x=xpos, y=ypos)
p display(p)
In this problem:
Formulate a mathematical model for the treatment cost and the amount of YUK that will be discharged into Pristine Brook based on the wastewater allocations. This is best done with some equations and supporting text explaining the derivation. Make sure you include, as additional equations in the model, any needed constraints on relevant values. You can find some basics on writing mathematical equations using the LaTeX typesetting syntax here, and a cheatsheet with LaTeX commands can be found on the course website’s Resources page.
Implement your systems model as a Julia function which computes the resulting YUK concentration and cost for a particular treatment plan. You can return multiple values from a function with a tuple, as in:
function multiple_return_values(x, y) return (x+y, x*y) end a, b = multiple_return_values(2, 5) @show a; @show b;
To evalute the function over vectors of inputs, you can broadcast the function by adding a decimal
.
before the function arguments and accessing the resulting values by writing a comprehension to loop over the individual outputs in the vector:x = [1, 2, 3, 4, 5] y = [6, 7, 8, 9, 10] output = multiple_return_values.(x, y) a = [out[1] for out in output] b = [out[2] for out in output] @show a; @show b;
Make sure you comment your code appropriately to make it clear what is going on and why.
Use your function to experiment with some different combinations of wastewater discharge and treatment and plot the results of these experiments. Can you find one that satisfies the YUK effluent standard (plot this as well as a dashed red line)? What was the cost? What can you say about the tradeoff between treatment cost and YUK concentration? You don’t have to find an “optimal” solution to this problem, but what do you think would be needed to find a better solution?
Problem 5 (10 points)
This problem is only required for students in BEE 5750.
Problem 5.1
Using a comprehension, count the number of odd numbers between 0 and 149.
iseven()
returns true
for even numbers and false
for odd numbers.
Problem 5.2
Write a function polynomial(x, a)
which calculates the polynomial \[p(x) = \sum_{i=1}^n a_i x^i\]
based on a point x
and a coefficient vector a
of length n
using a loop. Test your function by computing \[p(x) = 2x^3 - x^2 + 1\] at \(x=2\).
References
List any external references consulted, including classmates.