Is there some way of instantiating SymPy symbols so that they are interpreted as being in a specified interval?
Instantiate two SymPy symbols
x = symbols('x', real=True)
R = symbols('R', nonnegative=True)
and then take the square root of their squares. sqrt(x**2) correctly returns |x|. SymPy is smart enough to realize that taking the absolute value of a nonnegative quantity returns that same quantity, so sqrt(R**2) returns R rather than |R|. The difference in behavior traces to R's instantiation as nonnnegative.
Suppose we have a real symbol theta. Then sqrt(sin(theta)**2) returns |sin(theta)|. Is there a way of telling SymPy that the value of theta is to lie between 0 and pi, from which nonnegativity of sin(theta) follows? Would SymPy then return simply sin(theta) in response to sqrt(sin(theta)**2) ?
Related
I am trying to multiply a symbol with a matrix which is defined by QuTip quantum object, but I got this error:
TypeError: Incompatible object for multiplication
I used:
from qutip import *
import sympy as sp
w0 = sp.Symbol('\omega_{0}')
w0*destroy(4)
Did I miss something?
The object destroy(4) contains a lot more information than just the matrix representation of the annihilation operator, so its represented as the type Qobj in qutip. The type Qobj currently doesn't support multiplication with the type sympy.Symbol. Note that you can look under the __rmul__ method of Qobj to find which types are supported for multiplying with Qobj on the right.
If you're happy working with the matrix representations of these operators you could do the following to multiply a symbol with the matrix corresponding to destroy(4). The following will work:
w0 * destroy(4).data.todense()
This will be a numpy matrix containing symbols, and you can multiply it with the matrices corresponding to other operators in your calculation (at a great loss of efficiency!).
Otherwise this might be worth posting an issue on their github. An implementation might be possible based on how __rmul__ is dispatched to numbers.Number here.
While the result of the my linear programming model in Cplex seems to make sense, the q variable sometimes randomly (at least to me it seems random) shows tiny values such as 4e^-14. This doesn't have an effect on the decision variable but is still very irritating as I am not sure if something in my model isn't correct. You can see the results of the q variable with the mini residuals here: Results q variable. These residuals only started appearing in my model once I introduced binary variables.
q is defined as: dexpr float q [t in Years, i in Options] = (c[i] * (a[t+s[i]][i]-a[t+s[i]-1][i]));
a is a decision variable
This is a constraint q is subject to: q[i][t] == a[i] * p[i]* y[t][i])
Since y is a binary variable, q should either be the value of a[i] * p[i] or 0. This is why I am very irritated with the residual values.
Does anybody have any idea why these values appear and how to get rid of them? I have already spent a lot of time on this problem and no idea how to solve it.
Things I noticed while trying to solve it:
Turning all the input variables into integer variables doesn't change
anything
Turning q into an integer variable solves the problem, but ruins the model since a[i][t] needs to be a float variable
Adding a constraint making q >= 0 does not eliminate the negative residual values such as -4e^-14
Adding a constraint making q = 0 for a specific t helps eliminate the residual values there, but of course also ruins the model
Thank you very much for your help!
This is a tolerance issue. MIP solvers such as Cplex have a bunch of them. The ones in play here are integer feasibility tolerance (epint) and the feasibility tolerance (eprhs). You can tighten them, but I usually leave them as they are. Sometimes it helps to round results before printing them or just use fewer digits in the formatting of the output.
I'd like to integrate the following and easyfunction in sympy.
import sympy
x = sympy.symbols('x')
e_a = 1/(1-x)
u_x = sympy.integrate(e_a,x)
print(u_x)
sympy.plot(u_x)
My calculus memories suggests me to get -log(1-x) as a result, while sympy returns -log(x - 1). Can't understand what's wrong with the code...
Both -log(1-x) and -log(x-1) are valid answers. This was discussed on issue tracker, so I quote from there.
-log(x-1)=-(log(1-x)+log(-1)) by log rules, and log(-1)=i*pi (as e**(i*pi)=-1). -log(x-1) is the same as -log(1-x)-i*pi so the expressions actually differ by a constant, which makes no difference to the result when taking the derivative of the expression.
and
This is indeed correct behavior. SymPy doesn't return log(abs(x)) for integrate(1/x) because it isn't valid for complex numbers. Instead, the answer is correct up to an integration constant (which may be complex). All SymPy operations assume that variables are complex by default.
There are some workarounds suggested at the end of the thread.
But the bottom line, -log(x-1) is correct, and it is the desired form of answer when x is greater than 1. SymPy does not know if you mean for x to be less than 1 or greater than 1.
To get a specific antiderivative, integrate from a given initial point. For example, integration starting from 0 gives the antiderivative that is 0 when x=0.
x, t = sympy.symbols('x t')
e_a = 1/(1-x)
u_x = sympy.integrate(e_a, (x, 0, t)).subs(t, x)
sympy.plot(u_x)
I'm using statsmodels library for generic likelihood models. As I have a quite complicated likelihood function, I used sympy to calculate gradient and hessian for me. This works fine, but it is too slow for my needs, because likelihood function contains term b0*x0 + b1*x1 + ... + bn*xn. That way hessian size increases by N^2 and so does the complexity.
Elements of the hessian are often pretty similar like expensive_operation * x0 and expensive_operation * x1, etc. It means that if I could pre-calculate expensive_operation and use it in functions in hessian, I would drastically increase performance.
So the question is - is there a tool which would take list of functions, optimize them and then evaluate them effectively? Something like numexpr which would take list of functions?
SymPy has cse, which stands for common subexpression elimination. See the docs.
A simple example:
>>> print(cse(sin(x**2)*cos(x**2) + 2*sin(x**2) - cos(x**2)))
([(x0, x**2), (x1, sin(x0)), (x2, cos(x0))], [x1*x2 + 2*x1 - x2])
after optimization, I calculate the residuals with optimal parameters both in Python and C++. The gap in results is huge. Here is how I proceed more precisely:
I generate data according to a parametric model in Python. I store X and Y in Excel file. I load this file in my C++ program and run optimization. I come up with optimal parameters, that are pretty close to parameters used to generate the series. I then compute residuals (sum of squared difference between Y and model output with optimal parameters), in Python and with C++. Results are huge, with up to 10^3 difference for models that are very sensible to changes in parameters. Can these differences be imputable to different way to deal with precision in Python and C++, or can something else be wrong? Once optimization is finished, residuals computation is a simple calculation, and I wonder where the problem could lie if not in precision matter.
Thanks a lot for any advice or reference.
EDIT --- I can easily show Python code for generating data and calculating sum of squared residuals, but not C++ code since calculation is performed via an interpreter. Thanks for any comments.
P1 = 5.21
P2 = 0.22
X_= list(range(0,100,1))
X=[float(x)/float(10) for x in X_]
Y = [P1*numpy.exp(-1*P2*x) for x in X]
##plt.plot(X,Y)
##plt.show()
##for j in range(len(Y)):
## Y[j]+=rg.normal(0,0.01)
#build some input files
X1f = open('F:\WORK\SOLVEUR\ALGOCODE\PYTHON_\DataSets\exponential1X.txt', 'w')
for i in range(len(X)):
X1f.write(str(X[i])+'\n')
X1f.close()
Yf = open('F:\WORK\SOLVEUR\ALGOCODE\PYTHON_\DataSets\exponential1Y.txt', 'w')
for i in range(len(Y)):
Yf.write(str(Y[i])+'\n')
Yf.close()
def func_exp_1(param, x1, y):
p1, p2 = param
res = sum((y_i - p1*numpy.exp(-1*p2*x))**2 for x1_i, y_i in zip(x1, y))
return res
print func_exp_1([5.2132,0.2202],x1,y)
Both Python and C++ use the machine native format; Python's float is
the equivalent of C++'s double. Any differences
would be due to differences in the way the algorithm is implemented,
or, if the hardward has an extended format which is used for
intermediate values (the case for Intel), when and where the language
stores the values back to memory—values will probably be stored to
memory more often in Python than in C++. Without seeing exact code,
it's impossible to say more (but the sum of a large number of elements
can be off significantly, depending on the order and relative magnitudes
of the elements).