I have n rows and n+1 columns matrix and need to construct such system
For example matrix is
x4 x3 x2 x1 result
1 1 0 1 0
1 0 1 0 1
0 1 0 1 1
1 0 1 1 0
Then equation will be (+ is XOR)
x4+x3+x1=0
x4+x2=1
x3+x1=1
x4+x2+x1=0
I need to return answer as list of x1,.....
How can we do it in python?
You could make use of the Python interface pyz3 of Microsoft's Z3 solver:
from z3 import *
def xor2(a, b):
return Xor(a, b)
def xor3(a, b, c):
return Xor(a, Xor(b, c))
# define Boolean variables
x1 = Bool('x1')
x2 = Bool('x2')
x3 = Bool('x3')
x4 = Bool('x4')
s = Solver()
# every equation is expressed as one constraint
s.add(Not(xor3(x4, x3, x1)))
s.add(xor2(x4, x2))
s.add(xor2(x3, x1))
s.add(Not(xor3(x4, x2, x1)))
# solve and output results
print(s.check())
print(s.model())
Result:
sat
[x3 = False, x2 = False, x1 = True, x4 = True]
Learn Gauss, can be also used for XOR. Then write a gauss python program
Related
I am trying to write a program about Simpson's Law.What I am trying to do is use as error as shown in this picture:
.
In the code i write the Ih is my f1 and Ih/2 is my f2.If the error doesnt happen then the steps get halved.
However I get this error
Traceback (most recent call last):
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\example.py", line 22, in <module>
sim2 = simps(f2, x2)
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 436, in simps
return simpson(y, x=x, dx=dx, axis=axis, even=even)
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 542, in simpson
last_dx = x[slice1] - x[slice2]
IndexError: index -1 is out of bounds for axis 0 with size 0
Process finished with exit code 1
My code is
import numpy as np
from sympy import *
from scipy.integrate import simps
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)
while True:
x1 = np.linspace(a, b, N)
f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
sim1 = simps(f1, x1)
x2 = np.linspace(a, b, int(N/2))
f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
sim2 = simps(f2, x2)
if abs(sim1 - sim2) < error:
break
else:
N = int(N/2)
print(sim1)
I wasnt expecting any error,and basically expecting to calculate correctly.
When you reduce the grid step by half h -> h/2, the number of grid steps in turn grows N -> 2 * N, so you have to make two changes in your code:
Define x2 to have twice as many elements as x1
x2 = np.linspace(a, b, 2 * N)
Update N to be twice it was on the previous iteration
N = 2 * N
The resulting code would be
import numpy as np
from sympy import *
from scipy.integrate import simps
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)
while True:
x1 = np.linspace(a, b, N)
f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
sim1 = simps(f1, x1)
x2 = np.linspace(a, b, 2 * N)
f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
sim2 = simps(f2, x2)
if abs(sim1 - sim2) < error:
break
else:
N = 2 * N
print(sim1)
And this prints the value
87.9765411043221
with error consistent with the threshold
abs(sim1 - sim2) = 4.66441463231604e-9
#DmitriChubarov's solution is correct. However, your implementation is very inefficient: it does double the work it needs to. Also, simps is deprecated, you should be using proper exponential notation, and your function expression can be simplified. For an equivalent error-free algorithm that still doubles the input array length on each iteration but doesn't throw away the intermediate result,
import numpy as np
from scipy.integrate import simpson
a = 0
b = 2*np.pi
N = 100
ra = 0.1 # ρα
R = 0.05
fa = np.radians(35) # φα
za = 0.4
aa = np.linalg.norm((ra, R, za))
error = 5e-9
sim1 = np.nan
while True:
x = np.linspace(a, b, N)
f = (aa**2 - 2*ra*R*np.cos(x - fa))**-1.5
sim2 = simpson(f, x)
if np.abs(sim1 - sim2) < error:
break
sim1 = sim2
N *= 2
print(sim1)
When I modified your code by adding two lines to print(len(x1), len(f1)) and print(len(x2), len(f2)), I got these results:
Output:
length of x1 and f1: 100 100
length of x2 and f2: 50 50
length of x1 and f1: 50 50
length of x2 and f2: 25 25
length of x1 and f1: 25 25
length of x2 and f2: 12 12
length of x1 and f1: 12 12
length of x2 and f2: 6 6
length of x1 and f1: 6 6
length of x2 and f2: 3 3
length of x1 and f1: 3 3
length of x2 and f2: 1 1
length of x1 and f1: 1 1
length of x2 and f2: 0 0
as you can see the length decreases each loop because N decreases and ends with an empty list length of x2 and f2: 0 0 and this causes the error you have had. To fix the issue of 'the empty list' I suggest that you duplicate N; this means using N*2 instead of N/2.
If i have 2 z3 Ints for examaple x1 and x2, and a 2d array of numbers for example:
list = [[1,2],[12,13],[45,7]]
i need to right a rule so that x1 and x2 are any of the pairs of numbers in the list for example x1 would be 1 and x2 would be 2 or x1 is 12 and x2 is 13
im guessing it would be something like:
solver = Solver()
for i in range(o,len(list)):
solver.add(And((x1==list[i][0]),(x2==list[i][1])))
but this would obviously just always be unsat, so i need to right it so that x1 and x2 can be any of the pairs in the list. It's worth noting that the number of pairs in the list could be anything not just 3 pairs.
You're on the right track. Simply iterate and form the disjunction instead. Something like:
from z3 import *
list = [[1,2],[12,13],[45,7]]
s = Solver()
x1, x2 = Ints('x1 x2')
s.add(Or([And(x1 == p[0], x2 == p[1]) for p in list]))
while s.check() == sat:
m = s.model()
print("x1 = %2d, x2 = %2d" % (m[x1].as_long(), m[x2].as_long()))
s.add(Or(x1 != m[x1], x2 != m[x2]))
When run, this prints:
x1 = 1, x2 = 2
x1 = 12, x2 = 13
x1 = 45, x2 = 7
You can download the following data set from this repo.
Y
CONST
T
X1
X1T
X2
X2T
0
2.31252
1
1
0
0
1
1
1
-0.836074
1
1
1
1
1
1
2
-0.797183
1
0
0
0
1
0
I have a dependent variable (Y) and three binary columns (T, X1 and X2). From this data we can create four groups:
X1 == 0 and X2 == 0
X1 == 0 and X2 == 1
X1 == 1 and X2 == 0
X1 == 1 and X2 == 1
Within each group, I want to calculate the difference in the mean of Y between observations with T == 1 and T == 0.
I can do so with the following code:
# Libraries
import pandas as pd
# Group by T, X1, X2 and get the mean of Y
t = df.groupby(['T','X1','X2'])['Y'].mean().reset_index()
# Reshape the result and rename the columns
t = t.pivot(index=['X1','X2'], columns='T', values='Y')
t.columns = ['Teq0','Teq1']
# I want to replicate these differences with a regression
t['Teq1'] - t['Teq0']
> X1 X2
> 0 0 0.116175
> 1 0.168791
> 1 0 -0.027278
> 1 -0.147601
Problem
I want to recreate these results with the following regression model (m).
# Libraries
from statsmodels.api import OLS
# Fit regression with interaction terms
m = OLS(endog=df['Y'], exog=df[['CONST','T','X1','X1T','X2','X2T']]).fit()
# Estimated values
m.params[['T','X1T','X2T']]
> T 0.162198
> X1T -0.230372
> X2T -0.034303
I was expecting the coefficients:
T = 0.116175
T + X1T = 0.168791
T + X2T = -0.027278
T + X1T + X2T = -0.147601
Question
Why don't the regression coefficients match the results from the first chunk's output (t['Teq1'] - t['Teq0'])?
Thanks to #Josef for noticing that T, X1 and X2 have eight different combinations while my regression model has six parameters. I was therefore missing two interaction terms (and thus two parameters).
Namely, the regression model needs to account for the interaction between X1 and X2 as well as the interaction between X1, X2 and T.
This can be done by declaring the missing interaction columns and fitting the model:
# Declare missing columns
df = df.assign(X1X2 = df['X1'].multiply(df['X2']),
X1X2T = df['X1'].multiply(df['X2T']))
# List of independent variables
cols = ['CONST','T','X1','X1T','X2','X2T','X1X2','X1X2T']
# Fit model
m = OLS.fit(endog=df['Y'], exog=df[cols]).fit()
Alternatively, we can use the formula interface:
# Declare formula
f = 'Y ~ T + X1 + I(X1*T) + X2 + I(X2*T) + I(X1*X2) + I(X1*X2*T)'
# Fit model
m = OLS.from_formula(formula=f, data=df).fit()
Can anyone suggest an efficient way of reshaping a column (in a python pandas dataframe) into multiple columns, with alternating column assignment. I could do this with a loop but wondering if there is a more elegant way. For an example, consider the following example:
Added: does anyone have a solution that will reshape every n values in a single column into n separate columns e.g. reshaping from a single column with n variables to n columns?
Col
1 x1
2 y1
3 z1
4 x2
5 y2
6 z2
7 x3
8 y3
9 z3
..
to
x y z
1 x1 y1 z1
2 x2 y2 z2
3 x3 y3 z3
...
You can just reshape the underlying values, assuming that you have the correct number of values for the given shape and that you only care about ordering the values by shape without respect to the values themselves
s
Col
1 x1
2 y1
3 z1
4 x2
5 y2
6 z2
7 x3
8 y3
9 z3
pd.DataFrame(s.to_numpy().reshape(3, 3))
0 1 2
0 x1 y1 z1
1 x2 y2 z2
2 x3 y3 z3
You can use:
df_final=(pd.DataFrame(df.groupby(df.Col.str[-1])['Col'].apply(list)
.values.tolist(),columns=['x','y','z']))
x y z
0 x1 y1 z1
1 x2 y2 z2
2 x3 y3 z3
You can use auxiliary variables to work as the row and column index, then apply df.pivot
df1['aux'] = df1.Col.str[:-1]
df1['aux_idx'] = df1.Col.str[-1:]
print(df1.pivot(index= 'aux_idx', columns='aux', values='Col'))
Output:
aux x y z
aux_idx
1 x1 y1 z1
2 x2 y2 z2
3 x3 y3 z3
For the same result by just counting the number of elements, use df.index module n as the key
df1['aux_idx'] = (df1.index-1)// 3
df1['aux'] = df1.Col.str[:-1]
print(df1.pivot(index= 'aux_idx', columns='aux', values='Col'))
Output:
aux x y z
aux_idx
0 x1 y1 z1
1 x2 y2 z2
2 x3 y3 z3
I'm trying to solve a linear systems of inequations in Python.
My linear system look something like this :
3 * x1 + 2 * x2 + 4 * x3 > 0
x1 - 4 * x2 - 7 * x3 > 0
I've tried to use NumPy but linalg.solve(a, b) is designed for equations (=) and I have inequations (>).
I've thought about adding variables to my problem to trasnform inequations into equation like :
3 * x1 + 2 * x2 + 4 * x3 - x4 + 0 * x5 = 0
x1 + 4 * x2 + 7 * x3 + 0 * x4 - x5 = 0
x4 and x5 being > 0.
But I don't know how many constraints I'm going to have and I don't know if linalg.solve gives only strictly positive value to variables.
I've also look into SciPy linprog.
I could add an objective function like x1 + x2 + x3, that would'nt be a problem.
But with linprog I have only inequations as <= 0, but I want to exclude the value 0. It would be okay if I could have < 0.
I hope my problem is clear.
I've asked Google for some help, but find nothing. I guess I'm missing something since I can't be the only one with this problem.
Thank you for your help.
I would suggest to introduce a tolerance that defines how close you can come to zero and perhaps iterate on the tolerance value
I.e. Rewrite
3 * x1 + 2 * x2 + 4 * x3 > 0
x1 + 4 * x2 + 7 * x3 > 0
as
3 * x1 + 2 * x2 + 4 * x3 >= t
x1 + 4 * x2 + 7 * x3 >= t
Now, you can use spicy.linprog to solve this.
where t > 0.
Perhaps t >= 0.01 is acceptable as a starting point.
Then iterate on t in [0.01, 0.001, 0.0001, ... ]
At some point, your solution might start changing by less than your precision requirement.
Hope this helps.