x - x^2/fact(2) + x^3/fact(3) ... -x^6/fact(6)
I tried various ways, even used nested 'for' loops, but I can't seem to figure out the code, any help?
you could try this; order defines how many terms should be taken into account:
def taylor(x, order=3):
x_n = x
fact = 1
sign = 1
res = 0
for n in range(2, order+2):
res += sign * x_n/fact
x_n *= x
fact *= n
sign = -sign
return res
for comparison (because this is the same function):
from math import exp
def real_funtion(x):
return 1-exp(-x)
Related
Given two sequences A and B of the same length: one is strictly increasing, the other is strictly decreasing.
It is required to find an index i such that the absolute value of the difference between A[i] and B[i] is minimal. If there are several such indices, the answer is the smallest of them. The input sequences are standard Python arrays. It is guaranteed that they are of the same length. Efficiency requirements: Asymptotic complexity: no more than the power of the logarithm of the length of the input sequences.
I have implemented index lookup using the golden section method, but I am confused by the use of floating point arithmetic. Is it possible to somehow improve this algorithm so as not to use it, or can you come up with a more concise solution?
import random
import math
def peak(A,B):
def f(x):
return abs(A[x]-B[x])
phi_inv = 1 / ((math.sqrt(5) + 1) / 2)
def cal_x1(left,right):
return right - (round((right-left) * phi_inv))
def cal_x2(left,right):
return left + (round((right-left) * phi_inv))
left, right = 0, len(A)-1
x1, x2 = cal_x1(left, right), cal_x2(left,right)
while x1 < x2:
if f(x1) > f(x2):
left = x1
x1 = x2
x2 = cal_x1(x1,right)
else:
right = x2
x2 = x1
x1 = cal_x2(left,x2)
if x1 > 1 and f(x1-2) <= f(x1-1): return x1-2
if x1+2 < len(A) and f(x1+2) < f(x1+1): return x1+2
if x1 > 0 and f(x1-1) <= f(x1): return x1-1
if x1+1 < len(A) and f(x1+1) < f(x1): return x1+1
return x1
#value check
def make_arr(inv):
x = set()
while len(x) != 1000:
x.add(random.randint(-10000,10000))
x = sorted(list(x),reverse = inv)
return x
x = make_arr(0)
y = make_arr(1)
needle = 1000000
c = 0
for i in range(1000):
if abs(x[i]-y[i]) < needle:
c = i
needle = abs(x[i]-y[i])
print(c)
print(peak(x,y))
Approach
The poster asks about alternative, simpler solutions to posted code.
The problem is a variant of Leetcode Problem 852, where the goal is to find the peak index in a moutain array. We convert to a peak, rather than min, by computing the negative of the abolute difference. Our aproach is to modify this Python solution to the Leetcode problem.
Code
def binary_search(x, y):
''' Mod of https://walkccc.me/LeetCode/problems/0852/ to use function'''
def f(m):
' Absoute value of difference at index m of two arrays '
return -abs(x[m] - y[m]) # Make negative so we are looking for a peak
# peak using binary search
l = 0
r = len(arr) - 1
while l < r:
m = (l + r) // 2
if f(m) < f(m + 1): # check if increasing
l = m + 1
else:
r = m # was decreasing
return l
Test
def linear_search(A, B):
' Linear Search Method '
values = [abs(ai-bi) for ai, bi in zip(A, B)]
return values.index(min(values)) # linear search
def make_arr(inv):
random.seed(10) # added so we can repeat with the same data
x = set()
while len(x) != 1000:
x.add(random.randint(-10000,10000))
x = sorted(list(x),reverse = inv)
return x
# Create data
x = make_arr(0)
y = make_arr(1)
# Run search methods
print(f'Linear Search Solution {linear_search(x, y)}')
print(f'Golden Section Search Solution {peak(x, y)}') # posted code
print(f'Binary Search Solution {binary_search(x, y)}')
Output
Linear Search Solution 499
Golden Section Search Solution 499
Binary Search Solution 499
I am trying to learn Python and currently studying while loops and I am embarrassed to even ask this question cause I feel I should be able to do this, but I am very confused.
def summation(n, term):
"""Return the sum of numbers 1 through n (including n) wíth term applied to each number.
Implement using recursion!
>>> summation(5, lambda x: x * x * x) # 1^3 + 2^3 + 3^3 + 4^3 + 5^3
225
"""
assert n >= 1
"*** YOUR CODE HERE ***"
counter = 1
while counter <= n:
Also if there is any suggestions on where to practice while loops etc I will take any and all feedback, I have tried to google this but I cannot find anything.
This is how you can do it with a while loop:
def summation_while(n, term):
assert n >= 1
counter = 1
total = 0
while counter <= n:
total += term(counter)
counter += 1
return total
Test:
summation_while(5, lambda x: x**3)
Output:
225
You can also do this by summing a generator expression:
def summation_generator(n, term):
return sum(term(i) for i in range(1, n+1))
I am trying to create a code that returns a approximation of pi given n iterations that the user will give. The higher n the more accurate.
I created a while loop to do this, and it works fine:
import math
x = 1
k = 0
n = int(input("Enter n:"))
while x <= n:
k=k+(1/x**2) # summation of 1/k**2 for every n times
y=k*6 # multiply k by 6 like in formula
fin = math.sqrt(y) # find sqrt of y like in the formula
x += 1
print(fin)
But now I'm trying to make this into a function. This is what I've come up with:
import math
def pi(n):
x = 1
k = 0
#n = int(input("Enter n:"))
while x <= n:
k=k+(1/x**2) # summation of 1/k**2 for every n times
y=k*6 # multiply k by 6 like in formula
fin = math.sqrt(y) # find sqrt of y like in the formula
x += 1
return fin
g=pi(int(input("Enter n:")))
print(g)
For some reason I get different answers... why is it when I use the function that the answer becomes inaccurate?
You have your return inside the loop, hence the block inside the while is executed only once and the rest of approximations are never calculated, put your return out of your cycle:
while x <= n:
k=k+(1/x**2) # summation of 1/k**2 for every n times
y=k*6 # multiply k by 6 like in formula
fin = math.sqrt(y) # find sqrt of y like in the formula
x += 1
return fin
I tested it, now it returns the same result with both approaches.
Have a good day! :D
I have been writing code for a module I am making for my Discord Bot. I have been trying not to use any module as it is not helping in in importing stuff. So I thought I should write the code myself for both of them.
The problem here is that I don't really know how do we make them. I couldn't find them anywhere on the net as everywhere I only saw the use of math module which I don't want to use.
I don't know how do I work with them, so I want some help.
Thank You! :)
Using Taylor expansion you get an approximation up to the desired precision.
http://hyperphysics.phy-astr.gsu.edu/hbase/tayser.html
def pow(base, exponent):
return base ** exponent
def faktorial(n):
value = float(1)
for i in range(1, n+1):
value = value * i
return value
def cos(x):
x = x * 3.14/180
value = 1
sign = -1
n = 200 # precision
i = 2
while i < n:
value = value + (pow(x, i)/faktorial(i) * sign)
i = i + 2
sign = sign * -1
return value
def sin(x):
x = x * 3.14/180
value = x
sign = -1
n = 200 # precision
i = 3
while i < n:
value = value + (pow(x, i)/faktorial(i) * sign)
i = i + 2
sign = sign * -1
return value
pi = 3.1415926535897932384626433832795028841971 # Value of constant pi
def f(n): # Factorial Function
if n == 1 or n == 0:
return 1
else:
return n * f(n - 1)
def deg(x):
rad = x * pi/180
return rad
def sin(x): # Taylor Expansion of sinx
k = 0
sinx = 0
while x >= pi:
x -= pi
if pi > x > pi / 2:
x = pi - x
while k < 15:
sinx += (-1)**k * x**(2*k + 1) / f(2*k + 1)
k += 1
return sinx
def cos(x):
cosx = sin(pi / 2 - x)
return cosx
I improved the code now. Now it gives you accurate results of up to 14 decimal places. Also instead of writing full Taylor expression formula, I used a while loop to do that. While loop here acts as a summation function of maths. I also shorten the code inside cos(x). Instead of writing Taylor's expression here, I used a conversion formula of sinx to cosx. Which reduces the calculation process. I made a little change in the code. Now you can calculate sinx of huge number too with the same accuracy.
I wrote a code that is supposed to convert a number from base 10 to another base. This is the code, where n is the number to convert and l is the base to convert to:
def convert_from_base_10(n,l):
import math
counter = 0
m=n
z=0
string = ""
if n<2:
return n
else:
while m>=l:
m=m/l
counter +=1
while counter >= 0:
z= math.floor(n/(l**counter))
string = string + str(z)
n = n-z*(l**counter)
counter = counter - 1
return string
Because in the first else statement I change the value of the number I want to convert by dividing m by l, I had to assign m = n and use m instead of n. Is there a way to get around this and use only on variable?
I don't have enough reputation to add a comment, but I'm adding an answer as a workaround. Please take a look at the Math library from Python.
Please let me know if something like this might help:
log(x)/log(base)
math.log(x[, base]) With one argument, return the natural logarithm of
x (to base e).
With two arguments, return the logarithm of x to the given base,
calculated as log(x)/log(base).
Source: https://docs.python.org/3.6/library/math.html
Not sure what you are trying to accomplish, but it you do not want to use the built in functions as NellMartinez pointed out I think adding another function might be what you are looking for to remove a variable from it.
def set_count(n, l):
count = 0
if n >= 2:
while n >= l:
n = n / l
count += 1
return count
def convert_from_base_10(n, l):
string = ""
counter = set_count(n, l)
while counter >= 0:
z = math.floor(n / (l ** counter))
string = string + str(z)
n = n - z * (l ** counter)
counter = counter - 1
return string
You may choose to use a dictionary or a list.
Instead of assigning n to m, and using two variables, you may choose to use a list list_name = [n, n]. Now you can keep list_name[0] as constant and vary list_name[1].
With dictionary, you may do something like dict_name = {"original": n, "variable": n}.
I suggest you rewrite your code like this (it is the same code just more readable and better formatted. Some names still remain for you to choose)
You should return always a coherent result if it is a string, always return a string
I don't see a problem in saving var content if you need it later.
Note that number is a local function parameter so you won't alter the original (which is actually an immutable also in your case) but you want to
change the local value a bit later, so it's ok to copy it to m.
There are other ways to do the conversion but I suppose you want to code the algorithm not a brief solution.
import math
def convert_base10_to(number, base):
counter = 0
m = number # choose a proper name to m: what is m?
# That will be the best name for m
z = 0 # same for z
result = ""
if number < 2:
return str(number)
else:
while m >= base:
m = m / base
counter += 1
while counter >= 0:
z = math.floor(number / (base ** counter))
result = result + str(z)
number = number - z *(base ** counter)
counter = counter - 1
return result
print(convert_base10_to(7, 2))