Cubic Polynomial in Python - python-3.x

For my latest project in my coding class (python), we need to program and compute a cubic function. So something like 3x^3+2x^2+7x+1. I cannot figure out how to code in the different x powers. I know this is a very simple question, but I can't find what I am looking for on the internet and have searched. How would I write out this polynomial given the 3,2,7 & 1 values? I assume I need to use numpy but can only figure that out with a degree one polynomial.

powers can be represented with ** in python (there is also a more sophisticated pow) function:
def f(x):
return 3*x**3 + 2*x**2 + 7*x + 1
(in python ^ is the xor operator; if you use your expression python would not complain but just not calculate what you want)
if you need to be able to do symbolic math, i suggest you install the sympy package:
from sympy import symbols
def f(x):
return 3*x**3 + 2*x**2 + 7*x + 1
x = symbols('x')
print(f(x)) # 3*x**3 + 2*x**2 + 7*x + 1
print(f(x).subs(x, 5)) # 461

You can also create a custom function like this example:
def cubic(x, args):
args_len = len(args)
for k in args:
yield k * x ** (args_len-1)
args_len -=1
Demo:
user_input = [3, 2, 7, 1]
user_var_x = 1
somme = sum(cubic(user_var_x, user_input))
print(somme)
Output:
13

Related

Converting Python iterative function to recursive function

Please consider 2 crossed suites:
U0 = 1
V0 = 2
Un = 2U(n-1) + 3 V(n-1)
Vn = U(n-1) + V(n-1)
I want to resolve it with this Python iterative function:
def myfunction(n=5):
u = 1
v = 2
for i in range(n):
w = u
u = 2*u + 3*v
v = w + v
return(u,v)
I would prefer a recursive function but I have no idea to convert my function.
Do you have any idea?
Thanks.
As simple as:
def u(n):
if n == 0:
return 1
else:
return 2*u(n-1) + 3*v(n-1)
def v(n):
if n == 0:
return 2
else:
return u(n-1) + v(n-1)
print((u(5), v(5))) # -> (905, 393)
This is possible due to the nature of Python being an interpreted dynamic programing language.
Edit:
def myfunction(n):
def u(n):
if n == 0:
return 1
else:
return 2*u(n-1) + 3*v(n-1)
def v(n):
if n == 0:
return 2
else:
return u(n-1) + v(n-1)
return u(n), v(n)
print(myfunction(5)) # -> (905, 393)
Just to conform with your exact problem/function.
The naive recursive implementation proposed by #moctarjallo is very slow because the same values have to be calculated over and over again. For example, calculating u(22) takes the ridiculous 0.8 sec:
from timeit import timeit
timeit('u(22)', globals=globals(), number=10)
# 8.138428802136332
Consider using an lru_cache decorator that saves the previously computed values in an invisible table and actually calls the functions only when they have not been called with the same parameters before:
from functools import lru_cache
#lru_cache(None) # decorate with a cache
def fast_u(n):
return 1 if not n else 2 * fast_u(n-1) + 3 * fast_v(n-1)
#lru_cache(None) # decorate with a cache
def fast_v(n):
return 2 if not n else fast_u(n-1) + fast_v(n-1)
timeit('fast_u(22)',globals=globals(), number=10)
#9.34056006371975e-05
I also made the functions code a little more idiomatic. Enjoy the difference!
P.S. If you are looking for a one-function implementation:
def uv(n):
if n == 0: return 1, 2
u, v = uv(n-1)
return 2 * u + 3 * v, u + v
uv(5)
#(905, 393)
Caching still improves its performance by orders of magnitude.

Randomizing logic in python using enumerate [duplicate]

