From f22ee1d6700ea92899f8ff27708bfe69060fff04 Mon Sep 17 00:00:00 2001 From: Emanuel Lima Date: Fri, 18 Oct 2024 17:47:22 -0400 Subject: [PATCH] Work form the retreat Signed-off-by: Emanuel Lima --- .github/workflows/CI.yml | 2 +- Manifest.toml | 2 +- src/CadCAD.jl | 24 ++++++------ src/compositions.jl | 21 +++++++++-- src/spaces.jl | 81 +++++++--------------------------------- test/example.jl | 16 ++++---- test/polar2cartesian.jl | 59 +++++++++++++++++++++++++++++ 7 files changed, 113 insertions(+), 92 deletions(-) create mode 100644 test/polar2cartesian.jl diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 44b24f8..6a7d247 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -20,7 +20,7 @@ jobs: version: - 'nightly' - 'lts' - - 'release' + - '1' os: - ubuntu-latest - macos-latest diff --git a/Manifest.toml b/Manifest.toml index 6a19d57..53592d0 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.11.0" +julia_version = "1.11.1" manifest_format = "2.0" project_hash = "164b1a53474087c138be2860bd47c316d99a458d" diff --git a/src/CadCAD.jl b/src/CadCAD.jl index 68476d6..358be01 100644 --- a/src/CadCAD.jl +++ b/src/CadCAD.jl @@ -1,11 +1,11 @@ module CadCAD -export run +export run_exp include("spaces.jl") using .Spaces -using Logging, StructArrays, StaticArrays +using Logging, StaticArrays """ cadCAD.jl v0.0.2 @@ -25,24 +25,24 @@ function intro() """ end -function run(init_state::T, experiment_params::Dict{String, Int}, - pipeline::String) where {T <: Space} +function run_exp(init_state::T, experiment_params::NamedTuple, + pipeline::String) where {T <: Point} intro() pipeline_expr = pipeline_compile(pipeline) - result_matrix = SVector{experiment_params["n_runs"], StructArray{T <: Space}} + result_matrix = SVector{experiment_params.n_runs, Vector{T <: Point}} - for _ in 1:experiment_params["n_runs"] + for i in 1:(experiment_params.n_runs) current_state = init_state - result = StructArray{T <: Space} - push!(result, current_state) + result = Vector{T}(undef, experiment_params.n_steps) + result[1] = current_state - for _ in 1:experiment_params["n_steps"] - current_state = eval(Symbol(result[end]) * pipeline_expr) - push!(result, current_state) + for j in 1:(experiment_params.n_steps) + current_state = result[end] |> eval(pipeline_expr) # TODO + result[j + 1] = current_state end - push!(result_matrix, result) + result_matrix[i] = result end return result_matrix diff --git a/src/compositions.jl b/src/compositions.jl index 321d5ef..29c48a6 100644 --- a/src/compositions.jl +++ b/src/compositions.jl @@ -3,15 +3,30 @@ module Compositions include("dynamics.jl") using .Dynamics +using .Spaces: Point, dimensions, cartesian -import Base: > +import Base: >, | function is_composable(block1::Function, block2::Function)::Bool return isequal(lower_codomain(block1), lower_codomain(block2)) end -function >(prev_block_result::Any, next_block::Function) - return prev_block_result |> next_block +function >(prev_block_result::Point, next_block::Function) + return next_block(prev_block_result...) +end + +function |(first_block_result::Point, second_block_result::Point) + return joinpoint(first_block_result, second_block_result) +end + +function joinpoint(first_pt::Point, second_pt::Point) + first_dims = typeof(first_pt) + second_dims = typeof(second_pt) + + cartesian(first_dims, second_dims, "Joined$(name(first_dims))$(name(second_dims))") +end + +function splitpoint(first_pt::Point, second_pt::Point) end end diff --git a/src/spaces.jl b/src/spaces.jl index 42b2b00..25e6b31 100644 --- a/src/spaces.jl +++ b/src/spaces.jl @@ -7,7 +7,7 @@ export dimensions, inspect_space, name, is_empty, is_equivalent, import Base: +, *, ^, ==, ∩, - -#using Printf +using Printf abstract type Point end @@ -36,70 +36,19 @@ end =# # Factory methods -#function generate_space_type( -# schema::NamedTuple, name::String, io::IO = stderr, debug = false) -# state_signature = generate_space_signature(schema) -# -# if isnothing(state_signature) -# error("Invalid schema") -# else -# eval(space_factory(state_signature, name)) -# if debug -# println(io, "Generated space $name") -# end -# end -#end -# -#function generate_space_type( -# schema::Dict{Symbol, DataType}, name::String, io::IO = stderr, debug = false) -# state_signature = generate_space_signature(schema) -# -# if isnothing(state_signature) -# error("Invalid schema") -# else -# eval(space_factory(state_signature, name)) -# if debug -# println(io, "Generated space $name") -# end -# end -#end -# -#function generate_empty_space() -# eval(space_factory("", "EmptySpace")) -#end -# -#function space_factory(state_signature::String, space_name::String) -# fields = map(x -> Meta.parse(x), split(state_signature)) -# -# space = Symbol(space_name) -# -# return quote -# struct $space <: Space -# $(fields...) -# -# function $space($(fields...),) -# new($(fields...),) -# end -# end -# end -#end -# -#function generate_space_signature(schema::Union{NamedTuple, Dict}) -# state_signature = "" -# -# for (key, value) in pairs(schema) -# if isa(key, Symbol) && isa(value, DataType) -# state_signature *= "$key::$value " -# else -# return nothing -# end -# end -# return state_signature -#end +function generate_space_type( + schema::Union{Dict{Symbol, DataType}, NamedTuple}, name::String) + state_signature = Meta.parse("@kwdef struct $name <: Point\n$(join(["$(repr(key))::$(repr(value))" for (key, value) in schema], "\n"))\nend") + if isnothing(state_signature) + error("Invalid schema") + else + eval(state_signature) + end +end # Informational methods -function isspace(space::DataType)::Bool +function isspace(space::T)::Bool where {T <: DataType} return isstructtype(space) && !ismutabletype(space) && !(Any in fieldtypes(space)) end @@ -195,7 +144,7 @@ function is_shallow(space::DataType)::Bool return all(value -> !(value isa Space), values(dimensions(space))) end -function ==(space1::DataType, space2::DataType)::Bool +function ==(space1::T, space2::T)::Bool where {T <: DataType} if !isspace(space1) || !isspace(space2) error("Spaces were not provided") end @@ -294,10 +243,6 @@ function space_add( end function *(space1::DataType, space2::DataType) - if !isspace(space1) || !isspace(space2) - error("Spaces were not provided") - end - return cartesian(space1, space2, "$(name(space1))x$(name(space2))") end @@ -379,6 +324,8 @@ end # Built-in space types +using .Spaces + struct EmptySpace <: Point end @kwdef struct RealSpace <: Point diff --git a/test/example.jl b/test/example.jl index f0e09f7..3a5795d 100644 --- a/test/example.jl +++ b/test/example.jl @@ -2,7 +2,7 @@ module Example -using CadCAD.Spaces +using CadCAD: EmptySpace, Point # Create the spaces as kwdef structs (for now) @@ -43,22 +43,22 @@ sim_params = ( function predator_births(domain::EmptySpace, codomain::DeltaPopulation, params::NamedTuple) delta = params.predator_birth_rate * rand(Float64) * params.c_predator - codomain.delta_pop = floor(delta) + codomain.delta_pop = floor(Int, delta) end function prey_births(domain::EmptySpace, codomain::DeltaPopulation, params::NamedTuple) - delta = params.predator_birth_rate * rand(Float64) * params.c_prey - codomain.delta_pop = floor(delta) + delta = params.prey_birth_rate * rand(Float64) * params.c_prey + codomain.delta_pop = floor(Int, delta) end function predator_deaths(domain::EmptySpace, codomain::DeltaPopulation, params::NamedTuple) delta = params.predator_death_rate * rand(Float64) * params.c_predator - codomain.delta_pop = floor(delta) + codomain.delta_pop = floor(Int, delta) end function prey_deaths(domain::EmptySpace, codomain::DeltaPopulation, params::NamedTuple) delta = params.prey_death_rate * rand(Float64) * params.c_prey - codomain.delta_pop = floor(delta) + codomain.delta_pop = floor(Int, delta) end function join_naturals(prey_b::DeltaPopulation, predator_b::DeltaPopulation, @@ -79,7 +79,7 @@ end function hunt(initial_pop::Population, codomain::Population) codomain.predator_population = initial_pop.predator_population - codomain.prey_population = floor(initial_pop.predator_population * 0.95) + codomain.prey_population = floor(UInt, initial_pop.prey_population * 0.95) end # Set the initial state @@ -91,7 +91,7 @@ initial_conditions = Population(; # Set the pipeline -#pipeline = "((predator_births | prey_births | predator_deaths | prey_deaths) > join_naturals) > natural_causes > hunt" +pipeline = "((predator_births | prey_births | predator_deaths | prey_deaths) > join_naturals) > natural_causes > hunt" # Run the simulation diff --git a/test/polar2cartesian.jl b/test/polar2cartesian.jl new file mode 100644 index 0000000..3e79f9b --- /dev/null +++ b/test/polar2cartesian.jl @@ -0,0 +1,59 @@ +# WiP + +module Polar2Cartesian + +using CadCAD: Point, run_exp + +# Create the spaces as kwdef structs (for now) + +@kwdef struct Cartesian <: Point + x::Float64 + y::Float64 +end + +@kwdef struct Polar <: Point + r::Float64 + phi::Float64 +end + +# Set the parameters + +sim_params = ( + n_steps = 5, + n_runs = 1 +) + +# Define the dynamics of the simulation + +function cartesian2polar(cart::Cartesian)::Polar + return Polar( + r = sqrt(cart.x^2 + cart.y^2), + phi = atan(cart.y, cart.x) + ) +end + +function polar2cartesian(pol::Polar)::Cartesian + return Cartesian( + x = pol.r * cos(pol.phi), + y = pol.r * sin(pol.phi) + ) +end + +# Set the initial state + +initial_conditions = Cartesian(; + x = 1.5, + y = 3.7 +) + +# Set the pipeline + +pipeline = "cartesian2polar > polar2cartesian" + +# Run the simulation + +trajectory = run_exp(initial_conditions, sim_params, pipeline) + +println(trajectory) + +end