Solving for polynomial roots in Stata - stata

I am trying to solve for the roots of a function in Stata. There is the "polyeval" command under Mata, but I am not sure how to apply it here. It seems to me as if under polyeval functions must follow a very clear structure of x^2 + x + c.
I would like to find out more about how to use Stata to solve this type of problem in general. But here is my current one, if that provides some idea of what I am working with.
I am currently trying to solve the Black (1976) American Options pricing model:
C = e^{-rt} [ F N(d1) - E N(d2)]
where,
d1 = [ln(F/E) + 1/2 simga^2 t] / [sigma sqrt{t}]
d2 = d1 - sigma sqrt{t}
where C is the price of call option, t is time to expiration, r is interest rate, F is current futures price of contract, E is strike price, sigma is the annualized standard deviation of the futures contract. N(d1) and N(d2) are cumulative normal probability functions. All variables are known except for sigma.
As an aside, this seems to be really easy to do in R:
fun <- function(sigma) exp(-int.rate* T) * (futures * pnorm((log(futures/Strike)+ sigma^2 * T/2) / sigma * sqrt(T),0,1)- Strike * pnorm((log(futures/Strike)+ sigma^2 * T/2) / sigma * sqrt(T)- sigma * sqrt(T),0,1) ) - Option
uni <- uniroot(fun, c(0, 1), tol = 0.001 )
uni$root
Does anyone have any ideas/pointers on how to use Stata to solve this type of function?

Related

How to solve an algebraic equation in formal power series?

Motivation. It is well known that generating function for Catalan numbers satisfies quadratic equation. I would like to have first several coefficients of a function, implicitly defined by an algebraic equation (not necessarily a quadratic one!).
Example.
import sympy as sp
sp.init_printing() # math as latex
from IPython.display import display
z = sp.Symbol('z')
F = sp.Function('F')(z)
equation = 1 + z * F**2 - F
display(equation)
solution = sp.solve(equation, F)[0]
display(solution)
display(sp.series(solution))
Question. The approach where we explicitly solve the equation and then expand it as power series, works only for low-degree equations. How to obtain first coefficients of formal power series for more complicated algebraic equations?
Related.
Since algebraic and differential framework may behave differently, I posted another question.
Sympy: how to solve differential equation in formal power series?
I don't know a built-in way, but plugging in a polynomial for F and equating the coefficients works well enough. Although one should not try to find all coefficients at once from a large nonlinear system; those will give SymPy trouble. I take iterative approach, first equating the free term to zero and solving for c0, then equating 2nd and solving for c1, etc.
This assumes a regular algebraic equation, in which the coefficient of z**k in the equation involves the k-th Taylor coefficient of F, and does not involve higher-order coefficients.
from sympy import *
z = Symbol('z')
d = 10 # how many coefficients to find
c = list(symbols('c:{}'.format(d))) # undetermined coefficients
for k in range(d):
F = sum([c[n]*z**n for n in range(k+1)]) # up to z**k inclusive
equation = 1 + z * F**2 - F
coeff_eqn = Poly(series(equation, z, n=k+1).removeO(), z).coeff_monomial(z**k)
c[k] = solve(coeff_eqn, c[k])[0]
sol = sum([c[n]*z**n for n in range(d)]) # solution
print(series(sol + z**d, z, n=d)) # add z**d to get SymPy to print as a series
This prints
1 + z + 2*z**2 + 5*z**3 + 14*z**4 + 42*z**5 + 132*z**6 + 429*z**7 + 1430*z**8 + 4862*z**9 + O(z**10)

Runge Kutta in Fortran

