How to plug f(k) in to a series? - python

Lets suppose you have f(x)=x^2 and you want a series from k=1 to n of f(k). How would you enter it in python and print the result?
I tried doing this for n=10
n=10
def f(x):
return x^2
sum = 0
for k in range(1, n):
Sum = sum + f(k)
I don't know how to print it let alone whether I did it correctly.
I know you can represent a sum of k^2 as n(n+1)(2n+1)/6 but I am just using x^2 as an example.

First off sum is a builtin function so you should not use it as a variable name as python will simply let you overwrite the variable in the spirit of "we are all consenting adults here". Example
type(sum)
# <type 'builtin_function_or_method'>
sum = 0
type(sum)
# <type 'int'>
Now to your question. One way is to first generate the sequence and use the aforementioned sum function as the following examples show.
Generate the sequence using a so-called list comprehension to evaluate the function for each element in a range:
n = 5
def f(x):
return x*x
print([ f(i) for i in range(n)])
# [0, 1, 4, 9, 16]
print(sum([ f(i) for i in range(n)]))
# 30
Use the builtin map function to apply a function, either defined using def or lambda, on a range:
n = 10
f = lambda x: x*x
print(map(f, range(n)))
# [0, 1, 4, 9, 16]
# one line equivalent : print(map(lambda x: x*x, range(n)))
print(sum(map(f, range(n))))
# 30
Alternatively, you can follow your train of thought and use a simple loop and a variable:
n = 5
f = lambda x: x*x
s = 0
for i in range(n):
s += f(i)
print(s)
# 30
Finally, if speed/efficiency is a factor that you have to account for you can have a look at the numpy library. See for instance one of my answers on applying a funcion over a range.

Related

Creating a list of square of numbers in a given range

Edit: Sorry guys, I meant to use the power function, not squaring, i hope this clears it up
I'm a new to python, and I'm trying to create a function that lets the user input x and y and will give the output of the powers of those numbers in a loop, so create_list(2,8) returns the list [1,2,4,8,16,32,64,128,256].
I have this code so far, but I feel like it's way off as it only allows for 1 input, whereas I'm looking for 2
import math
a=int(input())
while a<=10000:
print (a)
a=a*2
An example output of this is if a=4, output:
4
8
16
32
64
128
256
512
1024
2048
4096
8192
The previous answers already explain how to solve your question, here I explain how to create a function. Notice that for simple operation like power, you don't need import math. With the following code you define a function create_list(x, y) that takes as input 2 numbers x and y and gives your output, regardless of how they are passed to the function:
def create_list(x, y):
my_list = []
for i in range(y+1):
my_list.append(x**i)
return my_list
After that, you can call the create_list function by giving the numbers programmatically (maybe they are the results of previous operations), but if you want to give them explicitly by keyboard, use this code:
x = int(input())
y = int(input())
my_list = create_list(x,y)
print(my_list)
First, use the input() function twice to let the user input two numbers.
Use the formula square = x * x (instead of x*2) to calculate the square.
Iterate over all numbers between a and b by using the range(a, b) function.
Collect all square numbers in a list and print the list afterwards.
a = int(input())
b = int(input())
squares = []
for i in range(a, b):
square = i * i
squares.append(square)
print(squares)
The more pythonic way in one line:
squares = [i*i for i in range (a,b)]
print(squares)
a=int(input())
b=int(input())
def create_list(a,b):
return [a**i for i in range(b+1)]
print(create_list(a,b))
output for create_list(2,8)
[1, 2, 4, 8, 16, 32, 64, 128, 256]
You can use python pow function
import math
def get_powers(power, length):
return [int(math.pow(power, x)) for x in range(1, length + 1)]
power_input = int(input('power:'))
length_input = int(input('length:'))
print(get_powers(power_input, length_input))
run
power:3
length:5
[3, 9, 27, 81, 243]
[ x * x for x in range (int(input("lower bound")), int(input("upper bound")))]
The above is a list comprehension. It takes every element in range and accesses it through the variable x. The expression on the left is what will actually end up in the list. For example, putting x + 1 would result in storing a value 1 greater than x being stored.
Inputs are evaluated from left to right so you can directly put them in as the parameters to the range function.
The evaluation order is:
Call 'lower bound' input
Convert to int
As above for right input
Evaluate range
Run list comprehension

