How to calculate a polynomial equation in haskell [closed] - haskell

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Basically I need to calculate a polynomial in haskell based on a value x, and the values of the coeficients need to be stored in a list of tupples.
So for example the polynomial f(x) = a·xn + a1·xn−1 + ... + an−1·x + an will be represented in a list of tuples like f = [(a0, n), (a1, n-1), ... , (an-1, 1), (an, 0)] , so if I want to calculate
2*x^2 + 3*x + 3 for x=20 I will need the list [(2,2), (3,1) , (0,3)].
Thanks a lot in advance and sorry if I explained this exercise in a messy way :)

If you want a basic solution, try using explicit recursion:
evaluate :: [(Int, Int)] -> Int -> Int
evaluate [] _x = .... -- TODO (1)
evaluate ((a,n) : rest) x = .... -- TODO (2)
where
result = evaluate rest x
Above, in (1) we need to specify what is the result of evaluating an "empty" polynomial (with no coefficients at all). This is the base case of our recursion.
Instead, (2) is the recursive step. Here, we split the coefficients-pairs into the first (a,n), and the rest of the list rest. We then recursively define result = evaluate rest x to evaluate the polynomial "without the first coefficient", that is a1·xn−1 + ... + an−1·x + an.
Then, in line (2) we need to combine this result with the first monomial, evaluated in x.
You should now be able to fill the dots.

Easy: just fold over the list. The accumulator function should add the current term (solved for x) to the accumulate. The seed needs to be 0, of course.

something like this
> peval p x = foldr (\(a,n) s -> s+(a*x^n)) 0 p
> poly = peval [(2,2),(3,1),(3,0)]
> map poly [0..5]
[3,8,17,30,47,68]

Related

