VBA Excel sine cosine functions - excel

I am trying to write a short trig function wanting to use sine and cosine functions in VB and I am very new to this as it's my first time coding in VB.
See what I'm trying to accomplish below:
Function XXX(HR, HR_RL, abc)
Const PI As Double = "3.141593"
AC = Sqr(HR ^ 2 + HR_RL ^ 2 - 2 * HR * HR_RL * Cos(abc * PI / 180))
VB is complaining about two things Cos and Sqr.
It seems they are both built-in VBA functions, but somehow I can't get them evaluated and as a result, AC variable = empty.
In fact, it doesn't seem that it even goes past "Cos(abc * PI / 180)". If I substitute "Cos(abc * PI / 180)" with a numeric value (just to see where else is another problem), surely enough, now VB complains about "Sqr".

Go into your VBA Editor menu and select Tools -> References..., then check the System library. It will give you access to all the math functions.

Related

Is there any method/solver in python to solve embedded derivatives in a ODE equation?

I've got this equation from mathematical model to know the thermal behavior of a battery.
dTsdt = Ts * a+ Ta * b + dTadt * c + d
However, i can't get to solve it due to the nested derivatives.
I need to solve the equation for Ts and Ta.
I tried to define it as follows, but python does not like it and several eŕrors show up.
Im using scipy.integrate and the solver ODEint
Since the model takes data from vectors, it has to be solved for every time step and record the output accordingly.
I also tried assinging the derivatives to a variable v1,v2, and then put everything in an equation without derivatives like the second approach shown as follows.
def Tmodel(z,t,a,b,c,d):
    Ts,Ta= z
    dTsdt = Ts*a+ Ta*b + dTadt*c+ d
    dzdt=[dTsdt]
    return dzdt
z0=[0,0]
# solve ODE
for i in range(0,n-1):
   
    tspan = [t[i],t[i+1]]
    # solve for next step
    z = odeint(Tmodel,z0,tspan,arg=(a[i],b[i],c[i],d[i],))
    # store solution for plotting
    Ts[i] = z[1][0]
    Ta[i] = z[1][1]
    # next initial condition
    z0 = z[1]
def Tmodel(z,t,a,b,c,d):
    Ts,v1,Ta,v2= z
# v1= dTsdt
# v2= dTadt
    v1 = Ts*a+ Ta*b + v2*c+ d
    dzdt=[v1,v2]
    return dzdt
That did not work either.I believe there might be a solver capable of solving that equation or the equation must be decouple in a way and solve accordingly.
Any advice on how to solve such eqtn with python would be appreciate it.
Best regards,
MM
Your difficulty seems to be that you are given Ta in a form with no easy derivative, so you do not know where to take it from. One solution is to avoid this derivative completely and solve the system for y=Ts-c*Ta. Substitute Ts=y+c*Ta in the right side to get
dy/dt = y*a + Ta*(b+c*a) + d
Of course, this requires then a post-processing step Ts=y+c*Ta to get to the requested variable.
If Ta is given as function table, use an interpolation function to get values at any odd time t that is demanded by the ODE solver.
Ta_func = interp1d(Ta_times,Ta_values)
def Tmodel(y,t,a,b,c,d):
Ta= Ta_func(t)
dydt = y*a+ Ta*(b+c*a) + d
return dydt
y[0] = Ts0-c*Ta_func(t[0])
for i in range(len(t)-1):
y[i+1] = odeint(Tmodel,y[i],t[i:i+2],arg=(a[i],b[i],c[i],d[i],))[-1,0]
Ts = y + c*Ta_func(t)

Excel VBA: Implementing Box Muller, Zigurrat and Ratio of Uniforms Algorithm