Optimizing a factorial function in python

So i have achieved this function with unpacking parameter(*x), but i want to make it display the result not return it , and i want a good optimization meaning i still need it to be a two lines function
1.def fac(*x):
2.return (fac(list(x)[0], list(x)[1] - 1)*list(x)[1]) if list(x)[1] > 0 else 1//here i need the one line to print the factorial
i tried achieving this by implementing lambda but i didn't know how to pass the *x parameter
Your factorial lambda is correct. I take it that you would like to calculate the factorials for a list say [1, 2, 3] and output the results, this is how you can achieve this.
fact = lambda x: x*fact(x-1) if x > 0 else 1
print(*[fact(i) for i in [1, 2, 3]])
Which will output: 1, 2, 6
Another option, if you have python 3.8 is to use a list comprehension with the new walrus operator (:=), this is a bit more tricky but will calculate and output all factorials up to n inclusive whilst still fitting in your required two lines.
fac, n = 1, 5
print(*[fac for i in range(1, n+1) if (fac := fac*i)])
Which will output: 1, 2, 6, 24, 120
The optimized factorial number is display by the function that i have created below.
def fact(n):
list_fact = []
if n > 1 and n not in list_fact:
list_fact.extend(list(range(1, n + 1)))
return reduce(lambda x, y: x * y, list_fact)
print(fact(9000)) # it will display output within microseconds.
Note:
while iteration i saved all previous values into a list, so that computation of each value is not going to happen each time.

Pythonic way to generate sequence from linear difference

