Russian peasant exponentiation using tail-recursive OCaml - ocaml

I tried the no tail recursion version of Russian Peasant exponentiation and it returned like this:
let rec fast_expNTR (base, power) =
match power with
|0->1
|n-> if n mod 2=0 then fast_expNTR (square base, power/2)
else base * fast_expNTR(square base , power/2)
But in else base*fast_expNTR(square base , power/2), it says expression is expected of type float but was given a type int. I don't understand the error.
Also, here is my attempt on tail-recursive fast exponentiation:
let fast_exp (base , power)=
let rec helper (acc ,acc2,p)=
if p=0 then acc * acc2
else if p mod 2 =0 then helper(int_of_float (square (float_of_int acc)),acc2, p/2)
else helper(int_of_float(square (float_of_int acc)),acc * acc2, p/2)
in helper(base,1,power)
But it didn't compute the correct result. Please help

Hint: Your function square has type float -> float and * is the integer multiplication.

Related

Haskell code to compute sum of squares of negative integers using foldr function

I am new to haskell code. I tried to compute the sum of squares of negative integer in a list using foldr high order.
sumsq :: Int -> Int
sumsq n = foldr op 0 [1..n]
where op x y = x*x + y
Please help to explain each line of code and give any solution if error in this code
When using "where", important to follow the indentation rule.
Here lambda will be appropriate
sumsq n = foldr (\x y -> x*x + y) 0 [1..n]

Standard ML: How to compute x to the power of i?

I am new to Standard ML. I am trying to compute x squared i, where x is a real and i is an non-negative integer. The function should take two parameters, x and i
Here is what I have so far:
fun square x i = if (i<0) then 1 else x*i;
The error that I am getting is that the case object and rules do not agree
The unary negation operator in SML is not - as it is in most languages, but instead ~. That is likely what is causing the specific error you cite.
That said, there are some other issues with this code. L is not bound in the example you post for instance.
I think you may want your function to look more like
fun square (x : real) 0 = 1
| square x i = x * (square x (i - 1))
You'll want to recurse in order to compute the square.

How to round up a real number to nth decimal in SML?