This is a very specific question mixing up stochastic knowledge and VBA skills. So very exciting!
I'm trying to compare several methods for generating standard, normally distributed numbers given a source of uniformly distributed random numbers. Therefore I'm implementing the Box Muller Algorithm, Ziggurat Algorithm and Ratio of Uniforms Algorithm. Every single implementation works great in terms of generating a clean standard, normally distribution. (checked by Shapiro-Wilk-Test).
What I want to find out: which is the quickest method?
Testing every single program with a total of 10^7 generated numbers these are the run times:
Box-Muller: 3,7 seconds
Ziggurat: 1,28 seconds
Ratio of Uniforms: 10,77 seconds
Actually I am very happy about those readings, because I didn't expect it to be that fast. Of course the run time of every single method depends as well on my programm-skills and VBA knowledge.
My problem: after doing some research I found out that the Ratio of Uniforms Algorithm should be the quickest (about 3 to 4 times quicker than Box Muller). This information just leans on this stack:
I am curious if this is just a wrong claim of this user or (what I do expect more) if my code is not perfectly implemented. Therefore I'll post my code and hope someone could help me with my question, if my code is just not good enough or if the Ratio of Uniforms just doesn't work that quick as mentioned.
Sub RatioUniforms()
Dim x(10000000) As Double
Dim passing As Long
Dim amount As Long: amount = 10000000
Dim u1 As Double
Dim u2 As Double
Dim v2 As Double
Do While passing <= amount
Do
u1 = Rnd 'rnd= random number(0,1)
Loop Until u1 <> 0 'u1 musn't become 0
v2 = Rnd
u2 = (2 * v2 - 1) * (2 * exp(-1)) ^ (1 / 2)
If u1 ^ 2 <= exp(-1 / 2 * u2 ^ 2 / u1 ^ 2) Then
x(passing) = u2 / u1
passing = passing + 1
End If
Loop
End Sub
Thank you very much helping me on this toppic. Maybe some of you have tried those algorithms in VBA or other languages and can help me with there experience about the run time? If you need something else to know about my other implementations just let me know. Have a great day!

Numerical differentiation using Cauchy (CIF)

I am trying to create a module with a mathematical class for Taylor series, to have it easily accessible for other projects. Hence I wish to optimize it as far as I can.
For those who are not too familiar with Taylor series, it will be a necessity to be able to differentiate a function in a point many times. Given that the normal definition of the mathematical derivative of a function will require immense precision for higher order derivatives, I've decided to use Cauchy's integral formula instead. With a little bit of work, I've managed to rearrange the formula a little bit, as you can see on this picture: Rearranged formula. This provided me with much more accurate results on higher order derivatives than the traditional definition of the derivative. Here is the function i am currently using to differentiate a function in a point:
def myDerivative(f, x, dTheta, degree):
riemannSum = 0
theta = 0
while theta < 2*np.pi:
functionArgument = np.complex128(x + np.exp(1j*theta))
secondFactor = np.complex128(np.exp(-1j * degree * theta))
riemannSum += f(functionArgument) * secondFactor * dTheta
theta += dTheta
return factorial(degree)/(2*np.pi) * riemannSum.real
I've tested this function in my main function with a carefully thought out mathematical function which I know the derivatives of, namely f(x) = sin(x).
def main():
print(myDerivative(f, 0, 2*np.pi/(4*4096), 16))
pass
These derivatives seems to freak out at around the derivative of degree 16. I've also tried to play around with dTheta, but with no luck. I would like to have higher orders as well, but I fear I've run into some kind of machine precission.
My question is in it's simplest form: What can I do to improve this function in order to get higher order of my derivatives?
I seem to have come up with a solution to the problem. I did this by rearranging Cauchy's integral formula in a different way, by exploiting that the initial contour integral can be an arbitrarily large circle around the point of differentiation. Be aware that it is very important that the function is analytic in the complex plane for this to be valid.
New formula
Also this gives a new function for differentiation:
def myDerivative(f, x, dTheta, degree, contourRadius):
riemannSum = 0
theta = 0
while theta < 2*np.pi:
functionArgument = np.complex128(x + contourRadius*np.exp(1j*theta))
secondFactor = (1/contourRadius)**degree*np.complex128(np.exp(-1j * degree * theta))
riemannSum += f(functionArgument) * secondFactor * dTheta
theta += dTheta
return factorial(degree) * riemannSum.real / (2*np.pi)
This gives me a very accurate differentiation of high orders. For instance I am able to differentiate f(x)=e^x 50 times without a problem.
Well, since you are working with a discrete approximation of the derivative (via dTheta), sooner or later you must run into trouble. I'm surprised you were able to get at least 15 accurate derivatives -- good work! But to get derivatives of all orders, either you have to put a limit on what you're willing to accept and say it's good enough, or else compute the derivatives symbolically. Take a look at Sympy for that. Sympy probably has some functions for computing Taylor series too.

