Warning in script running minisat: difficult to understand - python-3.x

Good day,
I'm running a python script on Linux about a graph of connections that are to be coloured in 2 different colours so that no two same colours are connected. The script is to return an answer in CNF format using minisat such as 'SATISFIABLE' OR 'UNSATISFIABLE', nothing more.
However, even tho I've gotten my script to work perfectly and it passes all the tests I had, it keeps throwing two warnings at me
Warning: for repeatability, setting FPU to use double precision.
Warning! DIMACS header mismatch: wrong number of variables.
I have never gotten these warnings before and can't find anything about them anywhere.
# python3
import itertools
import os
from subprocess import DEVNULL, STDOUT, check_call, call
import warnings
warnings.filterwarnings(action = "ignore", message = 'for repeatability, setting FPU to use double precision')
n, m = map(int, input().split())
edges = [list(map(int, input().split())) for i in range(m)]
clauses = []
colors = range(1, 4)
def varnum(i, k):
assert(i in colors and k in colors)
return 3 * (i - 1) + k
def exactlyOneOf(i):
literal = [varnum(i, k) for k in colors]
clauses.append([l for l in literal])
for pair in itertools.combinations(literal, 2):
clauses.append([-l for l in pair])
def adj(i, j):
for k in colors:
clauses.append([-varnum(i, k), -varnum(j, k)])
for i in range(1, n + 1):
exactlyOneOf(i)
for i, j in edges:
adj(i, j)
#print(len(clauses)) #, n * 3)
#for c in clauses:
# c.append(0)
# print(' '.join(map(str, c)))
with open('tmp.cnf', 'w') as f:
f.write('p cnf {} {}\n'.format(999, len(clauses)))
for c in clauses:
c.append(0)
f.write(" ".join(map(str, c)) + "\n")
os.system("minisat -verb=0 tmp.cnf tmp.sat")
call(['minisat', 'tmp.cnf', 'tmp.sat'], stdout = DEVNULL, stderr = STDOUT)
with open("tmp.sat", "r") as satfile:
for line in satfile:
if line.split()[0] == "UNSAT":
print("There is no solution")
elif line.split()[0] == "SAT":
#print("SATISFIABLE")
pass
else:
assignment = [int(x) for x in line.split()]
for i in colors:
for k in colors:
if varnum(i, k) in assignment:
#print(k)
break
#print("")

I don't know how I did it but I got rid of the warning by using the subprocess module to call Minisat instead of using the OS module.
I initially tried to use a call from the subprocess module but kept getting an error so I tweaked my code a bit and finally got rid of the error using this code line.
subprocess.call(['minisat', 'tmp.cnf', 'tmp.sat'], stdout = subprocess.DEVNULL, stderr = subprocess.STDOUT)

Related

Why does my function with complex numbers return as a NoneType?

I've been trying to code something to draw the mandelbrot-set, but my function doesnt seem to work.
the 'point' in my code is a complex number that is defined somewhere else in the code.
def mandelbrot(point, gen):
z = point
if gen > 0:
mandelbrot(z**2 + c, gen-1)
else:
return (z.real**2 + z.imag**2)**(1/2)
I got a grid of points that get colored in based on the result of this function. It would start with a complex number that i define in a loop later, and the 'gen' is just an integer that determines how often the function is used so i can do quicker tests in case it works. I thought it should have returned the length of the vector, but it gave an error that it was a NoneType.
For context, here is the full code:
import turtle
import cmath
Pen = turtle.Turtle()
Pen.speed(0)
Pen.penup()
size = 800
resolution = 16
accuracy = 3
c = complex(0,0)
z = complex(0,0)
Pen.goto(-size/2, -size/2)
def mandelbrot(point, gen):
z = point
if gen > 0:
mandelbrot(z**2 + c, gen-1)
else:
return (z.real**2 + z.imag**2)**(1/2)
def pixel(point):
if mandelbrot(point, accuracy) > 2:
Pen.fillcolor(1,1,1)
else:
Pen.fillcolor(0,0,0)
Pen.begin_fill()
for i in range (0, 4):
Pen.forward(size/resolution)
Pen.left(90)
Pen.end_fill()
for i in range(0, resolution):
Pen.goto(-size/2, -size/2 + i*size/resolution)
for j in range(0, resolution):
c = complex((-size/2 + j*size/resolution)/size*4,
(-size/2 + i*size/resolution)/size*4)
pixel(c)
Pen.forward(size/resolution)

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):

The code is running but there is not output showing

The code is being executed but the output is not shown nor the variables are created
import numpy as np
def magicsquares():
n=input('enter the order of squares')
n=int(n)
m=np.zeros((n,n))
s=n*(n**2+1)/2 #sum of each row or diagonal
p=int(n/2)
q=(n-1)
for i in range(n**2):
m[p][q]=1 #assigning postion of 1
P=p-1
Q=q+1
if(i>=2): #assigning remaining positions
if(P==-1):
P=n-1
if(Q==n):
Q=0
there is not output showing because you are just declaring the function but not calling the function and there is no print/return inside the function. Here is a solution which you can use to see the output and work on:
import numpy as np
def magicsquares():
n = input('enter the order of squares')
n = int(n)
m = np.zeros((n, n))
s = n*(n**2+1)/2 # sum of each row or diagonal
p = int(n/2)
q = (n-1)
for i in range(n**2):
m[p][q] = 1 # assigning postion of 1
P = p-1
Q = q+1
if i >= 2: # assigning remaining positions
if P == -1:
P = n-1
if Q == n:
Q = 0
print(m)
magicsquares()
It is not the ultimate solution to find magic_square. It's just an updated version of your code so that you can see the outputs and work on.

