Solve a Quadratic Equation in two variables using Python - linear-algebra

I have got two equations, one linear say,
, where m and c are constants
and the other quadratic say,
, where x1, y1 and r are constants.
Is there a way I can solve for x and y using Python ?
I could solve them on pen and paper finding the relation between x and y from the linear equation and substituting it in the other. There would be two roots satisfying the quadratic equation.

Look at SymPy.
Here is an example of how to solve a simple difference of squares equation, taken from their documentation.
>>> from sympy.solvers import solve
>>> from sympy import Symbol
>>> x = Symbol('x')
>>> solve(x**2 - 1, x)
[-1, 1]
Regarding your specific problem, the solution will look something like this:
>>> x = Symbol('x')
>>> y = Symbol('y')
>>> solve( (x-c1)**2 + (y-c2)**2 - c3**2, x, y)
c1, c2 and c3 are the constants declared as variables earlier in your code.

Provided we know the constants: m, c, x1, y1, r ; the code should look like this:
import sympy as sym
x,y = sym.symbols('x,y')
Eq1 = sym.Eq(y-mx,c)
Eq2 = sym.Eq((x-x1)**2 + (y-y1)**2, r**2)
sol = sym.solve([Eq1,Eq2],(x,y))

Related

Julia how to get coefficients out of SymPy solveset

I'm using symbolic math in Julia. When I do the differentiation it comes out very nicely, but I cant get the coefficients out
using SymPy
#vars x y
z = x*(10 + 5*x + 4*y)
dz = diff(z,x)
x_s = solveset(dz,x)
how do I get the the coefficients out of x_s?
You can use elements to get the elements of a finite sets as an array:
julia> elements(s)
1-element Array{Sym,1}:
-2*y/5 - 1
To get the coefficients can be done different ways, but here we convert the value to a Polynomial type, then use its coeffs method:
julia> p = sympy.Poly(elements(s)[1], y)
Poly(-2/5*y - 1, y, domain='QQ')
julia> p.coeffs()
2-element Array{Sym,1}:
-2/5
-1
As per my comment, the following works but isn't exactly what I'd describe as pretty:
julia> x_s.__pyobject__.args[1].__pyobject__.args[1]
-1
julia> x_s.__pyobject__.args[1].__pyobject__.args[2]
-2⋅y
─────
5
julia> x_s.__pyobject__.args[1].__pyobject__.args[2].__pyobject__.args[1]
-2/5
I couldn't find an accessor function in Sympy.jl that simplifies this, but as you say this could be the basis for rolling your own.

Is there any way to linearize x-x^2<=0?

I am trying to solve an optimization problem.
The objective function and all constraints of this problem are linear except x-x^2<=0.
Is there any way to linearize x-x^2<=0, where x is a continuous variable?
Note that x is not in the objective function.
The usual approach is to convert the problem to an iterative, non-linear one where you solve for increments:
f(x) = x - x^2
df/dx = 1 -2x
Make an initial guess x0; take a step for dx; solve for df; calculate x1 = x0 + dx and f1 = f0 + df and iterate until convergence.
You might look into optimization with constraints. Read up on Lagrange multipliers.

Julia Linear Regression

I was trying to fit a linear regression in Julia.
I have a data frame with 10 columns. The first 9 columns are the predictors
I call it X and the last column is the response variable I call it Y
I typed linreg(X, Y) But I get an error message saying
linreg has no method matching DataFrame and DataArray Float.
I was wondering how I could fix the issue.
I was thinking of converting X to a data Array
I tried convert(X, Array) But that threw an error as well:
'Convert has no method matching convert'
Does anyone have any suggestions
If you already have your data in a DataFrame, you should take a look at the GLM.jl package.
Specifically the lm function should do what you want and feel very familiar if you are an R user.
If you post more code (maybe which columns in your DataFrame store X and Y) we could help you further.
update: have to use dot operator in Julia 1.0 while performing scalar addition on arrays. i.e. y = m*x .+ b
You can also do linear regression using simple linear algebra.
Here is an example:
# Linear Algebra style
# For single linear regresion y= mx .+ b
m = 3.3; b = 2; x = rand(100,1)
y = m * x .+ b
# add noise
yn= y + randn(size(y)) * 0.5
# regression
X = zeros(100,2); X[:,1] = x; X[:,2] = 1.0
coeff_pred = X\yn
slope = round(coeff_pred[1], 2)
intercept = round(coeff_pred[2], 2)
println("The real slope is $m, and the predicted slope is $slope")
println("The real intercept is $b, and the predicted slope is $intercept")
You are just using convert wrong. The correct syntax is convert(T, x) it reads: convert x to a value of type T.
so basically you need to do:
linreg(convert(Array,X),convert(Array,Y))
and it should work.

