translating a Basic program; stuck on ^(-1/2) and ^(3/2) - basic

I am trying to translate a BASIC program. It has been many decades since I did any BASIC programming. :)
I am having a problem with 2 lines of code:
360 D=D+((X(I)-X(J))^2+(Y(I)-Y(J))^2+(Z(I)-Z(J))^2)^(-1/2)
510 F=((X(I)-X(J))^2+(Y(I)-Y(J))^2+(Z(I)-Z(J))^2)^(3/2)
x(i) etc form (x,y,z) coordinates; so line 360 is - I think - calculating the distance between 2 points; that would work if ^(-1/2) = square-root.
Line 510 is very similar, but the ^(3/2) has me stumped.
Is it sensible to raise a number to the power of 1.5?
I remember that ^2 means square (aka raise to the power 2).
So, can someone please tell me what ^(-1/2) and ^(3/2) mean in BASIC!?
Thanks for you help.
Steve.

Is it sensible to raise a number to the power of 1.5?
Yes. There is an ordinary arithmetical meaning to raising any number to any power. In this case it is equivalent to cubing then square-rooting (or square-rooting then cubing, as multiplication is commutative).
^(-1/2) = square-root.
Not quite. Raising a number to a negative power is equivalent to finding the reciprocal of having raised it to a positive power, so that is a "1 divided by square root X" operation

In BASIC the following is true:
360 D = D + ((X(I) - X(J)) ^ 2 + (Y(I) - Y(J)) ^ 2 + (Z(I) - Z(J)) ^ 2) ^ (-1 / 2)
361 D = D + 1 / SQR((X(I) - X(J)) ^ 2 + (Y(I) - Y(J)) ^ 2 + (Z(I) - Z(J)) ^ 2)
510 F = ((X(I) - X(J)) ^ 2 + (Y(I) - Y(J)) ^ 2 + (Z(I) - Z(J)) ^ 2) ^ (3 / 2)
511 F = SQR(((X(I) - X(J)) ^ 2 + (Y(I) - Y(J)) ^ 2 + (Z(I) - Z(J)) ^ 2) ^ 3)

These functions should report arrays of equal values:
DIM x(10) AS INTEGER, y(10) AS INTEGER, z(10) AS INTEGER
FOR x = 1 TO 10
x(x) = x: y(x) = x: z(x) = x
NEXT
I = INT(RND * 10 + 1): J = INT(RND * 10 + 1)
D1 = ((x(I) - x(J)) ^ 2 + (y(I) - y(J)) ^ 2 + (z(I) - z(J)) ^ 2) ^ (-1 / 2)
D2 = 1 / SQR((x(I) - x(J)) ^ 2 + (y(I) - y(J)) ^ 2 + (z(I) - z(J)) ^ 2)
F1 = ((x(I) - x(J)) ^ 2 + (y(I) - y(J)) ^ 2 + (z(I) - z(J)) ^ 2) ^ (3 / 2)
F2 = SQR(((x(I) - x(J)) ^ 2 + (y(I) - y(J)) ^ 2 + (z(I) - z(J)) ^ 2) ^ 3)
IF D1 = D2 THEN PRINT "values equal to:"; D1
IF F1 = F2 THEN PRINT "values equal to:"; F1
END