Inverse of a pow(a,b,n) function in python decryption code [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
I am working on a python decryption code using an encryption code which is already available.
In the encrytpion code, I have
pow (b, xyz, abc)
A number gets encrypted and is passed onto an array.
Now while decrypting, i need to get the value of "b" (from the pow function above) as i have the value in Array.
Using modulus gives the values in range and not the exact value and that is needed for my decryption logic to work.
How to continue with this?
First you factorise 928108726777524737. It has 2 prime factors, call them P and Q.
Then you need to find a value d such that d * 65539 mod (P-1)(Q-1) == 1 (use the Extended Euclidian Algorithm for this).
Once you have done that then given c = pow (b, 65539, 928108726777524737) you can calculate back to b with pow(c, d, 928108726777524737)
To help you a bit more P=948712711, Q=978282167 giving d=872653594828486879
>>> c = pow(99, 65539, 928108726777524737)
>>> pow(c, 872653594828486879, 928108726777524737)
99
Of course in real life you would start with the prime factors and make them a lot larger than this in which case it would be impractical to reverse the process without already knowing the factors. For small values such as this is it is easy to factorise and calculate the inverse.
Calculation of d:
def egcd(a, b):
x,y, u,v = 0,1, 1,0
while a != 0:
q, r = b//a, b%a
m, n = x-u*q, y-v*q
b,a, x,y, u,v = a,r, u,v, m,n
gcd = b
return gcd, x, y
First find the prime factors:
>>> P, Q = 948712711, 978282167
>>> P*Q
928108726777524737
>>> egcd(65539, (P-1)*(Q-1))
(1, -55455130022042981, 3916)
We want the middle value x:
>>> gcd, x, y = egcd(65539, (P-1)*(Q-1))
But we have to make it positive which we can do by adding on the (P-1)*(Q-1) value:
>>> x + (P-1)*(Q-1)
872653594828486879

Recursive arithmetic sequence in Haskell

It's been nearly 30 years since I took an Algebra class and I am struggling with some of the concepts in Haskell as I work through Learn you a Haskell. The concept that I am working on now is "recursion". I have watched several youtube videos on the subject and found a site with the arithmetic sequence problem: an = 8 + 3(an-1) which I understand to be an = an-1 + 3 This is what I have in Haskell.
addThree :: (Integral a) => a -> a
addThree 1 = 8
addThree n = (n-1) + 3
Running the script yields:
addThree 1
8
addThree 2
4
addThree 3
6
I am able to solve this and similar recursions on paper, (after polishing much rust), but do not understand the syntax in Haskell.
My Question How do I define the base and the function in Haskell as per my example?
If this is not the place for such questions, kindly direct me to where I should post. I see there are Stack Exchanges for Super User, Programmers, and Mathematics, but not sure which of the Stack family best fits my question.
First a word on Algebra and you problem: I think you are slightly wrong - if we write 3x it usually means 3*x (Mathematicans are even more lazy then programmers) so your series indeed should look like an = 8 + 3*an-1 IMO
Then an is the n-th element in a series of a's: a0, a1, a2, a3, ... that's why you there is a big difference between (n-1) and addThree (n-1) as the last one would designate an-1 while the first one would just be a number not really connected to your series.
Ok, let's have a look at your series an = 8 + 3an-1 (this is how I would understand it - because otherwise you would have x=8+3*x and therefore just x = -4:
you can choose a0 - let's say it`s 0 (as you did?)
then a1=8+3*0 = 8
a2=8+3*8 = 4*8 = 32
a3=8+3*32 = 8+3*32 = 104
...
ok let's say you want to use recursion than the problem directly translates into Haskell:
a :: Integer -> Integer
a 0 = 0
a n = 8 + 3 * a (n-1)
series :: [Integer]
series = map a [0..]
giving you (for the first 5 elements):
λ> take 5 series
[0,8,32,104,320]
Please note that this is a very bad performing way to do it - as the recursive call in a really does the same work over and over again.
A technical way to solve this is to observe that you only need the previous element to get the next one and use Data.List.unfoldr:
series :: [Integer]
series = unfoldr (\ prev -> Just (prev, 8 + 3 * prev)) 0
now of course you can get a lot more fancier with Haskell - for example you can define the series as it is (using Haskells laziness):
series :: [Integer]
series = 0 : map (\ prev -> 8 + 3 * prev) series
and I am sure there are much more ways out there to do it but I hope this will help you along a bit

How to convert (0,0) to [0,0] in prolog?

I'm making a predicate distance/3 that calculates the distance between 2 points on a 2d plane. For example :
?- distance((0,0), (3,4), X).
X = 5
Yes
My predicate only works if (0,0) is the list [0,0]. Is there a way to make this conversion?
You can do this with a simple rule that unifies its left and right sides:
convert((A,B), [A,B]).
Demo.
Although the others have answered, keep in mind that (a,b) in Prolog is actually not what you might think it is:
?- write_canonical((a,b)).
','(a,b)
true.
So this is the term ','/2. If you are working with pairs, you can do two things that are probably "prettier":
Keep them as a "pair", a-b:
?- write_canonical(a-b).
-(a,b)
true.
The advantage here is that pairs like this can be manipulated with a bunch of de-facto standard predicates, for example keysort, as well as library(pairs).
Or, if they are actually a data structure that is part of your program, you might as well make that explicit, as in coor(a, b) for example. A distance in two-dimensional space will then take two coor/2 terms:
distance(coor(X1, Y1), coor(X2, Y2), D) :-
D is sqrt((X1-X2)^2 + (Y1-Y2)^2).
If you don't know how many dimensions you have, you can then indeed keep the coordinates of each point in a list. The message here is that lists are meant for things that can have 0 or more elements in them, while pairs, or other terms with arity 2, or any term with a known arity, are more explicit about the number of elements they have.
If you just have a simple pair, you can use the univ operator and simply say something like:
X = (a,b) ,
X =.. [_|Y] .
which produces
X = (a,b) .
Y = [a,b] .
This doesn't work if X is something like (a,b,c), producing as it does
X = (a,b,c) .
Y = [a,(b,c)] .
[probably not what you want].
The more general case is pretty simple:
csv2list( X , [X] ) :- % We have a list of length 1
var(X) . % - if X is UNbound
csv2list( X , [X] ) :- % We have a list of length 1
nonvar(X) , % - if X is bound, and
X \= (_,_) . % - X is not a (_,_) term.
cs22list( Xs , [A|Ys] ) :- % otherwise (the general case) ,
nonvar(Xs) , % - if X is bound, and
Xs = (A,Bs) , % - X is a (_,) term,
csv2list(Bs,Ys % - recurse down added the first item to result list.
. % Easy!

Generating triangular number using iteration in haskell

I am trying to write a function in Haskell to generate triangular number, I am not allowed to use recursion, I am supposed to use iteration
here is my code ...
triSeries 0 = [0]
triSeries n = take n $iterate (\x->(0+x)) 1
I know that my function after iterate is wrong .
But It has been hours looking for a function, any hint please?
Start by writing out some triangular numbers
T(1) = 1
T(2) = 1 + 2
T(3) = 1 + 2 + 3
An iterative process to generate T(n) is to start from [1..n], take the first element of the list, and add it to a running total. In a language with mutable state, you might write:
def tri(n):
sum = 0
for x in [1..n]:
sum += x
return sum
In Haskell, you can iteratively consume a list of numbers and accumulate state via a fold function (foldl, foldr, or some variant). Hopefully that's enough to get started with.
Maybe wikipedia could be a hint, where something like
triangular :: Int -> Int
triangular x = x * (x + 1) `div` 2
could be got from.
triSeries could be something like
triSeries :: Int -> [Int]
triSeries x = map triangular [1..x]
and works like that
> triSeries 10
[1,3,6,10,15,21,28,36,45,55]
Talking about iterate. Maybe there is some way to use it here, but as John said, foldl would be sufficient. Take a look at this page, what are you looking is in the very beginning.
It is not clear what is meant by "recursion is not allowed, use iteration". All functions that appear to be "iterative" are recursive inside.
iterate in all your uses can only modify the input with a constant, and iterate (+1) 1 is the same as [1..]. Consider using a Data.List function that can combine a number from infinite range [1..] and the previously computed sum to produce a infinite list of such sums:
T_i=i+T_{i-1}
This is definitely cheaper than x*(x+1) div 2
Consider using a Data.List function that can produce an infinite list of finite lists of sums from a infinite list of sums. This is going to be cheaper than computing a list of 10, then a list of 11 repeating the same computation done for the list of 10, etc.

Finding Shortest Distance Between Two Parallel Lines, With Arbitrary Point [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I need to write a reliable method to retrieve the answer to the following scenario...
Given a line segment AB and an arbitrary point C, how would I find the closest point to A on a line parallel to AB that passes through point C? (Reliable mentioned above refers to the algorithms ability to find D while allowing the coordinates for A, B, and C to be completely arbitrary and unpredictable. I've ran in to a quite a few solutions that I was not able to adapt to all possible scenarios, sadly...)
In the case of the data displayed in the picture below, how would I reliably find the x,y coordinates of D?
A = <425, 473>
B = <584, 533>
C = <371, 401>
D = <???, ???>
Knowing that AB and CD are parallel, that obviously means the slopes are the same.
I have tried many different formulas to no avail and have been working on this for weeks now. I'm stumped!
It's a minimization problem.
In general, the Euclidean distance between two points (A and B) in N dimensional space is given by
Dist(A,B) = sqrt((A1-B1)^2 + ... + (AN-BN)^2)
If you need to find the minimum distance between a space curve A(t) (a 1-dimensional object embedded in some N dimensional space) and a point B, then you need to solve this equation:
d Dist(A(t),B) / dt = 0 // (this is straightforward calculus: we're at either a minimum or maximum when the rate of change is 0)
and test that set of roots (t1, t2, etc) against the distance function to find which one yields the smallest value of D.
Now to find the equation for the parallel line passing through C in y=mx+b form:
m = (Ay - By)/(Ax-Bx)
b = Cy - mCx
Let's write this in space-curve form as and plug it into our formula from part 1:
Dist(D(t),A) = sqrt((t-Ax)^2 + (m*t+b-Ay)^2)
taking our derivative:
d Dist(D(t),A)/ dt = d sqrt((t-Ax)^2 + (m*t+b-Ay)^2) / dt
= (t + (m^2)*t - Ax + m*b - m*Ay)/sqrt(t^2 + (m^2)t^2 - 2*t*Ax + 2*m*t*b - 2*m*t*Ay + (Ax)^2 + (Ay)^2 + b^2 - 2*b*Ay )
= ((1+m^2)*t - Ax + m*b - m*Ay)/sqrt((1+m^2)*(t^2) + 2*t*(m*b - Ax - m*Ay) + (Ax)^2 + (Ay)^2 + b^2 - 2*b*Ay )
Settings this equal to 0 and solving for t yields:
t = (Ax-m*b+m*Ay)/(1+m^2)
as the only root (you can check this for yourself by substituting back in and verifying that everything cancels as desired).
Plugging this value of t back in to our space curve yields the following:
D=<(Ax-m*b+m*Ay)/(1+m^2),b+m*(Ax-m*b+m*Ay)/(1+m^2)>
You can then plug in your expressions for m and b if you want an explicit solution in terms A,B,C, or if you only want the numerical solution you can just compute it as a three step process:
m = (Ay - By)/(Ax-Bx)
b = Cy - mCx
D=<(Ax-m*b+m*Ay)/(1+m^2),b+m*(Ax-m*b+m*Ay)/(1+m^2)>
This will be valid for all cases with parallel straight lines. One caveat when implementing it as a numerical (rather than analytical) code: if the lines are oriented vertically, calculating m = (Ay-By)/(Ax-Bx) will result in division by 0, which will make your code not work. You can throw in a safety valve as follows:
if( Ax == Bx) {
D = <Cx,Ay>
} else {
// normal calculation here
}
For serious numerical work, you probably want to implement that in terms of tolerances rather than a direct comparison due to roundoff errors and all that fun stuff (i.e., abs(Ax-Bx) < epsilon, rather than Ax==Bx)

Resources