How to obtain the numerical solution of these differential equations with matlab

I have differential equations derived from epidemic spreading. I want to obtain the numerical solutions. Here's the equations,
t is a independent variable and ranges from [0,100].
The initial value is
y1 = 0.99; y2 = 0.01; y3 = 0;
At first, I planned to deal these with ode45 function in matlab, however, I don't know how to express the series and the combination. So I'm asking for help here.
**
The problem is how to express the right side of the equations as the odefun, which is a parameter in the ode45 function.
**
Matlab has functions to calculate binomial coefficients (number of combinations) and the finite series can be expressed just as matrix multiplication. I'll demonstrate how that works for the sum in the first equation. Note the use of the element-wise "dotted" forms of the arithmetic operators.
Calculate a row vector coefs with the constant coefficients in the sum as:
octave-3.0.0:33> a = 0:20;
octave-3.0.0:34> coefs = log2(a * 0.05 + 1) .* bincoeff(20, a);
The variables get combined into another vector:
octave-3.0.0:35> y1 = 0.99;
octave-3.0.0:36> y2 = 0.01;
octave-3.0.0:37> z = (y2 .^ a) .* ((1 - y2) .^ a) .* (y1 .^ a);
And the sum is then just evaluated as the inner product:
octave-3.0.0:38> coefs * z'
The other sums are similar.
function demo(a_in)
X = [0;0;0];
T = [0:.1:100];
a = a_in; % for nested scope
[Xout, Tout ]= ode45( #myFunc, T, X );
function [dxdt] = myFunc( t, x )
% nested function accesses "a"
dxdt = 0*x + a;
% Todo: real value of dxdt.
end
end
What about this, and you simply need to fill in the dxdt from your math above? It remains to be seen if the numerical roundoff matters...
Edit: there's a serious issue due to the 1=y1+y2+y3 constraint. Is that even allowed, since you have an IVP with 3 initial values given and 3 first order ODE's? If that constraint is a natural consequence of the equations, it may not be needed.

Computation of numerical integral involving convolution

I have to solve the following convolution related numerical integration problem in R or perhaps computer algebra system like Maxima.
Integral[({k(y)-l(y)}^2)dy]
where
k(.) is the pdf of a standard normal distribution
l(y)=integral[k(z)*k(z+y)dz] (standard convolution)
z and y are scalars
The domain of y is -inf to +inf.
The integral in function l(.) is an indefinite integral. Do I need to add any additional assumption on z to obtain this?
Thank you.
Here is a symbolic solution from Mathematica:
R does not do symbolic integration, just numerical integration. There is the Ryacas package which intefaces with Yacas, a symbolic math program that may help.
See the distr package for possible help with the convolution parts (it will do the convolutions, I just don't know if the result will be integrable symbolicly).
You can numerically integrate the convolutions from distr using the integrate function, but all the parameters need to be specified as numbers not variables.
For the record, here is the same problem solved with Maxima 5.26.0.
(%i2) k(u):=exp(-(1/2)*u^2)/sqrt(2*%pi) $
(%i3) integrate (k(x) * k(y + x), x, minf, inf);
(%o3) %e^-(y^2/4)/(2*sqrt(%pi))
(%i4) l(y) := ''%;
(%o4) l(y):=%e^-(y^2/4)/(2*sqrt(%pi))
(%i5) integrate ((k(y) - l(y))^2, y, minf, inf);
(%o5) ((sqrt(2)+2)*sqrt(3)-2^(5/2))/(4*sqrt(3)*sqrt(%pi))
(%i6) float (%);
(%o6) .02090706601281356
Sorry for the late reply. Leaving this here in case someone finds it by searching.
I try to do something similar in matlab, where I convolute two random (Rayleigh distributed) variables. The result of fz_fun is equal to fy_fun, I don't know why. Maybe some here knows it?
sigma1 = 0.45;
sigma2 = 0.29;
fx_fun =#(x) [0*x(x<0) , (x(x>=0)./sigma1^2).*exp(-0.5*(x(x>=0)./sigma1).^2)];
fy_fun =#(y) [0*y(y<0) , (y(y>=0)./sigma2^2).*exp(-0.5*(y(y>=0)./sigma2).^2)];
% Rayleigh distribution of random var X,Y:
step = 0.1;
x= -2:step:3;
y= -2:step:3;
%% Convolution:
z= y;
fz = zeros(size(y));
for i = 1:length(y)
fz_fun(i) = integral(#(z) fy_fun(y(i)).*fx_fun(z-y(i)),0,Inf); % probability density of random variable z= x+y
end

Resources