I'm trying to implement the Runge Kutta method in Fortran and am facing a convergence problem. I don't know how much of the code I should show, so I'll describe the problem in detail, and please guide me as to what I should add/remove to/from the post to make it answerable.
I have a 6-dimensional vector of position and velocity of a ball, and a corresponding system of diff. eqs. that describe the equations of motions, from which I want to calculate the trajectory of the ball, and compare results for different orders of the RK method.
Let's focus on 3rd order RK. The model I use is implemented as follows:
k1 = h * f(vec_old,omega,phi)
k2 = h * f(vec_old + 0.5d0 * k1,omega,phi)
k3 = h * f(vec_old + 2d0 * k2 - k1,omega,phi)
vec = vec_old + (k1 + 4d0 * k2 + k3) / 6d0
Where f is the function that constitutes the equations of motion (or equivalently the RHS of my system of diff. eqs). Note that f is time independent, therefore has only 1 argument. h takes the role of a small time step dt.
If we wish to calculate the trajectory of the ball for a finite time total_time, and allow for a total error of epsilon, then we need to ensure each step takes a proportional fraction of the error. For the first step, I then did the following:
vec1 = solve(3,vec_old,h,omega,phi)
vec2 = solve(3,vec_old,h/2d0,omega,phi)
do while (maxval((/(abs(vec1(i) - vec2(i)),i=1,6)/)) > eps * h / (tot_time - current_time))
h = h / 2d0
vec1 = solve(3,vec_old,h,omega,phi)
vec2 = solve(3,vec_old,h/2d0,omega,phi)
end do
vec = (8d0/7d0) * vec2 - (1d0/7d0) * vec1
Where solve(3,vec_old,h,omega,phi) is the function that calculates the single RK step described above. 3 denotes the RK order we are using, vec_old is the current state of the position-velocity vector, h, h/2d0 both represent the time step being used, and omega,phi are just some extra parameters for f. Finally, for the first step we set current_time = 0d0.
The point is that if we use a 3rd order RK, we should have an error in $O(h^3)$, and thus fall off faster than linearly in h. Therefore, we should expect the while loop to eventually come to a halt for small enough h.
My problem is that the loop doesn't converge, and not even close - the ratio
maxval(...) / eps * (...)
remains pretty much constant, all the way until eps * h / (tot_time - current_time)) becomes zero due to finite precision.
For completeness, this is my definition for f:
function f(vec_old,omega,phi) result(vec)
real(8),intent(in) :: vec_old(6),omega,phi
real(8) :: vec(6)
real(8) :: v,Fv
v = sqrt(vec_old(4)**2+vec_old(5)**2+vec_old(6)**2)
Fv = 0.0039d0 + 0.0058d0 / (1d0 + exp((v-35d0)/5d0))
vec(1) = vec_old(4)
vec(2) = vec_old(5)
vec(3) = vec_old(6)
vec(4) = -Fv * v * vec_old(4) + 4.1d-4 * omega * (vec_old(6)*sin(phi) - vec_old(5)*cos(phi))
vec(5) = -Fv * v * vec_old(5) + 4.1d-4 * omega * vec_old(4)*cos(phi)
vec(6) = -Fv * v * vec_old(6) - 4.1d-4 * omega * vec_old(4)*sin(phi) - 9.8d0
end function f
Does anyone have any idea as to why the while loop doesn't converge?
If anything else is needed (output, other pieces of code etc.) please tell me and I'll add it. Also, if trimming is required, I'll cut whatever would be considered unnecessary. Thanks!
To compute the step error using the half step method, you need to compute the approximation at t+h in both cases, which means two steps with step size h/2. As it is now you compare the approximation at t+h to the approximation at t+h/2 which gives you an error of size f(vec(t+h/2))*h/2.
Thus change to a 3-step procedure
vec1 = solve(3,vec_old,h,omega,phi)
vec2 = solve(3,vec_old,h/2d0,omega,phi)
vec2 = solve(3,vec2 ,h/2d0,omega,phi)
in both locations, the difference of vec2-vec1 should then be of order h^4.

