Giter VIP home page Giter VIP logo

juliateachingctu / scientific-programming-in-julia Goto Github PK

View Code? Open in Web Editor NEW
67.0 4.0 13.0 65.25 MB

Repository for B0M36SPJ

Home Page: https://juliateachingctu.github.io/Scientific-Programming-in-Julia/dev/

License: MIT License

Julia 1.33% Jupyter Notebook 98.67%
automatic-differentiation differential-equations gpu-acceleration julia julia-language julialang meta-programming parallel-programming

scientific-programming-in-julia's Introduction

Course logo


License

This repository contains all the course materials for the master course Scientific Programming in Julia taught at the Czech Technical University in Prague. You can find more information on the official course website.

Before joining the course

Consider reading the following two blog posts to figure out if Julia is a language in which you want to invest your time.

  • What is great about Julia.
  • What is bad about Julia.

scientific-programming-in-julia's People

Contributors

anton-bushuiev avatar bozenkhaa avatar janfrancu avatar kunz-david avatar nmheim avatar pevnak avatar pitmonticone avatar smidl avatar themrghostman avatar vaclavmacha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

scientific-programming-in-julia's Issues

Lecture 2

Abstraction was too tough, explain better, how things click it.

  • The transition from theory to practice was difficult.

Improve lab 03

  • Simplify/split last exercise in multiple parts
  • explain better why we are moving to parametric types
  • should we maybe move away from the ecosystem? simpler example for parametric types would be good...?
  • add full solution of lab 03 (sketched below)
EcosystemCore.mates(::Animal{S,Female}, ::Animal{S,Male}) where S<:Species = true
EcosystemCore.mates(::Animal{S,Male}, ::Animal{S,Female}) where S<:Species = true
EcosystemCore.mates(::Agent, ::Agent) = false

##########  Additional functionality  ##########################################

function simulate!(world::World, iters::Int; cb=()->())
    for i in 1:iters
        world_step!(world)
        cb()
    end
end

agent_count(p::Plant) = size(p)/EcosystemCore.max_size(p)
agent_count(::Animal) = 1
agent_count(as::Vector{<:Agent}) = sum(agent_count,as)

function agent_count(w::World)
    function op(d::Dict,a::Agent{S}) where S<:Species
        n = nameof(S)
        if n in keys(d)
            d[n] += agent_count(a)
        else
            d[n] = agent_count(a)
        end
        return d
    end
    foldl(op, w.agents |> values |> collect, init=Dict{Symbol,Real}())
end

function every_nth(f::Function, n::Int)
    i = 1
    function callback(args...)
        # display(i) # comment this out to see out the counter increases
        if i == n
            f(args...)
            i = 1
        else
            i += 1
        end
    end
end

Lab06 sreplace_i

Hi, I have a I think correct solution for the string replacement, in case you wish to add it.

sreplace_i(s) = replace(s, r"([^\w]|\b)i(?=[^\w]|\z)" => s"\1k")

It replaces "i" only if it is not preceded or followed by an alphanumeric character or there is an end/beginning of string.

example:

s = "i + i*i + y*i - sin(z) + int(i) + i"
sreplace_i(s)

"k + k*k + y*k - sin(z) + int(k) + k"

Simplify find_food

1. Hint: For the functional programming way of coding this can use `filter` and
`isa` to filter for a certain type and `StatsBase.sample` to choose a random
element from a vector. You can get an `Iterator` of values of your dictionary
via `values` which you might want to `collect` before passing it to `sample`.
2. Hint: You could also program this with a for-loop that iterates over your
agents in a random order.

Using filter is both slow and not super straight forward in this case. We could remove hint 1 and expand on hint 2.

Another nice example for hygiene

module A
f() = println("hello")
macro foo()
      :(f())
end
end
Main.A

julia> f() = println("goodbye")
f (generic function with 1 method)

julia> A.@foo
hello

and compare this to

