diff --git a/.travis.yml b/.travis.yml index cfcf63d..1a8e414 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,14 @@ services: jobs: include: + - stage: Build Sources + if: branch = master + language: scala + scala: + - 2.12.5 + script: + - sbt ++$TRAVIS_SCALA_VERSION compile tut + - stage: GitHub Release if: tag IS present before_install: diff --git a/README.md b/README.md index cf04ed4..d839da9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Community tutorial for CIlib +[](https://travis-ci.org/cirg-up/cilib-tutorial) + Welcome to the community tutorial source repository! ## About the tutorial diff --git a/build.sbt b/build.sbt index a0d67cd..eff0f0d 100644 --- a/build.sbt +++ b/build.sbt @@ -11,18 +11,54 @@ git.useGitDescribe := true scalacOptions ++= Seq( "-deprecation", - "-encoding", "UTF-8", - "-unchecked", - "-feature", - "-Xlint", -// "-Xfatal-warnings", - "-Ywarn-dead-code", - "-Ypartial-unification" -// "-Ydelambdafy:inline" // workaround for future deadlock on the 2.12.1 REPL + "-encoding", "utf-8", // Specify character encoding used by source files. + "-explaintypes", // Explain type errors in more detail. + "-feature", // Emit warning and location for usages of features that should be imported explicitly. + "-language:existentials", // Existential types (besides wildcard types) can be written and inferred + "-language:experimental.macros", // Allow macro definition (besides implementation and application) + "-language:higherKinds", // Allow higher-kinded types + "-language:implicitConversions", // Allow definition of implicit functions called views + "-unchecked", // Enable additional warnings where generated code depends on assumptions. + "-Xcheckinit", // Wrap field accessors to throw an exception on uninitialized access. + "-Xfatal-warnings", // Fail the compilation if there are any warnings. + "-Xfuture", // Turn on future language features. + "-Xlint:adapted-args", // Warn if an argument list is modified to match the receiver. + "-Xlint:by-name-right-associative", // By-name parameter of right associative operator. + "-Xlint:constant", // Evaluation of a constant arithmetic expression results in an error. + "-Xlint:delayedinit-select", // Selecting member of DelayedInit. + "-Xlint:doc-detached", // A Scaladoc comment appears to be detached from its element. + "-Xlint:inaccessible", // Warn about inaccessible types in method signatures. + "-Xlint:infer-any", // Warn when a type argument is inferred to be `Any`. + "-Xlint:missing-interpolator", // A string literal appears to be missing an interpolator id. + "-Xlint:nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'. + "-Xlint:nullary-unit", // Warn when nullary methods return Unit. + "-Xlint:option-implicit", // Option.apply used implicit view. + "-Xlint:package-object-classes", // Class or object defined in package object. + "-Xlint:poly-implicit-overload", // Parameterized overloaded implicit methods are not visible as view bounds. + "-Xlint:private-shadow", // A private field (or class parameter) shadows a superclass field. + "-Xlint:stars-align", // Pattern sequence wildcard must align with sequence component. + "-Xlint:type-parameter-shadow", // A local type parameter shadows a type already in scope. + "-Xlint:unsound-match", // Pattern match may not be typesafe. + "-Yno-adapted-args", // Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver. + "-Ypartial-unification", // Enable partial unification in type constructor inference + "-Ywarn-dead-code", // Warn when dead code is identified. + "-Ywarn-extra-implicit", // Warn when more than one implicit parameter section is defined. + "-Ywarn-inaccessible", // Warn about inaccessible types in method signatures. + "-Ywarn-infer-any", // Warn when a type argument is inferred to be `Any`. + "-Ywarn-nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'. + "-Ywarn-nullary-unit", // Warn when nullary methods return Unit. + "-Ywarn-numeric-widen", // Warn when numerics are widened. + "-Ywarn-unused:implicits", // Warn if an implicit parameter is unused. + "-Ywarn-unused:imports", // Warn if an import selector is not referenced. + "-Ywarn-unused:locals", // Warn if a local definition is unused. + "-Ywarn-unused:params", // Warn if a value parameter is unused. + "-Ywarn-unused:patvars", // Warn if a variable bound in a pattern is unused. + "-Ywarn-unused:privates", // Warn if a private member is unused. + "-Ywarn-value-discard" // Warn when non-Unit expression results are unused. ) -scalacOptions in Tut := (scalacOptions in Tut).value.filterNot(Set("-Ywarn-unused-import")) +scalacOptions in Tut := (scalacOptions in Tut).value.filterNot(Set("-Ywarn-unused-import", "-Ywarn-unused:imports")) libraryDependencies ++= Seq( "net.cilib" %% "cilib-core" % cilibVersion, @@ -42,8 +78,10 @@ lazy val epub = taskKey[Unit]("Build the ePub version of the book") lazy val json = taskKey[Unit]("Build the Pandoc JSON AST of the book") lazy val all = taskKey[Unit]("Build all versions of the book") -pdf := { tutQuick.value ; "grunt pdf" ! } -html := { tutQuick.value ; "grunt html" ! } -epub := { tutQuick.value ; "grunt epub" ! } -json := { tutQuick.value ; "grunt json" ! } +import scala.sys.process._ + +pdf := { tutQuick.value ; Seq("grunt", "pdf").! } +html := { tutQuick.value ; Seq("grunt", "html").! } +epub := { tutQuick.value ; Seq("grunt", "epub").! } +json := { tutQuick.value ; Seq("grunt", "json").! } all := { pdf.value ; html.value ; epub.value ; json.value } diff --git a/project/build.properties b/project/build.properties index 64317fd..0531343 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.15 +sbt.version=1.1.2 diff --git a/project/plugins.sbt b/project/plugins.sbt index 90d4a2b..2ca4d70 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.9.3") -addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.5.2") -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC8") +addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.6.4") +addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.1") diff --git a/src/pages/benchmarks/index.md b/src/pages/benchmarks/index.md index 1d4aa28..bdd5953 100644 --- a/src/pages/benchmarks/index.md +++ b/src/pages/benchmarks/index.md @@ -1,13 +1,16 @@ # Benchmarks -Often in computational intelligence we will need to test algorithms on standard problems. -It should be noted that CIRG contains a library of benchmarks that we can use with CILib. -The benchmarks can be found [here][benchmarks] as well as a list of available benchmarks. -To import benchmarks into your build you need the following dependency added to your sbt.build. +Often in computational intelligence we will need to test algorithms on +standard problems. It should be noted that CIRG contains a library of +benchmarks that we can use with CILib. The benchmarks can be found +[here][benchmarks] as well as a list of available benchmarks. To +import benchmarks into your build you need the following dependency +added to your sbt.build. ` "net.cilib" %% "benchmarks" % "0.1.1"` -The following snippets of code will demonstrate how to include benchmarks in your program as an example use. +The following snippets of code will demonstrate how to include +benchmarks in your program as an example use. ```tut:book:silent import cilib._ @@ -17,12 +20,13 @@ import spire.implicits._ import spire.math.Interval // Example use +val bounds = Interval(-5.12,5.12)^30 val env = Environment( cmp = Comparison.dominance(Min), - eval = Eval.unconstrained(Benchmarks.spherical[NonEmptyList, Double]).eval, - bounds = Interval(-5.12,5.12)^30) + eval = Eval.unconstrained(Benchmarks.spherical[NonEmptyList, Double]).eval) ``` -That's all there is to it! -Be sure to check out the list of benchmarks that are included and can be accessed by the `Benchmark` object. +That's all there is to it! Be sure to check out the list of +benchmarks that are included and can be accessed by the `Benchmark` +object. diff --git a/src/pages/constraint/object.md b/src/pages/constraint/object.md index 4046160..e2235be 100644 --- a/src/pages/constraint/object.md +++ b/src/pages/constraint/object.md @@ -45,9 +45,10 @@ import spire.implicits._ import spire.algebra.Eq val sumLessThanCons = LessThan(sumCF, 12.0) -val firstNumberCons = cilib.Equal(ConstraintFunction((l: NonEmptyList[Double]) => l.head), 4.0) // A constraint that ensures the first element of a list is 4 +val firstNumberCons = cilib.Equal(ConstraintFunction((l: NonEmptyList[Double]) => l.head), 4.0) ``` + ```tut:book Constraint.violationCount(List(sumLessThanCons, firstNumberCons), NonEmptyList(19.0, 37.23, 12.0)) Constraint.violationCount(List(sumLessThanCons, firstNumberCons), NonEmptyList(4.0, 3.0, 2.0)) @@ -60,4 +61,4 @@ Determines the magnitude of the number of violated constraints. ```tut:book Constraint.violationMagnitude(0.1, 0.9, List(sumLessThanCons, firstNumberCons), NonEmptyList(19.0, 37.23, 12.0)) -``` \ No newline at end of file +``` diff --git a/src/pages/position/maths.md b/src/pages/position/maths.md index f189ce8..6243820 100644 --- a/src/pages/position/maths.md +++ b/src/pages/position/maths.md @@ -10,17 +10,17 @@ import spire.math._ import scalaz._ import Scalaz._ ``` + ```tut:book:silent val rng = RNG.init(1234L) val e = Eval.unconstrained[NonEmptyList,Double](_.map(x => x*x).suml).eval val a = Position.createPosition(Interval(-5.12,5.12)^3).eval(rng) val b = Position.createPosition(Interval(-5.12,5.12)^3).flatMap(p => Position.eval(e, p)).eval(rng) ``` + ```tut:book a + b // Add Point and Solution a + a // Add Point and Point b + b // Add Solution and Solution a - b // Subtract Solution from Point - -// And so forth -``` \ No newline at end of file +``` diff --git a/src/pages/runner/GAexample.md b/src/pages/runner/GAexample.md index 4ec95b1..5bbfc16 100644 --- a/src/pages/runner/GAexample.md +++ b/src/pages/runner/GAexample.md @@ -1,8 +1,12 @@ ## Creating a GA Isn't this exciting! + All our work over the past chapters is coming together! -It should be noted that the only thing we will be using from `cilib-ga` is the type `Individual`, which, as we discussed before, is an `Enity` with a state of type `Unit` since GA's do not need a state. + +It should be noted that the only thing we will be using from +`cilib-ga` is the type `Individual`, which, as we discussed before, is +an `Enity` with a state of type `Unit` since GA's do not need a state. ### Imports @@ -20,26 +24,30 @@ import spire.math.Interval ### The Problem Environment -For our problem we are going to attempt to find the greatest area produced by a 2 dimensional rectangle. -The sides can range from 0.1 to 12. +For our problem we are going to attempt to find the greatest area +produced by a 2 dimensional rectangle. The sides can range from 0.1 +to 12. ```tut:book +val bounds = Interval(0.1, 12.0)^2 + val env = Environment( cmp = Comparison.dominance(Max), - eval = Eval.unconstrained[NonEmptyList,Double](_.foldLeft1(_ * _)).eval, - bounds = Interval(0.1, 12.0)^2 + eval = Eval.unconstrained[NonEmptyList,Double](_.foldLeft1(_ * _)).eval ) ``` ### The GA Algorithm The GA algorithm is the exact same one used in `cilib-ga`. -The reason we are intentionally defining it as opposed to importing it is so that we can see the inner workings and learn from it. + +The reason we are intentionally defining it as opposed to importing it +is so that we can see the inner workings and learn from it. ```scala def ga[S]( p_c: Double, - parentSelection: NonEmptyList[Individual[S]] => RVar[List[Individual[S]]], + parentSelection: NonEmptyList[Individual[S]] => RVar[List[Individual[S]]], crossover: List[Individual[S]] => RVar[List[Individual[S]]], mutation: List[Individual[S]] => RVar[List[Individual[S]]] ): NonEmptyList[Individual[S]] => Individual[S] => Step[Double,List[Individual[S]]] = @@ -64,22 +72,27 @@ crossover //is the function that we will use to produce off spring mutation //is the function we will use to mutate the offspring ``` -All right. Not too bad. -By being able to pass functions to a generic GA method allows us to build a GA specific to our needs. -It should also be noted that all the passable functions yield the same data type. -Now before we move to the actual implementation of the `ga` method, I would like to remind you that for comprehensions are essentially chained `flatMaps`. -This allows us to chain steps together. -So we know that this method will return a function of type +All right. Not too bad. By being able to pass functions to a generic +GA method allows us to build a GA specific to our needs. It should +also be noted that all the passable functions yield the same data +type. Now before we move to the actual implementation of the `ga` +method, I would like to remind you that for comprehensions are +essentially chained `flatMaps`. This allows us to chain steps +together. So we know that this method will return a function of type `NonEmptyList[Individual[S]] => Individual[S] => Step[Double,List[Individual[S]]]` -Which in simply means, that we are going to get a function that return a `Step` representing a series of computations applied to every `Individual` with a collection of `Individuals`. -Okay, so now we know what we are returning but let's see how we get to that by looking at the "series of computations". +Which in simply means, that we are going to get a function that return +a `Step` representing a series of computations applied to every +`Individual` with a collection of `Individuals`. Okay, so now we know +what we are returning but let's see how we get to that by looking at +the "series of computations". `parents <- Step.pointR(parentSelection(collection))` -Here we are selecting our parents from the collection using the parentSelection function that was passed as a parameter. -Lastly, it will be wrapped in a `Step`. +Here we are selecting our parents from the collection using the +parentSelection function that was passed as a parameter. Lastly, it +will be wrapped in a `Step`. `r <- Step.pointR(Dist.stdUniform.map(_ < p_c))` @@ -91,27 +104,36 @@ crossed <- else Step.point[Double,List[Individual[S]]](parents) ``` -If r is `true` we will produce crossovers based on the `parents` using the crossover function parameter, else we are going to just leave the parents as is. -How frequently the crossover occurs depends on your `p_c`. +If r is `true` we will produce crossovers based on the `parents` using +the crossover function parameter, else we are going to just leave the +parents as is. How frequently the crossover occurs depends on your +`p_c`. `mutated <- Step.pointR[Double,List[Individual[S]]](mutation(crossed))` -Nothing too complex here. We are simply mutating our ``crossed`` individuals using the mutation function parameter. -Also note that ``mutated`` will have a data type very similar tto our return type. +Nothing too complex here. We are simply mutating our ``crossed`` +individuals using the mutation function parameter. Also note that +``mutated`` will have a data type very similar tto our return type. `evaluated <- mutated.traverseU(x => Step.eval((v: Position[Double]) => v)(x))` -Lastly, we are taking every `Individual` from `mutated` and wrapping each one in an evaluation `Step`. -Remember that this is just a step representing evaluation, not actually evaluating the `Individuals` right now. +Lastly, we are taking every `Individual` from `mutated` and wrapping +each one in an evaluation `Step`. Remember that this is just a step +representing evaluation, not actually evaluating the `Individuals` +right now. Let's get to creating the functions we will be passing to our ga method. ### Selection Method -For our selection method we will be creating a random selection method. -We know that it needs to have the type `NonEmptyList[Individual[S]] => RVar[List[Individual[S]]]`. -To make this even easier to read we can include a custom type, `type Ind = Individual[Unit]`, making it `NonEmptyList[Ind] => RVar[List[Individual[S]]]`. -Create a function with the name `randomSelection` that will randomly select two `Inds` from an non empty list. +For our selection method we will be creating a random selection +method. We know that it needs to have the type +`NonEmptyList[Individual[S]] => RVar[List[Individual[S]]]`. To make +this even easier to read we can include a custom type, `type Ind = +Individual[Unit]`, making it `NonEmptyList[Ind] => +RVar[List[Individual[S]]]`. Create a function with the name +`randomSelection` that will randomly select two `Inds` from an non +empty list.