Calculating the area of overlap of two functions

Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
I have two functions. I am giving here the basic structure only, as they have quite a few parameters each to adjust their exact shape.
For example, y = sin(.1*pi*x)^2 and y = e^-(x-5)^2.
The question is how much area of the sine is captured by the e function:
I tried to be clever and recursively find the points of intersection, but that turned out to be a lot more work than was necessary.
As n.m. pointed out, you want the integral from a to b of min(f, g). Since you're integrating by approximation, you're already stepping through the interval, meaning you can check at each step which function is greater and compute the area of the current trapezoid.
Simple implementation in C:
#define SLICES 10000
/*
* Computes the integral of min(f, g) on [a, b].
*
* Intended use is for when f and g are both non-negative, real-valued
* functions of one variable.
*
* That is, f: R -> R and g: R -> R.
*
* Assumes b ≥ a.
*
* #param a left boundary of interval to integrate over
* #param b right boundary of interval to integrate over
* #param f function accepting one double argument which returns a double
* #param g function accepting one double argument which returns a double
* #return integral of min(f, g) on [a, b]
*/
double minIntegrate (double a, double b, double (*f)(double), double (*g)(double)) {
double area = 0.0;
// the height of each trapezoid
double deltaX = (b - a) / SLICES;
/*
* We are integrating by partitioning the interval into SLICES pieces, then
* adding the areas of the trapezoids formed to our running total.
* To save a computation, we can cache the last side encountered.
* That is, let lastSide be the minimum of f(x) and g(x), where x was the
* previous "fence post" (side of the trapezoid) encountered.
* Initialize lastSide with the minimum of f and g at the left boundary.
*/
double lastSide = min(f(a), g(a));
// The loop starts at 1 since we already have the last (trapezoid) side
// for the 0th fencepost.
for (int i = 1; i <= SLICES; i++) {
double fencePost = a + (i * deltaX);
double currentSide = min(f(fencePost), g(fencePost));
area += trapezoid(lastSide, currentSide, deltaX);
lastSide = currentSide;
}
return area;
}
/*
* Computes the area of a trapezoid with bases `a` and `b` and height `height`.
*/
double trapezoid (double a, double b, double height) {
return h * (a + b) / 2.0;
}
If you're looking for something really, really simple, why don't you do Monte Carlo Integration?
Use the fact that the functions are easy to calculate to sample a large number of points. For each point, check whether it's below 0, 1, or 2 of the curves.
You might have some fiddling to find the boundaries for the sampling, but this method will work for a variety of curves.
https://en.wikipedia.org/wiki/Monte_Carlo_integration
I'm guessing your exponential is actually of the form e^-(x-5)^2 so that the exponential decays to zero at plus/minus infinity.
Given that, your integral would be most quickly and accurately calculated by something called Gaussian quadrature. There are a few types of common integrals which have very simple solutions using different polynomials (Hermite, Legendre, etc.). Yours specifically looks like it could be solved using Gauss-Hermite quadrature.
Hope this helps.

Parameter optimization using a genetic algorithm?

I am trying to optimize parameters for a known function to fit an experimental data plot. The function is fairly involved
where x sweeps along a know set of numbers and p, g and c are the independent parameters to be optimized. Any ideas or resources that could be of assistance?
I would not recommend Genetic Algorithms. Instead go for straight forward Optimization.
Scipy has some resources.
You haven't provided any data or so, so I'll just go for something that should run. Below is something to get you started. I can't know if it works without seeing the data. Also, there must probably is a way to dynamically feed objectivefunc your x and y data. That's probably in the docs to scipy.optimize.minimize.
What I've done. Create a function to minimize. Here, I've called it objectivefunc. For that I've taken your function y = x^2 * p^2 * g / ... and transformed it to be of the form x^2 * p^2 * g / (...) - y = 0. Then square the left hand side and try to minimise it. Because you will have multiple (x/y) data samples, I'd minimise the sum of the squares. Put it all in a function and pass it to the minimize from scipy.
import numpy as np
from scipy.optimize import minimize
def objectivefunc(pgq):
"""Your function transformed so that it can be minimised.
I've renamed the input pgq, so that pgq[0] is p, pgq[1] is g, etc.
"""
p = pgq[0]
g = pgq[1]
q = pgq[2]
x = [10, 9.4, 17] # Some input data.
y = [12, 42, 0.8]
sum_ = 0
for i in range(len(x)):
sum_ += (x[i]**2 * p**2 * g - y[i] * ( (c**2 - x**2)**2 + x**2 * g**2) )**2
return sum_
pgq = np.array([1.3, 0.7, 0.5]) # Supply sensible initivial values
res = minimize(objectivefunc, pgq, method='nelder-mead',
options={'xtol': 1e-8, 'disp': True})
Have you tired old good Levenberg-Marquardt as implemented in Levenberg-Marquardt.vi. If it does not suite your needs, you can try Waptia libraryfor LabVIEW with one of the genetic algorithms implemented.

