Commit f912eb7d authored by Jim Newton's avatar Jim Newton

Merge branch 'lecture-2'

parents 7e2ddc63 0897230a
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package lecture
object FixedPoint {
def fixedPoint[A](initial:A, f:A=>A, goodEnough:(A,A)=>Boolean):A = {
def improve(current:A):A = {
val nextResult = f(current)
if (goodEnough(current,nextResult))
current
else
improve(nextResult)
}
improve(initial)
}
def main(argv:Array[String]):Unit = {
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package lecture
object BinarySearch {
import scala.math._
def binSearch(left:Double, right:Double, f:Double=>Double, target:Double, threshold:Double,maxDepth:Int):Option[Double] = {
// find where f(x) = target +/- threshold
binSearch(left, right, x=>f(x)-target, threshold,maxDepth)
}
def binSearch(left:Double, right:Double, f:Double=>Double, threshold:Double ,maxDepth:Int):Option[Double] = {
// find where f(x) = 0.0 +/- epsilon
val epsilon = abs(threshold * (f(left)-f(right)))
def recur(left:Double, right:Double, depth:Int):Option[Double] = {
val mid = (left + right)/2.0
val fm = f(mid)
if (depth >= maxDepth)
None
else if (abs(fm) < epsilon)
Some(mid)
else if (fm < 0)
recur(mid,right,depth+1)
else
recur(left,mid,depth+1)
}
if ( f(left) <= 0.0 && f(right) >= 0.0)
recur(left,right,0)
else if (f(left) >= 0.0 && f(right) <= 0.0)
recur(right,left,0)
else
None
}
def main(argv:Array[String]) = {
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package lecture
import scala.math._
object Calculus {
def almostEqual(tolerance:Double)(x:Double, y:Double):Boolean = {
abs(x - y ) <= tolerance
}
def limit(f: Double => Double, delta: Double, test: (Double, Double) => Boolean)(x: Double): Double = {
@scala.annotation.tailrec
def recur(h: Double, previous: Double): Double = {
val improved = f(x + h)
if (test(improved, previous)) {
improved
}
else
recur(h / 2, improved)
}
recur(delta / 2, f(x + delta))
}
def derivative(f: Double => Double, delta: Double, test: (Double, Double) => Boolean)(x: Double):Double = {
def estimate(h: Double): Double = {
(f(x + h) - f(x)) / h
}
// f(x+h) - f(x)
// derivative = Limit ------------- // which is a function of x
// h->0.0 h
limit(estimate, delta, test)(0.0)
}
def integral(f:Double=>Double, left:Double, right:Double, test:(Double,Double)=>Boolean):Double = {
def sumRectangles(partitionWidth: Double): Double = {
val numPartitions = floor((right - left) / partitionWidth).toInt
(0 until numPartitions).foldLeft(0.0) {
(area, partition) => area + partitionWidth * f(left + partition * partitionWidth)
}
}
if (right == left)
0.0
else if (right < left)
-1 * integral(f, right, left, test)
else
limit(sumRectangles, (right - left) / 2, test)(0.0)
}
def main(argv:Array[String]):Unit = {
println(almostEqual(0.001)(0, limit(cos,0.1,almostEqual(0.0001))(Pi/2)))
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package lecture
object Polynomial {
import scala.math.{pow,sqrt}
// We represent a polynomial such as 4x^3 - 2x +4
// as Map(3->4.0, 1->-1.0, 0->4.0)
type POLY = Map[Int,Double]
// given a polynomial and a numerical value, evaluate the polynomial.
// E.g., evaluate(Map(2->2.2, 0-> -1.1),4.3))
// ==> 2.2*pow(4.3,2) - 1.1*pow(4.3,0)
def evaluate(a:POLY,x:Double):Double = {
a.foldLeft(0.0){case (acc,(e,c)) => acc + c * pow(x,e)}
}
// given two polynomials, add them to form a new polynomial
// e.g., plus(Map(2->2.2, 0-> -1.1),Map(3->3.3, 0-> -1.1))
// ==> Map(3->3.3, 2->2.2, 0-> -2.2)
def plus(a:POLY,b:POLY):POLY = {
(a.keys ++ b.keys).map { e =>
(a.get(e), b.get(e)) match {
case (Some(c1), Some(c2)) => e -> (c1+c2)
case (Some(c1), None) => e -> c1
case (None, Some(c2)) => e -> c2
}
}.toMap
}
// detect whether two polynomials are close enough to qualify
// as equal, i.e., their RMS is less than epsilon
def almostEqual(epsilon:Double)(a:POLY,b:POLY):Boolean = {
// RMS mean of difference
sqrt((a.keys ++ b.keys).foldLeft(0.0) { (acc, e) =>
val diff = a.getOrElse(e, 0.0) - b.getOrElse(e, 0.0)
diff * diff
}) < epsilon
}
def main(argv:Array[String]):Unit = {
()
}
}
......@@ -402,6 +402,7 @@ object MetroData {
("Étienne Marcel", 347, 412 ))
val legData = List( // (source, destination, time-in-seconds)
// source and destination are indices into stationPositions Array
(0, 238, 41 ),
(0, 159, 46 ),
(1, 12, 36 ),
......
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package homework
import lecture.BinarySearch._
import math._
// Assignment name: Binary search for Boolean function
//
// This homework assignment accompanies section "Binary Search".
// The test cases can be found in the file BinarySearchTestSuite.scala
// You should complete the function, replacing ??? with correct Scala
// code so that the tests pass.
object BinarySearch {
def binSearchByBoolean(left:Double, right:Double, f:Double=>Boolean, delta:Double, maxDepth:Int):Option[Double] = {
// takes a function, f, for which f(left) = false, and f(right) = true,
// finds an x such that f(x)=false, and f(x+threshold)= true
def recur(left:Double,right:Double,depth:Int):Option[Double] = {
val mid = ???
if ( ??? < ???)
Some(???)
else if (depth >= maxDepth)
None
else if ( f(mid))
recur(???,???,???)
else
recur(???,???,???)
}
if ( !f(left) && f(right))
recur(???,???,???)
else
???
}
def main(argv:Array[String]) = {
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package homework
import lecture.Calculus._
// Assignment name: Implement double integral
//
// This homework assignment accompanies section "Convergence".
// The test cases can be found in the file DoubleIntegralTestSuite.scala
// You should complete the function, replacing ??? with correct Scala
// code so that the tests pass.
object DoubleIntegral {
def slowDoubleIntegral(f:(Double,Double)=>Double,
xmin:Double,ymin:Double,xmax:Double,ymax:Double,
test:(Double,Double)=>Boolean):Double = {
def single(x:Double):Double = {
integral(y => ???,???,???,???) // a function of y uses right and left bounds on y
}
integral(single,???,???,???) // a function of x uses right and left bounds on x
}
def main(argv:Array[String]) = {
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package homework
import lecture.Calculus.almostEqual
import lecture.FixedPoint._
// Assignment name: Square-root in a special way
//
// This homework assignment accompanies section "Fixed point".
// The test cases can be found in the file FixedPointTestSuite.scala
// You should complete the function, replacing ??? with correct Scala
// code so that the tests pass.
object FixedPoint {
def average(x:Double, y:Double):Double = {
???
}
def squareRoot(x:Double):Double = {
fixedPoint(???, y => average(???,???), almostEqual(???))
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package homework
import lecture.Calculus.derivative
// Assignment name: Implement the gradient of a binary funciton
//
// This homework assignment accompanies section "Convergence".
// The test cases can be found in the file GradientTestSuite.scala
// You should complete the function, replacing ??? with correct Scala
// code so that the tests pass.
object Gradient {
def gradient(f:(Double,Double)=>Double, delta:Double, test:(Double,Double)=>Boolean,x:Double, y:Double): (Double,Double) = {
val fx = f(x,_) // a function of y
val fy = f(???,???) // a function of x
val partialWRTx = derivative(???,???,???) _ // function of x
val partialWRTy = derivative(???,???,???) _ // function of y
// now the return value as a tuple
(???,???)
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package homework
import lecture.Calculus._
// Assignment name: Evaluate limit at a discontinuity
//
// This homework assignment accompanies section "Convergence".
// The test cases can be found in the file LimitTestSuite.scala
// You should complete the functions, replacing ??? with correct Scala
// code so that the tests pass.
object LimitAtDiscontinuity {
def f(x:Double):Double = {
// implementation of the polynomial
//
// 2
// x + 2x - 3
// -------------
// x - 1
//
???
}
def evalLimitAtDiscontinutiy():Double = {
limit(???, 0.1, ???)(???)
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package lecture
object Polynomial {
import scala.math.{pow,sqrt}
// We represent a polynomial such as 4x^3 - 2x +4
// as Map(3->4.0, 1->-1.0, 0->4.0)
type POLY = Map[Int,Double]
// given a polynomial and a numerical value, evaluate the polynomial.
// E.g., evaluate(Map(2->2.2, 0-> -1.1),4.3))
// ==> 2.2*pow(4.3,2) - 1.1*pow(4.3,0)
def evaluate(a:POLY,x:Double):Double = {
a.foldLeft(0.0){case (acc,(e,c)) => acc + c * pow(x,e)}
}
// given two polynomials, add them to form a new polynomial
// e.g., plus(Map(2->2.2, 0-> -1.1),Map(3->3.3, 0-> -1.1))
// ==> Map(3->3.3, 2->2.2, 0-> -2.2)
def plus(a:POLY,b:POLY):POLY = {
(a.keys ++ b.keys).map { e =>
(a.get(e), b.get(e)) match {
case (Some(c1), Some(c2)) => e -> (c1+c2)
case (Some(c1), None) => e -> c1
case (None, Some(c2)) => e -> c2
}
}.toMap
}
// create a new polynomial by multiplying a given polynomial by a given scalar (Double)
def scale(s:Double,b:POLY):POLY = {
???
}
// subtract two polynomials forming a new polynomial
def subtract(a:POLY,b:POLY):POLY = {
// this can be done with scale and plus
???
}
// multiply two polynomials by multiplying two given polynomials.
// You may find this function challenging to write. It is not
// trivial. Remember that every term in a must be multiplied by every
// term in b. You might find it useful to use foldLeft twice,
// but you may write the code any way you like as long as it
// obey functional programming principles, i.e., don't modify
// variables, and don't use mutable data structures.
// It may help to use a pencil and paper to multiply polynomials
// together to notice the pattern. Good luck!
def times(a:POLY,b:POLY):POLY = {
???
}
// this is the polynomial which when multiplied by any polynomial p,
// the result is p. I.e., times(one,p) ==> times(p,one) ==> p
val one:POLY = ???
// this is the polynomial which when added to any polynomial p,
// the result is p. I.e., plus(zero,p) ==> plus(p,zero) ==> p
val zero:POLY = ???
// raise a polynomial to a positive integer (or 0) power.
def power(a:POLY,pow:Int):POLY = {
assert(pow >= 0, s"power is not and should not be implemented for pow$pow")
// warning if pow = 100, don't try to do 99 calls to times,
// Hint x^(2n) = (x^n)^2, and x^(2n+1) = x * x^(2n), what is x^0 ?, what is x^1 ?
pow match {
case 1 => ???
case 0 => ???
case n if n % 2 == ??? =>
???
case n =>
???
}
}
// detect whether two polynomials are close enough to qualify
// as equal, i.e., their RMS is less than epsilon
def almostEqual(epsilon:Double)(a:POLY,b:POLY):Boolean = {
// RMS mean of difference
sqrt((a.keys ++ b.keys).foldLeft(0.0) { (acc, e) =>
val diff = a.getOrElse(e, 0.0) - b.getOrElse(e, 0.0)
diff * diff
}) < epsilon
}
def main(argv:Array[String]):Unit = {
()
}
}
// Copyright (c) 2020 EPITA Research and Development Laboratory
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package homework
import lecture.Calculus._
import math._
object TrapezoidIntegral {
def integralByTrapezoids(f:Double=>Double, left:Double, right:Double, test:(Double,Double)=>Boolean):Double = {
// To complete this function, I suggest you follow the pattern
// of the 'integral' function and 'sumRectangles' in Lecture-2-3-Calculus.scala
//
def sumTrapezoids(partitionWidth:Double): Double = {
// using foldLeft, calculate and return the sum of the areas