savig matrix output gives zip argument error - python

I would like to write the outputs of the following code in a text file. It gives this error:
for x in zip(c(), R1):
TypeError: zip argument #1 must support iteration
I could not find any solution. Any help please?
import numpy as np
from math import *
from scipy.integrate import quad
from scipy.integrate import odeint
xx=np.array([0.01,0.012])
yy=np.array([32.95388698,33.87900347])
Cov=[[137,168],[28155,-2217]]
with open('txtfile.txt', 'w') as f:
for j in range (1,20):
R1=np.random.uniform(0,1)
Omn=0.32+R1
Odn=1-Omn
def dl(n):
fn=xx[n]*Odn+yy[n]*Omn
return fn
def c():
f_list = []
for i in range(2): #the value '2' reflects matrix size
f_list.append(dl(i))
r1=[f_list]
r2=[[f] for f in f_list]
a=np.dot(r1,Cov)
b=np.dot(a,r2)
matrix=np.linalg.det(b)
return matrix
for x in zip(c(), R1):
f.write("{0}\t{1}\n".format(x[0],x[1]))
I appreciate your help.

Both c() and R1 are both simple values, not lists. So to write them to a file with a tab, you would just need:
f.write("{}\t{}\n".format(c(), R1))
For example:
import numpy as np
from math import *
from scipy.integrate import quad
from scipy.integrate import odeint
def dl(n):
return xx[n] * Odn + yy[n] * Omn
def c():
f_list = []
for i in range(2): #the value '2' reflects matrix size
f_list.append(dl(i))
r1 = [f_list]
r2 = [[f] for f in f_list]
a = np.dot(r1, Cov)
b = np.dot(a, r2)
matrix = np.linalg.det(b)
return matrix
xx = np.array([0.01, 0.012])
yy = np.array([32.95388698, 33.87900347])
Cov = [[137, 168], [28155, -2217]]
with open('txtfile.txt', 'w') as f:
for j in range (1,20):
R1 = np.random.uniform(0, 1)
Omn = 0.32 + R1
Odn = 1 - Omn
f.write("{}\t{}\n".format(c(), R1))
This would create your txtfile.txt as follows:
35206063.6746 0.777596199441
45374454.3839 0.926105934266
3990656.69091 0.0493187574204
28925205.8769 0.674852617966
45542873.2768 0.928417018276
4412088.81481 0.0683471360264
20148228.6097 0.510253466599
6934013.9475 0.166927414742
18602042.1473 0.477747802178
49485237.1146 0.981343401759
31379848.1448 0.716219179241
21670623.7641 0.541061316417
25859179.9751 0.620631842725
10642383.5164 0.28331967175
14640960.1091 0.387697186294
5183085.91921 0.100940240452
12734994.2117 0.340005554729
26863086.7454 0.638722906359
6227944.29448 0.141453730959
To write extra variable for each row, I would recommend you switch to using a CSV writer as follows:
import numpy as np
from math import *
from scipy.integrate import quad
from scipy.integrate import odeint
import csv
def dl(n):
return xx[n] * Odn + yy[n] * Omn
def c():
f_list = [dl(i) for i in range(2)]
r1 = [f_list]
r2 = [[f] for f in f_list]
a = np.dot(r1, Cov)
b = np.dot(a, r2)
matrix = np.linalg.det(b)
return matrix
xx = np.array([0.01, 0.012])
yy = np.array([32.95388698, 33.87900347])
Cov = [[137, 168], [28155, -2217]]
with open('txtfile.txt', 'w', newline='') as f:
csv_output = csv.writer(f, delimiter='\t')
for j in range (1,20):
R1 = np.random.uniform(0, 1)
Omn = 0.32 + R1
Odn = 1 - Omn
csv_output.writerow([c(), R1])

Input to the zip function must be *iterables such an array or list.
Please try below, hopefully it will work.
for x in zip([c()], [R1]):
f.write("{0}\t{1}\n".format(x[0],x[1]))
Documentation for zip in python3 is available here.

When you are using zip(), you are working with lists.
List contains arrays, your function and random number are just number without [] which demonstrats an array. so you can use without its for loop containing zip().
f.write("{0}\t{1}\n".format(c(),R1))
The other point: Bring functions out of the with open order.

Related

Writing to CSV file with numpy arrays without brackets