Polynomial fitting using L1-norm

I have n points (x0,y0),(x1,y1)...(xn,yn). n is small (10-20). I want to fit these points with a low order (3-4) polynomial: P(x)=a0+a1*x+a2*x^2+a3*x^3.
I have accomplished this using least squares as error metric, i.e. minimize f=(p0-y0)^2+(p1-y1)^2+...+(pn-yn)^2. My solution is utilizing singular value decomposition (SVD).
Now I want to use L1 norm (absolute value distance) as error metric, i.e. minimize f=|p0-y0|+|p1-y1|+...+|pn-yn|.
Are there any libraries (preferably open source) which can do this, and that can be called from C++? Is there any source code available which can be quickly modified to suit my needs?
L_1 regression is actually quite simply formulated as a linear program. You want to
minimize error
subject to x_1^4 * a_4 + x_1^3 * a_3 + x_1^2 * a_2 + x_1 * a_1 + a_0 + e_1 >= y_1
x_1^4 * a_4 + x_1^3 * a_3 + x_1^2 * a_2 + x_1 * a_1 + a_0 - e_1 <= y_1
.
.
.
x_n^4 * a_4 + x_n^3 * a_3 + x_n^2 * a_2 + x_n * a_1 + a_0 + e_n >= y_n
x_n^4 * a_4 + x_n^3 * a_3 + x_n^2 * a_2 + x_n * a_1 + a_0 - e_n <= y_n
error - e_1 - e_2 - ... - e_n = 0.
Your variables are a_0, a_1, a_2, a_3, a_4, error, and all of the e variables. x and y are the data of your problem, so it's no problem that x appears to second, third, and fourth powers.
You can solve linear programming problems with GLPK (GPL) or lp_solve (LGPL) or any number of commercial packages. I like GLPK and I recommend using it if its licence is not a problem.
Yes, it should be doable. A standard way of formulating polynomial fitting problems as a multiple linear regression is to define variables x1, x2, etc., where xn is defined as x.^n (element-wise exponentiation in Matlab notation). Then you can concatenate all these vectors, including an intercept, into a design matrix X:
X = [ 1 x1 x2 x3 ]
Then your polynomial fitting problem is a regression problem:
argmin_a ( | y - X * a| )
where the | | notation is your desired cost function (for your case, L1 norm) and a is a vector of weights (sorry, SO doesn't have good math markups as far as I can tell). Regressions of this sort are known as "robust regressions," and Numerical Recipes has a routine to compute them: http://www.aip.de/groups/soe/local/numres/bookfpdf/f15-7.pdf
Hope this helps!
The problem with the L1 norm is that it's not differentiable, so any minimisers which rely on derivatives may fail. When I've tried to minimise those kinds of functions using e.g. conjugate gradient minimisation, I find that the answer gets stuck at the kink, i.e. x=0 in the function y=|x|.
I often solve these mathematical computing problems from first principles. One idea that might work here is that the target function is going to be piecewise linear in the coefficients of your low-order polynomial. So it might be possible to solve by starting from the polynomial that comes out of least squares, and then improving the solution by solving a series of linear problems, but each time only stepping from your current best solution to the nearest kink.