Why does the lambdify function from sympy throw an error in my case?

The error lies with the lambdify function. It says syntax error for some reason.
This is what is says exactly:
File "D:\Anaconda\lib\site-packages\sympy\utilities\lambdify.py", line 434, in lambdify func = eval(lstr, namespace).
The program crashes right after the user enters the tolerance. This is a Newtons Method program (or at least my attempt at one). Any suggestions on how to improve this code in general would be greatly appreciated too.
What I enter for f and dfdx is the following:
x**3 + 3*x + 5
and
3*x**2 + 3
respectively. As for v0 and eps, I enter 1 and 0.000001 respectively. The program terminates with the aforementioned error no matter what I enter (assuming it uses x as the variable, otherwise it says undefined and that's it).
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f = lambda x : eval('input("Enter the function: ")')
dfdx = lambda x : eval('input("Enter the derivative: ")')
x=sympy.symbols('x')
func = sympy.lambdify(f,x)
deriv = sympy.lambdify(f,x)
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value)/deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
Newton(func,deriv,v0,eps)
AFAIU your cunning plan is to first use Python interpreter to build a function from user's string (using input) and then to use SymPy to build a re-usable function from that. There are a few problems with your code, the most important probably is that you get signature of SymPy methods wrong.
Also idea of providing dfdx as input doesn't look good to me. If the original function f has a good derivative that you can calculate, SymPy can probably calculate it on its own.
So if you fix some obvious mistakes, you may get a code like this:
Python 3.x
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f_inp = lambda x: eval(input("Enter the function: "))
x = sympy.symbols('x')
f_symb = f_inp(x)
func = sympy.lambdify(x, f_symb)
deriv = sympy.lambdify(x, sympy.diff(f_symb, x))
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value) / deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
print (Newton(func, deriv, v0, eps))
Python 2.x
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f_inp = lambda x: input("Enter the function: ")
x = sympy.symbols('x')
f_symb = f_inp(x)
func = sympy.lambdify(x, f_symb)
deriv = sympy.lambdify(x, sympy.diff(f_symb, x))
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value) / deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
print Newton(func, deriv, v0, eps)
which for your input
1
0.000001
x**3 + 3*x + 5
produces following output:
(-1.154171557329764, 5)
The main difference between 2.x and 3.x versions is that input in 2.x calls eval inside while input in 3.x doesn't.

matplotlib.pyplot imshow() now shows a solid blue colour, no longer the colour rendering?

Further to my previous, helpfully addressed, question here
How to centre the origin in the centre of an imshow() plot
after some fiddling about with the some parameters, spyder now consistently shows a blank blue output. It is baffling!!
I've forced the dtype to be uint8 (I read this on a related question that this may be the cause) but to no avail.
EDIT: (Thanks to the rapid responses) here is the relevant code (from a larger program for modelling diffraction through a square aperture):
import numpy as np
import matplotlib.pyplot as plt
def expo(x,y,z,xp,yp,k):
"""
Function of the integrand in Eq. 5
"""
return np.exp((1j*k/(2*z))*(((x-xp)**2) + ((y-yp)**2)))
def square_2dsimpson_eval(a,b,n):
simp_eval = np.zeros((n+1,n+1))
deltap = (b-a)/n
xp = 0
yp = 0
w = np.zeros((n+1,n+1))
x=0
y=0
for h in range(n+1): #the first two for loops produce the 2d Simpson matrix of coeffecients
if h == 0 or h==n:
w[0,h] = 1
elif h%2 != 0:
w[0,h]=4
elif h%2 == 0:
w[0,h]=2
for g in range(n+1):
if g ==0 or g==n:
w[g,0]=1
elif g%2 != 0:
w[g,0]=4
elif g%2 == 0:
w[g,0]=2
for h in range(1,n+1):
for g in range(1,n+1):
w[h,g]=w[0,h]*w[g,0]
for h in range(0,n+1):
xp = h*deltap
for g in range(0,n+1):
yp = g*deltap
simp_eval[h,g] = expo(x,y,z,xp,yp,k) #the integrand
return (k/(2*np.pi*z))*((deltap**2)/9)*(np.sum(simp_eval*w))
n = 3.3
#this loop checks that user's N is even as required for Simpson's rule
while n % 2 != 0:
n = int(input("Type an even N value: "))
if n % 2 == 0:
break
else:
print("n must be even you noob!")
lam=float(input("Type light wavelength in mm: "))
k=(2*np.pi)/lam
z=float(input("Type screen distance, z in mm: "))
rho=float(input("Type rho in mm: "))
delta = 2/n
intensity = np.zeros((n+1,n+1),dtype='uint8')
for i in range(n+1):
x=-1+(i*delta)
for j in range(n+1):
y =-1+(j*delta)
intensity[i,j] = (abs(square_2dsimpson_eval(-rho/2,rho/2,n)))**2
print(intensity.dtype)
plt.imshow(intensity)
plt.show()
The plot has gone from this:
to this:
Thanks in advance.
Without Even knowing the code that produces either image, I can only say that the second image seems to be a cutout of the first image in a region where there is no data or data is close to or equal the minimum value.

Resources