I'm attempting to map out coordinates for a circle and export those values to excel to then plot the values. My output CSV file returns the correct values but with brackets around the values ex x,y, [0.],[9.]. I would like to learn how to remove those brackets with my current code attempt if possible.
import numpy as np
from itertools import zip_longest
r = 9
h = 1
k = 1
# r = int(input('Radius'))
# h = int(input('h'))
# k = int(input('k'))
deg = np.arange(0, 361, 1)[:, np.newaxis]
theta = (np.pi * deg * 2)/360
x = (r * np.sin(theta) + h)
y = (r * np.cos(theta) + k)
d = x, y
Points = zip_longest(*d, fillvalue = '')
with open('test.csv', 'w', encoding="ISO-8859-1", newline='') as myfile:
wr = csv.writer(myfile)
wr.writerow(('x','y','r','h','k'))
wr.writerows(Points)
myfile.close()
x and y are arrays with shape (361,1). When you iterate over such an array (as zip_longest will do), you get a stream of arrays of shape (1,) which is where your surplus brackets come from.
One solution would be to make your arrays (361,) instead (i.e, one-dimensional). Then iterating would give scalars.
Another solution would be to use np.hstack([x,y]) instead of zip, and tossing the entire resulting (361,2) array to writerows.
(Off topic: You do not need myfile.close(); the with ... construct takes care of that for you — that's what it's for!)

Error using scicpy.integrate.odeint and sympy symbols

I'm trying to solve the following system: d²i/dt² + R'(i)/L di/dt + 1/LC i(t) = 1/L dE/dt as a set of coupled first order differential equations:
di/dt = k
dk/dt = 1/L dE/dt - R'(i)/L k - 1/LC i(t)
Here is the code I'm using:
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
from scipy.integrate import odeint
#Define model: x = [i , k]
def RLC(x , t):
i = sp.Symbol('i')
t = sp.Symbol('t')
#Data:
E = sp.ln(t + 1)
dE_dt = E.diff(t)
R1 = 1000 #1 kOhm
R2 = 100 #100 Ohm
R = R1 * i + R2 * i**3
dR_di = R.diff(i)
i = x[0]
k = x[1]
L = 10e-3 #10 mHy
C = 1.56e-6 #1.56 uF
#Model
di_dt = k
dk_dt = 1/L * dE_dt - dR_di/L * k - 1/(L*C) * i
dx_dt = np.array([di_dt , dk_dt])
return dx_dt
#init cond:
x0 = np.array([0 , 0])
#time points:
time = np.linspace(0, 30, 1000)
#solve ODE:
x = odeint(RLC, x0, time)
i = x[: , 0]
However, I get the following error: TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'
So, I don't know if sympy and odeint don't work well together. Or maybe is it a problem because I defined t as sp.Symbol?
When you differentiate a function, you get a function back. So you need to evaluate it at a point in order to get a number. To evaluate a sympy expression, you could use .subs() but I prefer .replace() which feels more powerful (at least for me).
You must try and make every single variable have its own name in order to avoid confusion. For example, you replace the float input t with a sympy Symbol from the very beginning, thus losing the value of t. The variables x and i are also repeated in the outer scope which is not good practice if they mean different things.
The following should avoid confusion and hopefully produce something that you were expecting:
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
from scipy.integrate import odeint
# Define model: x = [i , k]
def RLC(x, t):
# define constants first
i = x[0]
k = x[1]
L = 10e-3 # 10 mHy
C = 1.56e-6 # 1.56 uF
R1 = 1000 # 1 kOhm
R2 = 100 # 100 Ohm
# define symbols (used to find derivatives)
i_symbol = sp.Symbol('i')
t_symbol = sp.Symbol('t')
# Data (differentiate and evaluate)
E = sp.ln(t_symbol + 1)
dE_dt = E.diff(t_symbol).replace(t_symbol, t)
R = R1 * i_symbol + R2 * i_symbol ** 3
dR_di = R.diff(i_symbol).replace(i_symbol, i)
# nothing should contain symbols from here onwards
# variables can however contain sympy expressions
# Model (convert sympy expressions to floats)
di_dt = float(k)
dk_dt = float(1 / L * dE_dt - dR_di / L * k - 1 / (L * C) * i)
dx_dt = np.array([di_dt, dk_dt])
return dx_dt
# init cond:
x0 = np.array([0, 0])
# time points:
time = np.linspace(0, 30, 1000)
# solve ODE:
solution = odeint(RLC, x0, time)
result = solution[:, 0]
print(result)
Just something to note: the value i = x[0] seemed to sit very close to 0 throughout each iteration. This means dR_di stayed basically at 1000 the whole time. I'm not familiar with odeint or your specific ODE, but hopefully this phenomenon is expected and isn't a problem.

Integrate square function