module A
f() = println("hello")
macro foo()
      :(esc(f())))
end
end

2nd Lab problem with provided method agent_step!()

In 2nd lab we are provided with method agent_step!(a::Animal, w::World).

https://github.com/JuliaTeachingCTU/Scientific-Programming-in-Julia/blob/master/docs/src/lecture_02/lab.md#code-skeleton

This method assumes we have implmented kill_agent!() method which is then used here

if energy(a) <= 0 kill_agent!(a,w) return end

But this is never referenced as a task or side note, but it is present in solved solutions.

It would be worth to add task for creating this method aswell, so the simulation works in the end after adding all other methods.

Improve lab 04

We should probably use PkgTemplates.jl to simplify the lab. Orient on Vasek's workflow tutorial in lecture 7 of the julia for optimization course.

Polynomial coefficients order consistency

All the versions of polynomial function should share the same order of coefficients, that is consistent with how it is evaluated in Julia's evalpoly.

Currently in the lab we have coefficients ordered from a_0 to a_n, but it is probably reversed such that the order from the original polynomial a_n*x^n + a_{n-1}*x^{n-1} + ... + a_1*x + a_0 is conserved.

Affected pages

  • Lab 1 (naive)
  • Lab 5 (Horner)
  • Lab 6 (recursive)
  • Lab 7 (macro generation)

Lecture 8 --- a take on explaining the tape

  • First, when working out the tape example, we should use the same names of variables, i.e. x,y h1, h2, h3, z...
  • we should explain that the computation graph is not stored in a single place, but it is stored in a distributed fashion in nodes.
  • we might break the computation to steps, for example h1 = x * y and show, how the graph is built and how edges are stored and where.

Lab 5 Ecosystem profiling and benchmarking

Ideally we should have used deepcopy and fixed Random.seed! for the simulation profiling.
Different versions of the code might use RNG in a different way, thus the simulation is also different.
The same applies for the benchmarking. We should benchmark only what is needed: find_rand.

Ideas for improving lecture/lab 11

AbbreviatedStackTraces

Test and if it succeeds, put AbbreviatedStackTraces.jl to Lecture 1 on parsing the errors

Add note on unit testing on GitLab to lab4

Unit test can be setup also on GitLab, see tutorial from Tamás K. Papp.
It boils down to adding a file .gitlab-ci.yml to the root of a repo with the following few lines

image: julia:1.6                # image comes from Docker hub

default:
  script:
    - julia --project=@. -e "import Pkg; Pkg.test()"

Documentation can be hosted in a similar fashion as well.

Improving Lab 02 & 03