This question already has answers here:
A weighted version of random.choice
(28 answers)
Closed 1 year ago.
Need to write a program using Randomizing logic(Python). It can be like a generic function which takes versions and probability as input and returns a version. Probability can be anything like 1/2,1/3,1/4,1/5 and versions should be equally distributed accordingly
Python has a built-in random library that has a choice function that can do exactly what you want.
import random
My_choice = random.choices(population, weights=None, cum_weights=None, k=1)
The value of the weights may be used to build a non-uniform probability density function. and cum_weights can be used to make a uniform probability with the sum of all weights.
You can read more about the random modules in their documentation.
from random import randint
def random_version_generator(no_of_version):
"""
As we have only 4 versions of template currently limiting with the
validation and returning version 1
"""
if no_of_version > 4:
return 1
r =randint(0,100)
propability_per_version = [100 // no_of_version + int(x < 100 % no_of_version)for x in range(no_of_version)]
for idx, i in enumerate(range(len(propability_per_version))):
if r <= propability_per_version[i]:
return idx + 1
elif r <= propability_per_version[i] + propability_per_version[i+1]:
return idx + 2
elif r <= propability_per_version[i] + propability_per_version[i+1] + propability_per_version[i+1]:
return idx + 3
else:
return idx + 4
You can get more about randomizing logic here https://www.geeksforgeeks.org/write-a-function-to-generate-3-numbers-according-to-given-probabilities/
To Know Regarding enumerate click here https://www.geeksforgeeks.org/enumerate-in-python/

Different Result when calculating Polepairs with Octave vs Python

I am trying to calculate pole pairs with both Octave 5.1.10 and Python 3.8.
The Octave code:
wc=1
n=4
s={n}
G=1
function poles (n, wc, G)
s={n}
for k =1:n
s{k}=wc*e^((j*(2*k+n-1)*pi)/(2*n))
endfor
endfunction
The ouput is:
s =
{
[1,1] = -0.38268 + 0.92388i
[1,2] = -0.92388 + 0.38268i
[1,3] = -0.92388 - 0.38268i
[1,4] = -0.38268 - 0.92388i
}
The Python code:
import numpy as np
import math
wc=1
n=4
G=1
def poles (n, wc, G):
import math
s=[] #contains the complex polpairs
e=math.e
pi=math.pi
for k in range(n):
s.append(wc*e**((1j*(2*k+n-1)*pi)/(2*n)))
return s
returns
s=[
(0.38268343236508984 + 0.9238795325112867j),
(-0.3826834323650897 + 0.9238795325112867j),
(-0.9238795325112867 + 0.3826834323650899j),
(-0.9238795325112868 - 0.38268343236508967j)]
Can someone explain to me why these two outputs are different?
In your octave loop, k takes values from 1 to 4.
In your python loop, k takes values from 0 to 3
If you want the same behaviour in your python loop, change
for k in range(4):
to
for k in range(1, 5):

Finding a Dot Product without using np.dot or loops in Python

I need to write a function which:
Receives - two numpy.array objects
Returns - the floating-point dot product of the two input
numpy arrays
Not allowed to use:
numpy.dot()
loops of any kind
Any suggestions?
A possible solution makes use of recursion
import numpy as np
def multiplier (first_vector, second_vector, size, index, total):
if index < size:
addendum = first_vector[index]*second_vector[index]
total = total + addendum
index = index + 1
# ongoing job
if index < size:
multiplier(first_vector, second_vector, size, index, total)
# job done
else:
print("dot product = " + str(total))
def main():
a = np.array([1.5, 2, 3.7])
b = np.array([3, 4.3, 5])
print(a, b)
i = 0
total_sum = 0
# check needed if the arrays are not hardcoded
if a.size == b.size:
multiplier(a, b, a.size, i, total_sum)
else:
print("impossible dot product for arrays with different size")
if __name__== "__main__":
main()
Probably considered cheating, but Python 3.5 added a matrix multiply operator that numpy uses to compute the dot product without actually calling np.dot:
>>> arr1 = np.array([1,2,3])
>>> arr2 = np.array([3,4,5])
>>> arr1 # arr2
26
Problem solved!

AttributeError: module 'sympy' has no attribute 'polys'

I'm encountering some problems using sympy, here is my code:
from sympy import integrate as inter
import sympy as sp
from sympy import symbols
def f(x):
f1 = (sp.exp(-x ** 2)) / (1 + x ** 2)
f2 = (2 * (sp.cos(x)) ** 2) / (1 + (x - 4) ** 2)
f = f1 + f2
return(f)
def integrate_f_from0(b):
x = symbols('x')
a = inter(f(x), (x, 0, b))
return(a)
The error I get upon running the integrate_f_from0 function is:
AttributeError: module 'sympy' has no attribute 'polys'
What is causing this error?
In SymPy 1.1.1 your code works as expected: integrate_f_from0(3) returns
Integral((2*x**2*exp(x**2)*cos(x)**2 + x**2 - 8*x + 2*exp(x**2)*cos(x)**2 + 17)*exp(-x**2)/((x**2 + 1)*(x**2 - 8*x + 17)), (x, 0, 3))
Which means, SymPy could not find a symbolic expression for that integral, so it returns it unevaluated (although transformed in the process of searching for antiderivative).
A quick check with Wolfram Alpha confirms there is no antiderivative in terms of elementary functions.
Suggestions:
If you have the sum of two complicated functions, try integrating it one term at a time. It does not help in this case, but in general you'll at least have an idea of what part of the expression fails to have an elementary antiderivative.
To find the integral numerically, use N(Integral(f(x), (x, 0, 3))) (returns 1.24063...) though of course, for numeric integration one is more likely to use SciPy.

Resources