I need to make the fourier series of an square function.
To get this a have a function y = square(t)
i need to make the integral of (2/p)*(square(t)*cos((2pi/p)*t)) from 0 to a variable I type for example p = 10 but i cant make this integral because every time i try to do this with scipy i get an error with the square function.
from scipy.signal import *
from scipy.integrate import quad
from numpy import *
p = 10
na = arange(0,10,1)
def integrand(t, a, b):
return square(t)*cos(b*((2*pi)/a)*t)
i,err = quad(integrand,0,p, args=(p,na))
y = i
quadpack.error: Supplied function does not return a valid float.
quad returns 2 parameters, the integral and the absolute value of the error, you just have to unpack it.
from scipy.signal import *
from scipy.integrate import quad
from numpy import *
p = 10
def integrand(t, a):
return square(t)*cos(((2*pi)/a)*t)
i, err = quad(integrand,0,p, args=(p,))
y = (2/p)*i
update:
from scipy.signal import *
from scipy.integrate import quad
from numpy import *
p = 10
na = arange(0,10,1)
y = []
def integrand(t, a, b):
return square(t)*cos(b*((2*pi)/a)*t)
for e in na:
i,err = quad(integrand,0,p, args=(p, e))
y.append(i)
print(y)

indexing in lambda function to optimize multiple variables of a sum

I want to solve an optimization problem as proposed in this thread. Now, I not only want to solve for the x[1]...x[n], but also for the variable y. It looks like something is wrong with the indexing.
from sympy import Sum, symbols, Indexed, lambdify
from scipy.optimize import minimize
import numpy as np
def _eqn(y, variables, periods, sign=-1.0):
x, i = symbols("x i")
n = periods-1
s = Sum(Indexed('x', i)/(1+0.06)**i, (i, 1, n))
f = lambdify(x, s, modules=['sympy'])
return float(sign*(y + f(variables)))
z = 3
results = minimize(lambda xy: _eqn(xy[0], xy[1:z], z),np.zeros(z))
print(results.x)
From the error message it seems there is an issue in your indexing. The summation runs from 1 to n but by default indexing of list type objects in Python goes from 0 to n-1. If I change this in your code it seems to work. Check it out.
import sympy as sp
from scipy.optimize import minimize
import numpy as np
sp.init_printing()
def _eqn(y, variables, periods, sign=-1.0):
x, i = sp.symbols("x i")
n = periods-1
s = sp.Sum(sp.Indexed('x', i)/(1+0.06)**(i+1), (i, 0, n-1)).doit()
f = sp.lambdify(x, s, modules=['sympy'])
return float(sign*(y + f(variables)))
z = 3
results = minimize(lambda xy: _eqn(xy[0], xy[1:z], z),np.zeros(z))
print(results.x)
If all you need is variable number of arguments for minimization then does the following code work for you?
from sympy import var
from scipy.optimize import minimize
import numpy as np
def _eqn(y, variables, periods, sign=-1.0):
f = 0
for i,x in enumerate(variables):
f += x/(1+0.06)**(i+1)
return float(sign*(y + f))
z = 3
results = minimize(lambda xy: _eqn(xy[0], xy[1:z], z),np.zeros(z))
print(results.x)

Creating a Matrix of Floats to do Polynomial Regression

I'm trying to do a polynomial regression of csv file I have (or any other csv file). I am not sure how to build a matrix that contains the data set I have. Here is the current code I have.
from matplotlib.pyplot import *
import numpy as np
import csv
from math import *
f=open("data_setshort.csv", "r")
csv_f = csv.reader(f)
xval = []
yval = []
polyreg = []
for row in csv_f:
xval.append(row[0])
yval.append(row[1])
f.close()
x = np.array(xval)
y = np.array(yval)
xlist = [float(i) for i in x]
ylist = [float(i) for i in y]
print xlist
print ylist
def poly_fit(x,y):
for i in range(1, len(x)):
M = np.matrix(x[i],y[i])
return M
Matrix = poly_fit(xlist,ylist)
print Matrix
The poly_fit(x,y) is the function I am trying to build to do the polynomial regression.
Maybe I misunderstood exactly what you're trying to do, but if it's fitting a polynomial from continuous x and y values, then this will do it:
import numpy as np
xi = np.random.uniform(-3, 3, 30)
ni = np.random.uniform(0, .4, 30)
coefficients = np.polyfit(xi, ni, 3)
print coefficients
Then, to use it to generate y values given new x values:
new_x = 2.5
polynomial = np.poly1d(coefficients)
new_y = polynomial(new_x)

Categories