Lab 02

  • implement rational numbers (do we have a real world use case?)
  • implement ecosystem without world
    • do it bottom up with simple examples instead of top down
    • implement: types (non-parametric Wolf/Sheep/Grass, show, eats

Improvement suggestions from last year

  • get rid of getters/setters (#16)

Lab 03

  • quick, theoretical walk through of ⚥Sheep forward method including overloading of getproperty (and setproperty!) for ⚥Sheep:
function Base.getproperty(s::⚥Sheep, x::Symbol)
    if x == :sex || x == :sheep
        getfield(s,x)
    else
        getfield(s.sheep,x)
    end
end
  • introduce parametric type for species/sex
  • implement rest of ecosystem (immutable version?!!)

Improvement suggestions from last year

  • Simplify/split last exercise in multiple parts
  • explain better why we are moving to parametric types
  • Previous #13: Using filter is both slow and not super straight forward in this case. We could remove hint 1 and expand on hint 2.
    1. Hint: For the functional programming way of coding this can use `filter` and
    `isa` to filter for a certain type and `StatsBase.sample` to choose a random
    element from a vector. You can get an `Iterator` of values of your dictionary
    via `values` which you might want to `collect` before passing it to `sample`.
    2. Hint: You could also program this with a for-loop that iterates over your
    agents in a random order.
  • add full solution of lab 03 (sketched below)
EcosystemCore.mates(::Animal{S,Female}, ::Animal{S,Male}) where S<:Species = true
EcosystemCore.mates(::Animal{S,Male}, ::Animal{S,Female}) where S<:Species = true
EcosystemCore.mates(::Agent, ::Agent) = false

##########  Additional functionality  ##########################################

function simulate!(world::World, iters::Int; cb=()->())
    for i in 1:iters
        world_step!(world)
        cb()
    end
end

agent_count(p::Plant) = size(p)/EcosystemCore.max_size(p)
agent_count(::Animal) = 1
agent_count(as::Vector{<:Agent}) = sum(agent_count,as)

function agent_count(w::World)
    function op(d::Dict,a::Agent{S}) where S<:Species
        n = nameof(S)
        if n in keys(d)
            d[n] += agent_count(a)
        else
            d[n] = agent_count(a)
        end
        return d
    end
    foldl(op, w.agents |> values |> collect, init=Dict{Symbol,Real}())
end

function every_nth(f::Function, n::Int)
    i = 1
    function callback(args...)
        # display(i) # comment this out to see out the counter increases
        if i == n
            f(args...)
            i = 1
        else
            i += 1
        end
    end
end

Homework 05 warntype improvements

Checking type stability on function with optional arguments does not show the whole picture

@code_warntype find_root(p, Newton(), -5.0, 5.0) # shows only the wrapper function which is stable
@code_warntype find_root(p, Newton(), -5.0, 5.0, 100, 0.95, 1e-12)  # fully specified (shows type instabilities - also used in the eval)

The problem here is that the function is type stable in the way that the compiler knows the output type before execution, however the eval pipeline checks for all ::Any entries in the fully specified function, i.e. for runtime dispatches of which there are few. This leads to confusion based on what has been said in the lab.

Final project: Parallel Ecosystem

Implement / test / benchmark a parallelized version of the Ecosystem which would be based on multiple phases of an agent step:

  1. create a list of all potential interactions (e.g.: "wolf eats sheep", "sheep eats grass", ...)
  2. find collisions like "sheep1 eats grass1" / "sheep2 eats grass1" and resolve them
  3. execute interactions
  4. remove / spawn agents

Notes for lecture 3

  • Mention Peter Norvig's claim that in functional programming most design patterns are not needed?
  • Make a difference between closure and partial evaluation
  • Do we mention Inner Constructor to enforce type invariants?
  • Note that the structure ##1 is not directly accessible. Try f.x and g.x. is I think incorrect as you can access it. Try in repl
function call_counter(f)
	called = 0
	(args...;kwargs...) -> begin
		called += 1
		f(args...;kwargs...)
	end
end

counted_println = call_counter(println);
counted_println("hello world"

But somehow the above does not trigger that
https://discourse.julialang.org/t/accessing-data-in-a-closure/54930/4

Remove annoying getters & setters

The getters and setters we currently use in the Ecosystem are only there because of the ⚥Sheep type which should demonstrate the forwarding of fields. We could get rid of all of them by overloading getproperty (and setproperty!) for ⚥Sheep instead:

function Base.getproperty(s::⚥Sheep, x::Symbol)
    if x == :sex || x == :sheep
        getfield(s,x)
    else
        getfield(s.sheep,x)
    end
end

Example why polynomials is a thing

In labs, we talk a lot about polynomials as an example where meta programming buys you speed due to loop unrolling.
But students might not appreciate why polynomials are such a big deal.

  • they are important for computing complicated functions, which are mostly computed from taylor expansion.
  • We have found out polynomials to be super important for private machine learning, as secret sharing schemes rely on that https://mortendahl.github.io/

Notes for Lecture 4

  • Precompilation has improved by a great mean
  • As mentioned in notes to 3, Interface -> Separate(sub)Module for discoverability
  • Might be good place to talk about PackageCompiler, which is just an awesome way to avoid TTFT.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.