Difference in Macro vs Manual Output on same formula using LOG

Well its rather a very strange question
I have a macro which generates the delta of a Option(d1):
Function dOne(UnderlyingPrice, ExercisePrice, Time, Interest, Volatility, Dividend)
dOne = (Log(UnderlyingPrice / ExercisePrice) + (Interest - Dividend + (0.5 * Volatility ^ 2)) * Time) / (Volatility * (Sqr(Time)))
End Function
When I pass the the values to it, it generates the desired output:
However when I try to replicate this in Excel, it gives an entirely different output
I know that the calculations for output generated manually are correct.
However the desired values are those generated from VBA.
Please suggest what am I missing here.
The Log function in VBA is the natural log: ln(x).
The LOG function in the formula is log base 10: log10(x).
If you want log base 10 in VBA you will have to use the logarithmic identity for converting bases:
Log(x)/Log(10)
In your case
dOne = (Log(UnderlyingPrice / ExercisePrice) / Log(10) + (Interest - Dividend + (0.5 * Volatility ^ 2)) * Time) / (Volatility * (Sqr(Time)))

Test Visual Basic Scripts behind an Excel Spreadsheet

First of all I need to point out that I have never coded Visual Basic before.
I have an old spreadsheet which has some functions that are apparently written in Visual Basic. An example functions is:
Function Helmert_X(X, Y, Z, DX, Y_Rot, Z_Rot, s)
'Computed Helmert transformed X coordinate.
'Input: - _
cartesian XYZ coords (X,Y,Z), X translation (DX) all in meters ; _
Y and Z rotations in seconds of arc (Y_Rot, Z_Rot) and scale in ppm (s).
'Convert rotations to radians and ppm scale to a factor
Pi = 3.14159265358979
sfactor = s * 0.000001
RadY_Rot = (Y_Rot / 3600) * (Pi / 180)
RadZ_Rot = (Z_Rot / 3600) * (Pi / 180)
'Compute transformed X coord
Helmert_X = X + (X * sfactor) - (Y * RadZ_Rot) + (Z * RadY_Rot) + DX
End Function
I'm trying to convert these functions into C. I have almost finished but what I would like to do is to build a visual basic project that calls the functions with various parameters. Then I will have a C project which uses the same parameters and checks that the C gets the same answers as the Visual Basic.
When I put the Visual Basic functions into a Module in Visual Studio I get a lot of errors. Firstly the comments don't all register as comments, and the variables apparently need to be declared.
Am I using the functions properly? Is there anyway to use them in code without modifying them? Could I use Excel to run test parameters through the functions?
It seems you need to declare all variables that exist in that function. Try to add theses lines after the comments:
Dim Pi As Double
Dim sfactor As Double
Dim RadY_Rot As Double
Dim RadZ_Rot As Double
You can also specify type for variables that came with function, as well the function itself:
Function Helmert_X(X as Double, Y as Double, Z as Double, DX as Double, Y_Rot as Double, Z_Rot as Double, s as Double) as Double
Let me know if it works or if there is still some issue.

Resources