New to SML, trying to round up a real number to nth decimal, by declaring a function round(n,L), where L is a list of real numbers and n decide the nth decimal that can round up to.
My approach is to convert the real number to a string first, and then get the substring to the nth decimal and then parse the substring back to real number, this works fine if I only want to get the real number to nth decimal, but if I have a number like 0.3456 which I want to round to 0.35, my method won't really achieve that.
fun rd(_,[]) = []
|rd(a:int, x::y:real list) =
if x>0.0
then Option.getOpt(Real.fromString(String.substring(Real.toString(x),0,a+2)),0.0) :: rd(a,y)
else Option.getOpt(Real.fromString(String.substring(Real.toString(x),0,a+3)),0.0) :: rd(a,y)
The expected result is like this:
- rd (2, [0.1234, 0.2345, ~0.3456]);
val it = [0.12,0.23,~0.35] : real list`
But the actual output I got is
val it = [0.12,0.23,~0.34] : real list
If I want to round up the number, is there any good approach?
I've also tried this:
fun rd(_,[]) = []
|rd(a:int, x::y:real list) =
let
val n = real(round(x*Math.pow(10.0,real(a)))) / Math.pow(10.0,real(a))
in n::rd(a,y)
end;
but this solution will give me an uncaught exception overflow...
trying to round up a real number to nth decimal
declaring a function round(n,L), where L is a list of real numbers and n decide the nth decimal
Judging by your use of Math.pow(10.0,real(a)) in your second attempted solution, you seem to be on track. I don't understand where a list comes in; as Yawar points out, try and solve this for rounding a single real, and then apply that recursively (using map) to a list of reals.
So a function
fun roundN (x, n) = ...
fun roundManyN (xs, n) = map (fn x => roundN (x, n)) xs
Start by making some examples and encode them as tests. Since you can't compare real for equality in those tests, start by making (or copying) a custom equality operator.
fun nearlyEqual (a, b, eps) =
let val absA = Real.abs a
val absB = Real.abs b
val diff = Real.abs (a - b)
in Real.== (a, b) orelse
( if Real.== (a, 0.0) orelse
Real.== (b, 0.0) orelse
diff < Real.minNormalPos
then diff < eps * Real.minNormalPos
else diff / Real.min (absA + absB, Real.maxFinite) < eps )
end
val test_roundN_1 =
let val got = roundN (3.14159, 1)
val expected = 3.1
in nearlyEqual (got, expected, 0.1) end
val test_roundN_2 =
let val got = roundN (3.14159, 2)
val expected = 3.14
in nearlyEqual (got, expected, 0.01) end
(* rounding point *)
val test_roundN_3 =
let val got = roundN (3.14159, 3)
val expected = 3.142
in nearlyEqual (got, expected, 0.001) end
(* rounding point *)
val test_roundN_4 =
let val got = roundN (3.14159, 4)
val expected = 3.1416
in nearlyEqual (got, expected, 0.0001) end
val test_roundN_5 =
let val got = roundN (3.14159, 5)
val expected = 3.14159
in nearlyEqual (got, expected, 0.00001) end
You also have some edge cases that you eventually want to deal with:
When n is zero or negative, or when n is greater than the number of digits in the fraction.
When x is close to a rounding point, e.g. roundN (3.1451, 2) ~> 3.15.
When x·10ⁿ has a magnitude that exceeds the size of an int.
When n is so large that a magnitude change may affect the precision of a real.
For a better testing library, check out testlib.sml (and its use in test.sml) in this exercism exercise.
Extracting your second solution into a function, and giving Math.pow (10.0, real n) a temporary binding, you get the solution:
fun roundN (x, n) =
let val m = Math.pow(10.0, real n)
in real (round (x * m)) / m end
this solution will give me an uncaught exception overflow
On what input, I might ask.
One source could be that round : real -> int is a partial function: There are real values that cannot be expressed as int, such as Real.posInf, Real.negInf, 1e10 (on 32-bit SML) and 1e19 (on 64-bit SML). To avoid this, consider using Real.realRound : real -> real to avoid the int conversion.
One way to avoid errors related to x * Math.pow(10.0, real n) causing imprecision because the number grows too big, could be to strip the integer part before multiplying, and adding the integer part back after dividing.

Ocaml Product of two polynomials

How to compute the product of two polynomials ?
For example: x^3 + 3x^2 +0.2x and 2x^4 + 3
First I made a type
Type term = {coefficient:int; name:string; exponent:int};;
Type polynomials = term list;;
then I made a function calculate coefficient
let product l l' =
List.concat (List.map (fun e -> List.map (fun e' -> (e*e')) l'.coefficient)
l.coefficient);;
This is where I get stuck. I guess I can use the same function for exponent as well,but the question is asking writing a polynomials function with one param, which means two polynomials will be in the same variable
Can someone help me out here
You seem to be saying that you're asked to write a function to multiply two polynomials, but the function is supposed to have just one parameter. This, indeed, doesn't make a lot of sense.
You can always use a tuple to bundle any number of values into a single value, but there's no reason to do this (that I can see), and it's not idiomatic for OCaml.
Here's a function with one parameter (a pair) that multiplies two ints:
# let multiply (a, b) = a * b;;
val multiply : int * int -> int = <fun>
# multiply (8, 7);;
- : int = 56
(As a separate comment, the code you give doesn't compile.)

Why does the exponential operator use float variables in OCaml?

Why does the exponential operator use float variables in OCaml?
Shouldn't it allow int variables too?
# 3**3;;
Error: This expression has type int but an expression was expected of type
float
Works:
# 3.0**3.0;;
- : float = 27.
So, the existing answers go into how to get around this, but not into why it is the case. There are two main reasons:
1) OCaml doesn't have operator aliasing. You can't have two operators that do the "same thing", but to different types. This means that only one kind of number, integers or floats (or some other representation) will get to use the standard ** interface.
2) pow(), the exponentiation function has historically been defined on floats (for instance, in Standard C).
Also, for another way to get around the problem, if you're using OCaml Batteries included, there is a pow function defined for integers.
You can use int
let int_exp x y = (float_of_int x) ** (float_of_int y) |> int_of_float
There's a similar question: Integer exponentiation in OCaml
Here's one possible tail-recursive implementation of integer exponentiation:
let is_even n =
n mod 2 = 0
(* https://en.wikipedia.org/wiki/Exponentiation_by_squaring *)
let pow base exponent =
if exponent < 0 then invalid_arg "exponent can not be negative" else
let rec aux accumulator base = function
| 0 -> accumulator
| 1 -> base * accumulator
| e when is_even e -> aux accumulator (base * base) (e / 2)
| e -> aux (base * accumulator) (base * base) ((e - 1) / 2) in
aux 1 base exponent