...
 
Commits (12)
// 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
// of as many trapezoids as possible each having a width (delta-x) of partitionWidth.
// You must figure out how to compute the area of one trapezoid whose
// bottom two corners lie on the x-axis, and whose top two corners
// lie on the curve y=f(x) and whose width in the x direction is partitionWidth.
???
}
if (right == left)
??? // follow example from integral in in Lecture-2-3-Calculus.scala
else if (right < left)
-1 * integralByTrapezoids(???,???,???,???) // follow example from integral in in Lecture-2-3-Calculus.scala
else
limit(???,???,???)(???) // follow example from integral in in Lecture-2-3-Calculus.scala
}
def fasterDoubleIntegral(f:(Double,Double)=>Double,
xmin:Double, ymin:Double, xmax:Double, ymax:Double,
test:(Double,Double)=>Boolean):Double = {
def single(x:Double):Double = {
integralByTrapezoids(y => f(x,y),???,???,???) // follow example from slowDoubleIntegral which you implemented earlier
}
integralByTrapezoids(single,???,???,???) // follow example from slowDoubleIntegral which you implemented earlier
}
def main(argv:Array[String]) = {
}
}
import scala.math._
// find a root of the given function within the given range
def binSearch(left:Double,right:Double,f:Double=>Double,epsilon:Double):Double = {
// assume f(left) <=0 and f(right) >=0
val m = (left + right) / 2
val fm = f(m)
if (abs(fm) < epsilon)
m
else if (fm < 0)
binSearch(m,right,f,epsilon)
else
binSearch(left,m,f,epsilon)
}
binSearch(-Pi/10, Pi/20, sin, .0001)
import scala.math._
// find a root of the given function within the given range
def binSearch(left:Double,right:Double,f:Double=>Double,epsilon:Double):Option[Double] = {
// assume f(left) <=0 and f(right) >=0
def recur(left:Double,right:Double):Double = {
val m = (left + right) / 2
val fm = f(m)
if (abs(fm) < epsilon)
m
else if (fm < 0)
recur(m, right)
else
recur(left, m)
}
if (f(left) <=0 && f(right) >=0)
Some(recur(left,right))
else if (f(left) >=0 && f(right) <=0)
Some(recur(right,left))
else
None
}
binSearch(-Pi/10, Pi/20, sin, 0.0001)
binSearch(-Pi/10, Pi/20, cos, 0.0001)
binSearch(-10.0,10.0,x=>10-x*x*x,0.0001)
import scala.math._
// find a root of the given function within the given range
def binSearch(left:Double,right:Double,f:Double=>Double,epsilon:Double,maxDepth:Int):Option[Double] = {
def recur(left:Double,right:Double,depth:Int):Option[Double] = {
val m = (left + right) / 2
val fm = f(m)
if (depth >= maxDepth)
None
else if (abs(fm) < epsilon)
Some(m)
else if (fm < 0)
recur(m, right,depth+1)
else
recur(left, m,depth+1)
}
if (f(left) <=0 && f(right) >=0)
recur(left,right,0)
else if (f(left) >=0 && f(right) <=0)
recur(right,left,0)
else
None
}
binSearch(-Pi/10, Pi/20, sin, 0.0001,32)
binSearch(-Pi/10, Pi/20, cos, 0.0001,32)
binSearch(-10.0,10.0,x=>10-x*x*x,0.0001,32)
import scala.math._
def almostEqual(epsilon:Double)(a:Double,b:Double):Boolean = {
abs(a-b) < epsilon
}
def limit(f:Double=>Double,dx:Double,test:(Double,Double)=>Boolean)(a:Double):Double = {
def recur(dx:Double):Double = {
val f1 = f(a + dx)
val f2 = f(a + dx / 2)
if (test(f1,f2))
f2
else
recur(dx / 2)
}
recur(dx)
}
def derivative(f:Double=>Double,dx:Double,test:(Double,Double)=>Boolean)(x:Double):Double = {
def estimate(h:Double):Double = {
(f(x+h) - f(x) ) / h
}
limit(estimate,dx:Double,test)(0)
}
val cos_est:Double=>Double = derivative(sin,0.01,almostEqual(0.000001)) // cos
val poly_est:Double=>Double = derivative(x => x*x + 3*x + 1,0.01,almostEqual(0.00001)) // 2*x + 3
for {n <- 0 to 20
x = -Pi + n * 2 * Pi / 20
c1 = cos(x)
c2 = cos_est(x)
delta = c1 - c2
} println(s"$x delta= $delta")
//derivative(sin)(Pi/2)
//derivative(x => x*x + 3*x + 1)(1)
\ No newline at end of file
def fixedPoint[A](h: A => A, x0: A): A = {
val v = h(x0)
if (x0 == v)
x0
else
fixedPoint(h, v)
}
def g3(data: List[Char], open: Char, close: Char): List[Char] = {
def recur(data: List[Char], acc: List[Char]): List[Char] = {
data match {
case op :: cl :: tail =>
if (op == open && cl == close)
recur(tail, acc)
else
recur(cl :: tail, op :: acc)
case _ => (data ++ acc).reverse
}
}
recur(data, List())
}
def g(data: List[Char]): List[Char] = {
g3(data, '(', ')')
}
def f(data: String): String = {
g(data.toList).mkString
}
f(f(f(")()x((z))((())())y(")))
f("x")
g(")()x((z))((())())y(".toList)
fixedPoint(f, ")()x((z))((())())y(")
fixedPoint(g, ")()x((z))((())())y(".toList)
fixedPoint( g3(_,'(',')'),
")()x((z))((())())y(".toList)
fixedPoint( g3(_,'[',']'),
"][]x[[z]][[[]][]]y[".toList).mkString
import scala.math._
import lecture.MetroData._
//stationPositions
//stationPositions.map(triple => triple._1)
//stationPositions.map(triple => triple._1).distinct
//
//stationPositions.map(triple => triple._1)
// .distinct
// .filter(name => ! name.toList.contains(' '))
stationPositions.filter(triple => triple._2 > 300)
.map(_._1)
stationPositions.toList
.filter(triple => triple._2 > 300)
.splitAt(3)
import scala.math._
def almostEqual(epsilon:Double)(a:Double,b:Double):Boolean = {
abs(a-b) < epsilon
}
def limit(f:Double=>Double,dx:Double,test:(Double,Double)=>Boolean)(a:Double):Double = {
def recur(dx:Double):Double = {
val f1 = f(a + dx)
val f2 = f(a + dx / 2)
if (test(f1,f2))
f2
else
recur(dx / 2)
}
recur(dx)
}
def derivative(f:Double=>Double,dx:Double,test:(Double,Double)=>Boolean)(x:Double):Double = {
def estimate(h:Double):Double = {
(f(x+h) - f(x) ) / h
}
limit(estimate,dx:Double,test)(0)
}
def integral(f:Double=>Double,left:Double,right:Double,test:(Double,Double)=>Boolean):Double = {
def sumRectangles(partitionWidth: Double): Double = {
val numPartitions = ((right - left) / partitionWidth).floor.toInt
(1 to numPartitions).foldLeft(0.0)( (acc, i) => acc + f(left + i * partitionWidth) * partitionWidth )
}
//limit(sumRectangles,(right - left)/2,test)(0)
if (right == left)
0.0
else if (right < left)
- integral(f, right, left, test)
else
limit(sumRectangles,(right - left)/2,test)(0)
}
for {n <- 0 to 20
x = -Pi + n * 2 * Pi / 20
s1 = sin(x)
s2 = integral(cos,0,x,almostEqual(0.00001))
delta = s1 - s2
} println(s"$x delta= $delta")
def doubleRange(lower:Double, upper:Double, steps:Int) = {
val step = (upper - lower)/steps
for { i <- (0 to steps).view
x = lower+ i*step
} yield x.min(upper)
}
(for {x <- doubleRange(-Pi, Pi, 21)
c = cos(x)} println(s"x=$x cos(x)=$c"))
import scala.math._
def limit4(f:Double=>Double,dx:Double,dy:Double,a:Double):Double = {
val f1 = f(a + dx)
val f2 = f(a + dx / 2)
if (abs(f1 - f2) < dy)
f2
else
limit4(f, dx / 2, dy, a)
}
limit4(cos,0.1,0.0001,0.0)
limit4(sin,0.1,0.0001,0.0)
limit4(cos,0.1,0.00001,Pi/4)
def limit(dx: Double, dy: Double) = {
limit4(_,dx,dy,_)
}
val limit2a = limit(0.1, 0.0001)
val limit2b = limit(0.1, 0.000001)
val limit2c = limit(0.1, 0.00000001)
limit2a(sin , Pi)
limit2b(sin , Pi)
limit2c(sin , Pi)
def f(x:Double):Double = {
(x * x - 1) / (x - 1)
}
f(0)
f(0.999999)
limit2c(f,1.0)
\ No newline at end of file
import scala.math._
def almostEqual(epsilon:Double)(a:Double,b:Double):Boolean = {
abs(a-b) < epsilon
}
def limit(f:Double=>Double,dx:Double,test:(Double,Double)=>Boolean)(a:Double):Double = {
def recur(dx:Double):Double = {
val f1 = f(a + dx)
val f2 = f(a + dx / 2)
if (test(f1,f2))
f2
else
recur(dx / 2)
}
recur(dx)
}
limit(cos,0.1, almostEqual(0.0001))( 0.0)
limit(sin,0.1, almostEqual(0.0001))( 0.0)
limit(cos,0.1, almostEqual(0.00001))( Pi/4)
val limit2a:(Double=>Double,Double)=>Double = limit(_,0.1, almostEqual(0.0001))(_)
val limit2b = limit(_,0.1, almostEqual(0.0001)) _
val limit2c:(Double=>Double,Double)=>Double = limit(_,0.1, almostEqual(0.000001))(_)
val limit2d:(Double=>Double,Double)=>Double = limit(_,0.1, almostEqual(0.00000001))(_)
limit2a(sin , Pi)
limit2b(sin , Pi)
limit2c(sin , Pi)
def f(x:Double):Double = {
(x * x - 1) / (x - 1)
}
f(0)
f(0.999999)
limit2c(f,1.0)
\ No newline at end of file
import lecture.Polynomial._
Map(1->1, 2->1, 3->3).keys
// 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.
import homework.BinarySearch._
import lecture.BinarySearch._
import org.scalatest.FunSuite
import scala.math._
class BinarySearchTestSuite extends FunSuite {
def almostEqual(tolerance:Double)(x:Double, y:Double):Boolean = {
abs(x - y ) <= tolerance
}
test("tolerance") {
assert(almostEqual(0.0)(1.0, 1.0))
assert(almostEqual(0.5)(1.1, 1.2))
assert(almostEqual(0.5)(100.1, 100.2))
assert(almostEqual(0.1)(1000.01, 1000.05))
assert(!almostEqual(0.01)(0.001, 0.101))
}
test("bin search") {
assert(None != binSearch(-1.5, 1.0, sin, 0.0001, 20))
assert(None != binSearch(-1.0, 1.0, sin, 0.000001, 30))
// given function does not equal 0.0 in the given interval
assert(None == binSearch(1.0, 2.0, (x: Double) => 3.0, 0.001, 20))
assert(None != binSearch(-1.0, 1.0, sin, 0.1, 0.0001, 20))
// interval reversed
assert(None != binSearch(1.0, -1.0, sin, 0.1, 0.0001, 20))
// given function does not equal 20.3 in the given interval
assert(None == binSearch(1.0, -1.0, sin, 20.3, 0.001, 20))
// not enough iterations allowed
assert(None == binSearch(-0.9, 0.72, sin, 0.000001, 2))
}
test("boolean search") {
def optionAlmostEqual(test: (Double, Double) => Boolean): (Option[Double], Option[Double]) => Boolean = {
(op1, op2) => {
(op1, op2) match {
case (None,None) => true
case (Some(a), Some(b)) => test(a, b)
case _ => false
}
}
}
def ae(delta: Double): (Option[Double], Option[Double]) => Boolean = {
optionAlmostEqual(almostEqual(delta))
}
// check for maxDepth exceeded
assert(None == binSearchByBoolean(0.0, 100.0, _>= 5.0, 0.01, 3))
assert(ae(0.1)(None,binSearchByBoolean(0.0, 100.0, _>= 5.0, 0.01, 2)))
// check for successfully finding the switching point
assert(ae(0.1)(Some(3.4), binSearchByBoolean(0.3, 52.1, _ > 3.4, 0.01, 1000)))
// check for no such result in range
assert(None == binSearchByBoolean(10.0, 20.0, _ > 3.4, 0.01, 100))
}
}
// 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.
import homework.DoubleIntegral._
import lecture.Calculus.almostEqual
import org.scalatest.FunSuite
import scala.math._
class DoubleIntegralTestSuite extends FunSuite {
test("slow double integral 1") {
assert(0.0 == slowDoubleIntegral((x, y) => 0.0,
-1.0, -1.0, 1.0, 1.0,
_ == _))
}
test("slow double integral 2") {
assert(1.0 == slowDoubleIntegral((x, y) => 1.0,
0.0, 0.0, 1.0, 1.0,
almostEqual(0.01)))
}
test("slow double integral 3") {
// taken from http://www.stankova.net/statistics_2012/double_integration.pdf
assert(almostEqual(0.01)(57.0, slowDoubleIntegral((x: Double, y: Double) => 1 + 8 * x * y,
0.0, 1.0, 3.0, 2.0,
almostEqual(0.001))))
}
test("slow double integral 4") {
assert(almostEqual(0.1)(1.0, slowDoubleIntegral((x, y) => x * y,
0.0, 0.0, 1.0, 2.0,
almostEqual(0.001))))
}
test("slow double integral 5") {
assert(almostEqual(0.01)(0.5, slowDoubleIntegral((x, y) => y * sin(x),
0.0, 0.0, (Pi / 2), 1.0,
almostEqual(0.001))))
}
test("slow double integral 6") {
// example from https://mathinsight.org/double_integral_examples
assert(almostEqual(0.01)(2.0 / 3, slowDoubleIntegral((x, y) => x * y * y,
0.0, 0.0, 2.0, 1.0,
almostEqual(0.0001))))
}
}
// 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.
import homework.FixedPoint._
import lecture.Calculus.almostEqual
import org.scalatest.FunSuite
class FixedPointTestSuite extends FunSuite {
test("fixed point") {
assert(almostEqual(0.01)(5.0, squareRoot(25.0)))
}
}
// 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.
import homework.Gradient._
import lecture.Calculus.almostEqual
import org.scalatest.FunSuite
import scala.math._
class GradientTestSuite extends FunSuite {
def ae(z1:(Double,Double),z2:(Double,Double)):Boolean = {
val (x1,y1) = z1
val (x2,y2) = z2
almostEqual(0.001)(x1, x2) && almostEqual(0.001)(y1,y2)
}
test("gradient"){
assert((0.0,0.0) == gradient((x:Double,y:Double)=>0.0, 0.1, almostEqual(0.001), 3.0, 4.0))
assert(ae((1.0,1.0),gradient((x:Double,y:Double)=>x+y, 0.1, almostEqual(0.001), 3.0, 4.0)))
def f1(x:Double,y:Double) = x*x+y
assert(ae((4.0,1.0), gradient((x:Double,y:Double)=>(x*x+y), 0.01, almostEqual(0.0001), 2.0, 0.0)))
def f2(x:Double,y:Double):Double = x*x + y*y*y
assert(ae((2.0,12.0), gradient(f2, 0.1, almostEqual(0.001), 1.0,2.0)))
def f3(x:Double,y:Double):Double = x*cos(y) + y*sin(x)
assert(ae((1.0,0.0),gradient(f3,0.1,almostEqual(0.0001),0.0,0.0)))
}
}
// 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.
import homework.LimitAtDiscontinuity._
import lecture.Calculus.almostEqual
import org.scalatest._
class LimitAtDiscontinuityTestSuite extends FunSuite {
test("limit at discontinuity"){
assert(almostEqual(0.0015)(4.0, evalLimitAtDiscontinutiy()))
}
}
// 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.
import org.scalatest.FunSuite
import lecture.Polynomial._
import scala.math._
class PolynomialTestSuite extends FunSuite {
import lecture.Polynomial._
val polynomials: Array[POLY] = Array(one,
zero,
Map(0 -> 3, 1 -> 0.1, 2 -> -0.5),
Map(1 -> 1.0, 2 -> 2.0),
Map(2 -> -2.0, 3 -> 0.125, 1 -> 1.0),
Map(2 -> -2.1, 3 -> 0.125, 1 -> 1.0, 0 -> -0.5),
Map(2 -> -2.2, 3 -> 0.125, 1 -> 1.0),
Map(2 -> -2.3, 3 -> 0.125, 1 -> 1.0, 0 -> -0.25),
Map(2 -> -2.4, 3 -> 0.125, 1 -> 1.0),
Map(2 -> -2.3, 3 -> 0.125, 1 -> -0.5, 0 -> -0.25))
val xs: Array[Double] = Array(1.0, 0.5, 0.25, -0.8, 0.75)
test("evaluate") {
for {p <- polynomials
x <- xs}
evaluate(p, x)
for {x <- xs}
assert(abs(evaluate(Map(2 -> 1), x) - x * x) < 0.001, "x=$x n=$n")
for {n <- 0 to 10
x <- xs}
assert(abs(evaluate(Map(n -> 1), x) - pow(x, n)) < 0.001, "x=$x n=$n")
for {x <- xs
c1 <- List(0.5, 0.25)
c2 <- List(0.5, 0.25)
y = c1 * pow(x, 3) + c2 * pow(x, 2) - 1.0
p = Map(3 -> c1, 2 -> c2, 0 -> -1.0)}
assert(abs(y - evaluate(p, x)) < 0.0001)
for {x <- xs} assert(1.0 == evaluate(one, x))
for {x <- xs} assert(0.0 == evaluate(zero, x))
}
test("plus") {
for {p1 <- polynomials
p2 <- polynomials
} plus(p1, p2)
// check commutativity
for {p1 <- polynomials
p2 <- polynomials
} assert(almostEqual(0.001)(plus(p1, p2), plus(p2, p1)))
// check associativity
for {p1 <- polynomials
p2 <- polynomials
p3 <- polynomials
} assert(almostEqual(0.001)(plus(plus(p1, p2),p3), plus(p1,plus(p2, p3))))
for {x <- xs
p1 <- polynomials
p2 <- polynomials
p12 = plus(p1, p2)
p1x = evaluate(p1, x)
p2x = evaluate(p2, x)
p12x = evaluate(p12, x)
} assert(abs(p1x + p2x - p12x) < 0.0001, s"p1=$p1 p2=$p2 p12=$p12 x=$x p1x=$p1x p2x=$p2x p12x=$p12x")
}
test("scale") {
for {p <- polynomials
s <- Array(0.0, 1.0, -1.0, 0.5, 0.25, 0.125)
} scale(s, p)
for {p <- polynomials
s <- Array(0.0, 1.0, -1.0, 0.5, 0.25, 0.125)
x <- xs
spx = evaluate(scale(s,p),x)
px = evaluate(p,x)
} assert(abs(spx - s*px) < 0.0001)
}
test("subtract") {
for {p1 <- polynomials
p2 <- polynomials
} subtract(p1, p2)
for {x <- xs
p1 <- polynomials
p2 <- polynomials
p12 = subtract(p1, p2)
p1x = evaluate(p1, x)
p2x = evaluate(p2, x)
p12x = evaluate(p12, x)
} assert(abs(p1x - p2x - p12x) < 0.0001, s"p1=$p1 p2=$p2 p12=$p12 x=$x p1x=$p1x p2x=$p2x p12x=$p12x")
for {p1 <- polynomials
p2 <- polynomials
p12a = subtract(p1, p2)
p12b = plus(p1,scale(-1.0,p2))
} assert(almostEqual(0.0001)(p12a,p12b))
}
test("times") {
for {p1 <- polynomials
p2 <- polynomials
} times(p1, p2)
// check commutativity
for {p1 <- polynomials
p2 <- polynomials
} assert(almostEqual(0.001)(times(p1, p2), times(p2, p1)))
// check associativity
for {p1 <- polynomials
p2 <- polynomials
p3 <- polynomials
} assert(almostEqual(0.001)(times(times(p1, p2),p3), times(p1,times(p2, p3))))
for {x <- xs
p1 <- polynomials
p2 <- polynomials
p12 = times(p1, p2)
p1x = evaluate(p1, x)
p2x = evaluate(p2, x)
p12x = evaluate(p12, x)
} assert(abs(p1x * p2x - p12x) < 0.0001, s"p1=$p1 p2=$p2 p12=$p12 x=$x p1x=$p1x p2x=$p2x p12x=$p12x")
}
test("one") {
for {p <- polynomials
} assert(almostEqual(0.0001)(p, times(one, p)))
for {p <- polynomials
} assert(almostEqual(0.0001)(p, times(p,one)))
}
test("zero") {
for {p <- polynomials
} assert(almostEqual(0.0001)(p, plus(zero, p)))
for {p <- polynomials
} assert(almostEqual(0.0001)(p, plus(p,zero)))
for {p <- polynomials
} assert(almostEqual(0.0001)(zero, times(zero, p)))
for {p <- polynomials
} assert(almostEqual(0.0001)(zero, times(p,zero)))
}
test("power") {
for {n <- 1 to 20}
assert(almostEqual(0.0001)(zero, power(zero, n)), s"zero to any positive power ($n) should be zero")
for {n <- 1 to 20}
assert(almostEqual(0.0001)(one, power(one, n)), "one to any positive power should be 1")
for {p <- polynomials}
assert(almostEqual(0.0001)(one, power(p, 0)), "one raised to zero should be one")
for {p <- polynomials}
assert(almostEqual(0.0001)(p, power(p, 1)), "p raised to one should be p")
for {x <- xs
poly <- polynomials
n <- 0 to 4
p1 = power(poly, n)
polyx = evaluate(poly, x) // Double
p1x = evaluate(p1, x) // Double
polyxn = pow(polyx, n) // Double
} assert(abs(p1x - polyxn) < 0.0001, s"poly=$poly n=$n x=$x")
}
}
// 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.
import homework.TrapezoidIntegral._
import lecture.Calculus.almostEqual
import org.scalatest.FunSuite
import scala.math._