I have a sequence definition
xn+1 = f(xn , xn-1)
Where xn is x evaluated at time tn. Any value in the sequence is defined by some function of the previous two values (and the time step, but for now that's constant). I would like to generate the first N values in this sequence, given x0 & x1.
What's the most pythonic way to do this?
My current approach is just to loop. I create a numpy.ones array of the correct size, then loop through it by index. If index = 0 or 1 then I change the value from 1 to x0 / x1 respectively. For greater indecies I lookup the previous values in the array and apply the function.
But I feel like this doesn't seem to be making use of the numpy array methods, so I wonder if there's a better approach?
Code
In my code I have a createSequence function, which takes in a definition of xn+1 as well as boundary conditions and timestep, and outputs a sequence following those rules. NB, I'm very new to Python so any general advice would also be appreciated!
import numpy as np
def x_next(x_current,x_previous,dt):
"""Function to return the next value in the sequence
x_current and x_previous are the values at tn and tn-1 respectively
dt is the time step
"""
return (x_current - x_previous)/dt #as an example
def createSequence(x_next,x0,x1,start,stop,dt):
""" Function to create sequence based on x_next function, and boundary conditions"""
num = (stop-start)/dt
x_array = np.ones(int(num))
x_array[0] = x0
x_array[1] = x1
for index in range(len(x_array)):
if index == 0:
x_array[index] = x0
elif index == 1:
x_array[index] = x1
else:
x_current = x_array[index - 1]
x_previous = x_array[index - 2]
x_array[index] = x_next(x_current,x_previous,dt)
return x_array
print(createSequence(x_next=x_next,x0=0.1,x1=0.2,start=0,stop=20,dt=0.1))
I would recommend using a generator because
it allows you to generate sequences of arbitrary length without wasting memory
one might argue it is "pythonic".
In the following, I will use the Fibonacci sequence as an example because it takes a similar form to your problem.
def fibonacci(a=0, b=1, length=None):
# Generate a finite or infinite sequence
num = 0
while length is None or num < length:
# Evaluate the next Fibonacci number
c = a + b
yield c
# Advance to the next item in the sequence
a, b = c, a
num += 1
Note that a corresponds to your x_n, b corresponds to x_{n-1}, and c corresponds to x_{n+1}. And a simple example:
>>> list(fibonacci(length=10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
If you want to get the sequence into a numpy array
>>> np.fromiter(fibonacci(length=10), int)
array([ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
I think you want the initial collection of terms. However, if it should happen that you, or anyone reading this question, might want individual terms then the sympy library comes in handy. Everything here up to the horizontal line is from Solve a recurrence relation.
>>> from sympy import *
>>> var('y')
y
>>> var('n', integer=True)
n
>>> f = Function('f')
>>> f = y(n)-2*y(n-1)-5*y(n-2)
>>> r = rsolve(f, y(n), [1, 4])
Once you have r you can either evaluate it for various values of n within the sympy facilities ...
>>> N(r.subs(n,1))
4.00000000000000
>>> N(r.subs(n,2))
13.0000000000000
>>> N(r.subs(n,10))
265333.000000000
Or you could 'lift' the code in r and re-use it for your own routines.
>>> r
(1/2 + sqrt(6)/4)*(1 + sqrt(6))**n + (-sqrt(6) + 1)**n*(-sqrt(6)/4 + 1/2)

Using the variable of a function in another function

I have the following functions to calculate two different things:
def LCM(X0, a, c, m, n): #Generates "n" numbers of random numbers# with given parameters.
X = []
X.append(X0)
for i in range(n):
X.append(float((a*X[i]+c) % m))
X[i] = X[i]/m
del X[0]
X[n-1] = X[n-1]/m
plt.hist(X)
plt.title("LCM Frequency Histogram")
plt.show()
print "For this example, the LCM generated a good quality uniform distribution."
print "However, it should be also noted that every 2000 generations,"
print "the numbers are repeated."
return X[:10] #Show only the first 10 values of the list.
def exponential(lambdavalue):
Z =[]
for i in range(10000):
Z.append(float(-(1/lambdavalue)*math.log(1-X[i])))
plt.hist(Z)
plt.title("Exponential Frequency Histogram")
plt.show()
return Z[:10] #Show only the first 10 values of the list.
In the first function, I calculate the variable X and in the second I find Z based on X and plot its histogram. I am not able to understand how I can pass the variable X to the second function. I am running following for the first function:
LCM(27, 17, 9, 10000, 10000)
and this for the second:
exponential(10)
I am also aware I can use some packages to make these things (LCM random generation and exp distr), however, I wanted to make something to practice.
Since you are returning the X values from the first function you could pass them to the second function as follows:
X = LCM(27, 17, 9, 10000, 10000)
Z = exponential(X, 10)
You just need to add an argument to exponential for the X values.
You need to pass the value returned from the LCM function into a variable so you do-
x = lcm(27, 17, 9, 10000, 10000)
And then you pass the value of x as an argument into the exponential function as -
x = exponential(10)
Another way is you can declare a global variable X=[ ] outside both your function and you can use them in both of your functions. Without passing it as an argument in the second.
You can use a global variable in other functions by declaring it as global in each function that assigns to it:
x = 0
def f():
x = 1
f()
print x #=>0
and expect 1. Instead, you need do declare that you intend to use the global x:
x = 0
def f():
global x
x = 1
f()
print x #=>1
I hope it will help you. Or at least get you closer to solution.

How does reduce function work?

As far as I understand, the reduce function takes a list l and a function f. Then, it calls the function f on first two elements of the list and then repeatedly calls the function f with the next list element and the previous result.
So, I define the following functions:
The following function computes the factorial.
def fact(n):
if n == 0 or n == 1:
return 1
return fact(n-1) * n
def reduce_func(x,y):
return fact(x) * fact(y)
lst = [1, 3, 1]
print reduce(reduce_func, lst)
Now, shouldn't this give me ((1! * 3!) * 1!) = 6? But, instead it gives 720. Why 720? It seems to take the factorial of 6 too. But, I need to understand why.
Can someone explains why this happens and a work-around?
I basically want to compute the product of factorials of all the entries in the list.
The backup plan is to run a loop and compute it. But, I would prefer using reduce.
The other answers are great. I'll simply add an illustrated example that I find pretty good to understand reduce():
>>> reduce(lambda x,y: x+y, [47,11,42,13])
113
will be computed as follows:
(Source) (mirror)
The easiest way to understand reduce() is to look at its pure Python equivalent code:
def myreduce(func, iterable, start=None):
it = iter(iterable)
if start is None:
try:
start = next(it)
except StopIteration:
raise TypeError('reduce() of empty sequence with no initial value')
accum_value = start
for x in iterable:
accum_value = func(accum_value, x)
return accum_value
You can see that it only makes sense for your reduce_func() to apply the factorial to the rightmost argument:
def fact(n):
if n == 0 or n == 1:
return 1
return fact(n-1) * n
def reduce_func(x,y):
return x * fact(y)
lst = [1, 3, 1]
print reduce(reduce_func, lst)
With that small revision, the code produces 6 as you expected :-)
Your function calls fact() on both arguments. You are calculating ((1! * 3!)! * 1!). The workaround is to only call it on only the second argument, and pass reduce() an initial value of 1.
From the Python reduce documentation,
reduce(function, sequence) returns a single value constructed by calling the (binary) function on the first two items of the sequence, then on the result and the next item, and so on.
So, stepping through. It computes reduce_func of the first two elements, reduce_func(1, 3) = 1! * 3! = 6. Then, it computes reduce_func of the result and the next item: reduce_func(6, 1) = 6! * 1! = 720.
You missed that, when the result of the first reduce_func call is passed as input to the second, it's factorialized before the multiplication.
Ok, got it:
I need to map the numbers to their factorials first and then call reduce with multiply operator.
So, this would work:
lst_fact = map(fact, lst)
reduce(operator.mul, lst_fact)
You could also implement factorial using reduce.
def factorial(n):
return(reduce(lambda x,y:x*y,range(n+1)[1:]))
Beyond the trivial examples, here is one where I find reduce to be actually quite useful:
Imagine an iterable of ordered int values, often with some runs of contiguous values, and that we'd like to "summarize" it as a list of tuples representing ranges. (Note also that this iterable could be a generator of a very long sequence --another reason to use reduce and not some operation on an in-memory collection).
from functools import reduce
def rle(a, b):
if a and a[-1][1] == b:
return a[:-1] + [(a[-1][0], b + 1)]
return a + [(b, b + 1)]
reduce(rle, [0, 1, 2, 5, 8, 9], [])
# [(0, 3), (5, 6), (8, 10)]
Notice the use of a proper initial value ([] here) for reduce.
Corner cases handled as well:
reduce(rle, [], [])
# []
reduce(rle, [0], [])
# [(0, 1)]
Well, first of all, your reduce_func doesn't have the structure of a fold; it doesn't match your description of a fold (which is correct).
The structure of a fold is: def foldl(func, start, iter): return func(start, foldl(func, next(iter), iter)
Now, your fact function doesn't operate on two elements - it just calculates factorial.
So, in sum, you're not using a fold, and with that definition of factorial, you don't need to.
If you do want to play around with factorial, check out the y-combinator: http://mvanier.livejournal.com/2897.html
If you want to learn about folds, look at my answer to this question, which demonstrates its use to calculate cumulative fractions: creating cumulative percentage from a dictionary of data
Reduce executes the function in parameter#1 successively through the values provided by the iterator in parameter#2
print '-------------- Example: Reduce(x + y) --------------'
def add(x,y): return x+y
x = 5
y = 10
import functools
tot = functools.reduce(add, range(5, 10))
print 'reduce('+str(x)+','+str(y)+')=' ,tot
def myreduce(a,b):
tot = 0
for i in range(a,b):
tot = tot+i
print i,tot
print 'myreduce('+str(a)+','+str(b)+')=' ,tot
myreduce(x,y)
print '-------------- Example: Reduce(x * y) --------------'
def add(x,y): return x*y
x = 5
y = 10
import functools
tot = functools.reduce(add, range(5, 10))
print 'reduce('+str(x)+','+str(y)+')=' ,tot
def myreduce(a,b):
tot = 1
for i in range(a,b):
tot = tot * i
print i,tot
print 'myreduce('+str(a)+','+str(b)+')=' ,tot
myreduce(x,y)

Categories

Resources