Three-dimensional coordinate systems from google:
The distance formula states that the distance between two points in xyz-space is
the square root of the sum of the squares of the differences between corresponding
coordinates. That is, given P1 = (x1,y1,z1) and P2 = (x2,y2,z2), the distance
between P1 and P2 is given by d(P1,P2) = sqr((x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2)
So, apparently, you can get the distance between 2 xyz points..

Related

How to write this formula in VBA?

I have this formula to solve.
enter image description here
And here is my code that outputs an error in the formula.
Private Sub CommandButton6_Click()
Dim Z As String
Dim X As Double, Y As Double
Z = InputBox("Input number X!", "Inputing number X"): X = Val(Z)
Y = Sqr(2 * ((X - 2) ^ 2) * ((8 - X) - 1)^1/3
MsgBox ("Y =" + Str(Y))
End Sub
Taking into account when we get negative result under the root
Y = (2 * ((X - 2) ^ 2) * (8 - X) - 1)
If Y >= 0 Then
Y = Y ^ (1 / 3)
Else
Y = -(Abs(Y) ^ (1 / 3))
End If
This is the answer for your 2nd question in comments
Y = (2 * (X ^ 2) * (X - 6))
If Y >= 0 Then
Y = 1 + (Y ^ (1 / 3))
Else
Y = 1 - (Abs(Y) ^ (1 / 3))
End If
You can add round if you want, but haven't seen any rounding used in the image link.

Why function gives #value even though msgbox show right calculated value

I am creating a function that calculate the input from an Excel spreadsheet. However, the function is returning #value!. When I checked via MsgBox and debug Watch, the function is able to calculate a correct value.
Public Function pT_Flash_PR(comp, zComp, Temp, Pres) As Variant
NC = UBound(comp) - LBound(comp) + 1
Dim VapFrac As Variant
ReDim Tc(1 To NC)
ReDim Pc(1 To NC)
ReDim w(1 To NC)
ReDim Keq(1 To NC)
ReDim xComp(1 To NC)
ReDim yComp(1 To NC)
ReDim acrit(1 To NC)
ReDim bCrit(1 To NC)
ReDim Kappa(1 To NC)
ReDim alpha(1 To NC)
ReDim PR_Kij(1 To NC, 1 To NC)
ReDim psi_Liq(1 To NC)
ReDim psi_Vap(1 To NC)
ReDim phi_Liq(1 To NC)
ReDim phi_Vap(1 To NC)
ReDim Keq_New(1 To NC)
ReDim fug_Liq(1 To NC)
ReDim fug_Vap(1 To NC)
Dim ResSum(1 To 2) As Double
comp = Application.Transpose(comp)
zComp = Application.Transpose(zComp)
pSat_coeff_Range = Sheets("Database").Range("c3:L18")
PR_Kij_Database = Sheets("Database").Range("y3:an18")
VapFrac = 0.5
dVapFrac = 0.001
RConst = 8.31446261815324
For j = 1 To NC
For i = 1 To NC
rowNum = Application.Match(comp(i), Worksheets("Database").Range("x3:x18"), 0)
ColNum = Application.Match(comp(j), Worksheets("Database").Range("y2:AN2"), 0)
PR_Kij(i, j) = Application.Index(PR_Kij_Database, rowNum, ColNum)
Tc(i) = Application.WorksheetFunction.VLookup(comp(i), pSat_coeff_Range, 8, False) 'Tc in K
Pc(i) = Application.WorksheetFunction.VLookup(comp(i), pSat_coeff_Range, 9, False) * 1000
w(i) = Application.WorksheetFunction.VLookup(comp(i), pSat_coeff_Range, 10, False)
Keq(i) = Pc(i) / Pres * Exp(5.37 * (1 + w(i)) * (1 - Tc(i) / Temp))
Next
Next
For iter02 = 1 To 100
For iter01 = 1 To 100
For j = 1 To 2
VapFrac = VapFrac + (j - 1) * dVapFrac
For i = 1 To NC
Res = zComp(i) * (Keq(i) - 1) / (1 + VapFrac * (Keq(i) - 1))
ResSum(j) = ResSum(j) + Res
Next
Next
dResSum = 1 / dVapFrac * (ResSum(2) - ResSum(1))
VapFracNew = VapFrac - ResSum(1) / dResSum
Dif = Abs(VapFracNew - VapFrac)
If (Dif < 0.00000001) Then
Exit For
End If
VapFrac = VapFracNew
Next iter01
a_alpha_mixL = 0
bmixL = 0
a_alpha_mixV = 0
bmixV = 0
For i = 1 To NC
xComp(i) = zComp(i) / (1 + VapFrac * (Keq(i) - 1))
yComp(i) = zComp(i) * Keq(i) / (1 + VapFrac * (Keq(i) - 1))
acrit(i) = 0.45724 * RConst ^ 2 * Tc(i) ^ 2 / Pc(i) 'ai = 0.45724*R^2*Tci^2/Pci
bCrit(i) = 0.0778 * RConst * Tc(i) / Pc(i) 'bi = 0.07780*R*Tci/Pci
Kappa(i) = 0.37464 + 1.5422 * w(i) - 0.26992 * w(i) ^ 2 'Kappai = 0.3796 + 1.5422*wi - 0.2699*wi^2
alpha(i) = (1 + Kappa(i) * (1 - (Temp / Tc(i)) ^ 0.5)) ^ 2 'alphai = [1+mi*(1-sqrt(Temp/Tci)]^2
Next
For i = 1 To NC
'Calculation OF a*alpha_mix abd bmix for Liquid
bmixL = bmixL + xComp(i) * bCrit(i)
For j = 1 To NC
a_alpha_mixL = a_alpha_mixL + xComp(i) * xComp(j) * (acrit(i) * acrit(j) * alpha(i) * alpha(j)) ^ 0.5 * (1 - PR_Kij(i, j))
Next
'Calculation OF a*alpha_mix abd bmix for Vapour
bmixV = bmixV + yComp(i) * bCrit(i)
For j = 1 To NC
a_alpha_mixV = a_alpha_mixV + yComp(i) * yComp(j) * (acrit(i) * acrit(j) * alpha(i) * alpha(j)) ^ 0.5 * (1 - PR_Kij(i, j))
Next
Next
'Calculation A AND B constant for Compressibility Equation
ALPR = a_alpha_mixL * Pres / (RConst * Temp) ^ 2
BLPR = bmixL * Pres / (RConst * Temp)
AVPR = a_alpha_mixV * Pres / (RConst * Temp) ^ 2
BVPR = bmixV * Pres / (RConst * Temp)
'Iteration of Compressibility Equation for Liquid Phase
ZLiq = 0
For k = 1 To 100
Z = ZLiq
ZForm = Z ^ 3 + (BLPR - 1) * Z ^ 2 + Z * (ALPR - 3 * BLPR ^ 2 - 2 * BLPR) - (ALPR * BLPR - BLPR ^ 2 - BLPR ^ 3)
dZ = 0.0001
Z = ZLiq + dZ
ZFormdZ = Z ^ 3 + (BLPR - 1) * Z ^ 2 + Z * (ALPR - 3 * BLPR ^ 2 - 2 * BLPR) - (ALPR * BLPR - BLPR ^ 2 - BLPR ^ 3)
ZLiq = Z - ZForm / ((ZFormdZ - ZForm) / dZ)
EpsZLiq = Abs(ZLiq - Z)
If (EpsZLiq < 0.0000001) Then
Exit For
End If
Next
'Iteration of Compressibility Equation for Vapour Phase
ZVap = 1
For k = 1 To 100
Z = ZVap
ZForm = Z ^ 3 + (BVPR - 1) * Z ^ 2 + Z * (AVPR - 3 * BVPR ^ 2 - 2 * BVPR) - (AVPR * BVPR - BVPR ^ 2 - BVPR ^ 3)
dZ = 0.0001
Z = ZVap + dZ
ZFormdZ = Z ^ 3 + (BVPR - 1) * Z ^ 2 + Z * (AVPR - 3 * BVPR ^ 2 - 2 * BVPR) - (AVPR * BVPR - BVPR ^ 2 - BVPR ^ 3)
ZVap = Z - ZForm / ((ZFormdZ - ZForm) / dZ)
EpsZVap = Abs(ZVap - Z)
If (EpsZVap < 0.0000001) Then
Exit For
End If
Next
'Calculation of Fug Coefficent for Liq and Gas
EpsK = 0
For i = 1 To NC
' Calculation of psi Liq for individual compoennt for Fug Coefficient Eq
psi_Liq(i) = 0
For j = 1 To NC
psi_Liq(i) = psi_Liq(i) + xComp(j) * (acrit(i) * acrit(j) * alpha(i) * alpha(j)) ^ 0.5 * (1 - PR_Kij(i, j))
Next
' Calculation of Liquid Fug Coefficient, PhiL for individual component
phi_Liq(i) = Exp(bCrit(i) * (ZLiq - 1) / bmixL - logE(ZLiq - BLPR) - ALPR / 8 ^ 0.5 / (BLPR) * (2 * psi_Liq(i) / a_alpha_mixL - bCrit(i) / bmixL) * logE((ZLiq + BLPR * (1 + 2 ^ 0.5)) / (ZLiq + BLPR * (1 - 2 ^ 0.5))))
Cells(i, 17) = PhiL
' Calculation of psi Vap for individual compoennt for Fug Coefficient Eq
psi_Vap(i) = 0
For j = 1 To NC
psi_Vap(i) = psi_Vap(i) + yComp(j) * (acrit(i) * acrit(j) * alpha(i) * alpha(j)) ^ 0.5 * (1 - PR_Kij(i, j))
Next
' Calculation of Vapour Fug Coefficient, PhiL for individual component
phi_Vap(i) = Exp(bCrit(i) * (ZVap - 1) / bmixV - logE(ZVap - BVPR) - AVPR / 8 ^ 0.5 / (BVPR) * (2 * psi_Vap(i) / a_alpha_mixV - bCrit(i) / bmixV) * logE((ZVap + BVPR * (1 + 2 ^ 0.5)) / (ZVap + BVPR * (1 - 2 ^ 0.5))))
Cells(i, 18) = phiV
'Calculation of new K values
Keq_New(i) = phi_Liq(i) / phi_Vap(i)
fug_Liq(i) = xComp(i) * phi_Liq(i)
fug_Vap(i) = yComp(i) * phi_Vap(i)
'Calculation of summation of difference between new and old K values
EpsK = EpsK + (xComp(i) * phi_Liq(i) / (yComp(i) * phi_Vap(i)) - 1) ^ 2
Next
If (EpsK < 0.000000001) Then
Exit For
End If
Keq = Keq_New
Next iter02
pT_Flash_PR = VapFrac
MsgBox VapFrac
End Function
Sub Test()
comp = Range("g33:g35")
zComp = Range("h33:h35")
Temp = Range("h31") + 273.15
Pres = Range("h32")
VF = pT_Flash_PR(comp, zComp, Temp, Pres)
End Sub
VBA functions work differently if called from within excel cells. In your case (for example) all your parameters are read as Variant() arrays if the function is called from within the VB editor. However, if called from an excel cell they are accepted as Ranges and you therefore get an error when you do something like Lbound(someRange) or .Transpose(someRange). A way around is to check for the caller at the very beginning of your function like this:
'Check if called from an excel cell
If TypeName(Application.Caller) = "Range" Then
If TypeName(comp) = "Range" Then comp = comp.Value
If TypeName(zComp) = "Range" Then zComp = zComp.Value
If TypeName(Temp) = "Range" Then Temp = Temp.Value
If TypeName(Pres) = "Range" Then Pres = Pres.Value
End If
Here I am checking the type of each parameter again to allow for passing literal values.

VBA - Trying to get the root of a function

I got this equation to solve in VBA:
Energy = y + (0.5) ^ 2 / ( 2 * 9.81 * y ^ 2 )
but I got the Energy value and want to solve for the y value.
In R is easy: uniroot. There is something like this?
The equation is a cubic polynomial with two positive roots and one negative. We can eliminate the negative one, and consider a direct evaluation of the two positive roots with the following VBA code in a Module.
Global Const g As Double = 9.81
Global Const PI As Double = 3.14159265358979
Public Function CalcE(ByVal y As Double) As Double
CalcE = y + (0.5) ^ 2 / (2# * g * y ^ 2)
End Function
Public Function SolveForY(ByVal E As Double, Optional ByVal second As Boolean = False) As Double
' Solve "E = y + (0.5) ^ 2 / ( 2 * g * y ^ 2 )" for "y"
If Not second Then
SolveForY = E / 3# - 2# * E * Sin(Asin((16# * E ^ 3# * g - 27#) / (16# * E ^ 3# * g)) / 3#) / 3#
Else
SolveForY = E / 3# + 2# * E * Sin(Asin((16# * E ^ 3 * g - 27#) / (16# * E ^ 3 * g)) / 3# + PI / 3#) / 3#
End If
End Function
and the supporting Asin() function defined in terms of Atn().
Public Function Asin(ByVal x) As Double
If Abs(x) < 1# Then
Asin = Atn(x / Sqr(1# - x * x))
Else
Asin = 2 * Atn(1) * Sgn(x)
End If
End Function
Some example results are
? SolveForY(1#)
0.12035578724076
? SolveForY(1#, True)
0.986917853921696
And checking the solutions
? CalcE(0.12035578724076)
0.999999999999997
? CalcE(0.986917853921696)
1
Consider using algebra:
Energy = y + (0.5)^2 / ( 2 * 9.81 * y^2 )
Energy = y + .25 / ( 19.62 * y^2 )
Energy * ( 19.62 * y^2 ) = y * ( 19.62 * y^2 ) + .25
Energy * 19.62 * y^2 = 19.62 * y^3 + .25
0 = 19.62 * y^3 - Energy * 19.62 * y^2 + .25
and apply standard techniques:
Previous Post
Here's a translation of John Alexiou's answer from VBA to Excel formulas. If energy in in cell B2 then the three solutions are given by:
=B2/3-2*B2*SIN((ASIN((16*B2^3*9.81-27)/(16*B2^3*9.81))+0*PI())/3)/3
=B2/3-2*B2*SIN((ASIN((16*B2^3*9.81-27)/(16*B2^3*9.81))+4*PI())/3)/3
=B2/3-2*B2*SIN((ASIN((16*B2^3*9.81-27)/(16*B2^3*9.81))+2*PI())/3)/3
The third equation gives negative y.

Z factor iteration using VBA

I created a form button with two subroutines.
1.Pressure Depth Calculations
2. Z factor calculation
Both are iterations. (1) is running properly while (2) does not execute.
Following are the codes:
Sub PressureDepthCalculation()
'Declaring Variables
Dim i, t, row As Integer
t = Range("B5").Value
row = 11
'For Loop
For i = t To 0 Step -100
'Depth caclculation
Range("A" & row).Value = i
'Pressure calculation
Range("B" & row).Value = Range("F5").Value + 0.052 * Range("F6") * i
row = row + 1
Next i
End Sub
Sub ZFactorCalculation()
'Z factor calculation
Dim r1, r2, r3, r4, r5, ppc, tpc, ppr, tpr, fr, dfr, ddfr, rhor As Double
Dim i, row,t As Integer
t = 1
row = 11
Range("D6").Value = 10.731
a1 = 0.3265
a2 = 1.07 * -1
a3 = 0.5339 * -1
a4 = 0.01569
a5 = 0.05165 * -1
a6 = 0.5475
a7 = 0.7361 * -1
a8 = 0.1844
a9 = 0.1056
a10 = 0.6134
a11 = 0.721
For i = t To 100
ppc = (4.6 + (0.1 * Range("H6").Value) - (0.258 * Range("H6").Value ^ 2) * 10.1325 * 14.7)
tpc = (99.3 + (180 * Range("H6").Value) - (6.94 * Range("H6").Value ^ 2) * 1.8)
ppr = 6760 / ppc
tpr = Range("B6").Value / tpc
rhor = 0.27 * ppr / tpr
r1 = (a1 + (a2 / tpr) + (a3 / tpr ^ 3) + (a4 / tpr ^ 4) + (a5 / tpr ^ 5))
r2 = ((0.27 * ppr) / tpr)
r3 = (a6 + (a7 / tpr) + (a8 / tpr ^ 2))
r4 = a9 * ((a7 / tpr) + (a8 / tpr ^ 2))
r5 = (a10 / tpr ^ 3)
fr = (r1 * rhor) - (r2 / rhor) + (r3 * rhor ^ 2) - (r4 * rhor ^ 5) + (r5 * (1 + (a11 * rhor ^ 2))) * (Exp(-a11 * rhor ^ 2)) + 1
dfr = (r1) + (r2 / rhor ^ 2) + (2 * r3 * rhor) - (5 * r4 * rhor ^ 4) + (2 * r5 * rhor * (Exp(-a11 * rhor ^ 2)) * ((1 + (2 * a11 * rhor ^ 3)) - (a11 * rhor ^ 2 * (1 + (a11 * rhor ^ 2)))))
ddfr = rhor - (fr / dfr)
If Abs(rhor - ddfr) <= 0.000000000001 Then
Range("I" & r).Value = (0.27 * ppr) / (rhor * tpr)
Else
rhor = ddfr
End If
Also when in (1) I calculate Range("B"&row).value, I want to use it to calculate ppc in place of 6760 in (2).
It appears that your second loop has no directive to continue the loop.
You can either do:
For i = t To 100 **Step someNumber** 'The -Step- argument was used in loop 1, but was omitted in loop 2
Or this:
For i = t To 100
'the rest of your code here
**Next i** 'will increment i by 1
Welcome to StackOverflow :)

Excel function sheet gives errors

My first attempt at user-defined functions in Excel (Mac) isn't going well. This gives "function or sub undefined":
Function CylArea(d0 As Double, theta As Double, y As Double) As Double
CylArea = Pi() * (d0 ^ 2 / 4 + d0 * Tan(Radians(theta)) * y + Tan(Radians(theta)) ^ 2 * y ^ 2)
End Function
Function CylVolume(d0 As Double, theta As Double, y As Double) As Double
CylVolume = Pi() * (d0 ^ 2 / 4 * y + 1 / 2 * d0 * Tan(Radians(theta)) * y ^ 2 + 1 / 3 * Tan(Radians(theta)) ^ 2 * y ^ 3)
End Function
Function CylAreaDeriv(d0 As Double, theta As Double, y As Double) As Double
CylAreaDeriv = Pi() * (d0 * Tan(Radians(theta)) + 2 * Tan(Radians(theta)) ^ 2 * y)
End Function
Curiously, the Pi in CylVolume is highlighted.
It looks like you are attempting to use Excel functions as you would in a worksheet within VBA code. This will likely not work.
Try changing all instances of Pi() to WorksheetFunction.Pi, all instances of Tan to Math.Tan and all instances of Radians to WorksheetFunction.Radians so that the code looks more like this:
Function CylVolume(d0 As Double, theta As Double, y As Double) As Double
CylVolume = WorksheetFunction.Pi * (d0 ^ 2 / 4 * y + 1 / 2 * d0 * Math.Tan(WorksheetFunction.Radians(theta)) * y ^ 2 + 1 / 3 * Math.Tan(WorksheetFunction.Radians(theta)) ^ 2 * y ^ 3)
End Function

Resources