...
 
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 { ...@@ -402,6 +402,7 @@ object MetroData {
("Étienne Marcel", 347, 412 )) ("Étienne Marcel", 347, 412 ))
val legData = List( // (source, destination, time-in-seconds) val legData = List( // (source, destination, time-in-seconds)
// source and destination are indices into stationPositions Array
(0, 238, 41 ), (0, 238, 41 ),
(0, 159, 46 ), (0, 159, 46 ),
(1, 12, 36 ), (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._
class TrapezoidIntegralTestSuite extends FunSuite {
test("faster double integral 1") {
assert(0.0 == fasterDoubleIntegral((x, y) => 0.0,
-1.0, -1.0, 1.0, 1.0,
_ == _))
}
test("faster double integral 2") {
assert(1.0 == fasterDoubleIntegral((x, y) => 1.0,
0.0, 0.0, 1.0, 1.0,
almostEqual(0.01)))
}
test("faster double integral 3") {
// taken from http://www.stankova.net/statistics_2012/double_integration.pdf
assert(almostEqual(0.01)(57.0, fasterDoubleIntegral((x: Double, y: Double) => 1 + 8 * x * y,
0.0, 1.0, 3.0, 2.0,
almostEqual(0.001))))
}
test("faster double integral 4") {
assert(almostEqual(0.1)(1.0, fasterDoubleIntegral((x, y) => x * y,
0.0, 0.0, 1.0, 2.0,
almostEqual(0.001))))
}
test("faster double integral 5") {
assert(almostEqual(0.01)(0.5, fasterDoubleIntegral((x, y) => y * sin(x),
0.0, 0.0, (Pi / 2), 1.0,
almostEqual(0.001))))
}
test("faster double integral 6") {
// example from https://mathinsight.org/double_integral_examples
assert(almostEqual(0.01)(2.0 / 3, fasterDoubleIntegral((x, y) => x * y * y,
0.0, 0.0, 2.0, 1.0,
almostEqual(0.0001))))
}
}