Take only non zero and non negative arguments in UDF of excel VBA - excel

I have created a UDF to iterate an equation. The UDF is working fine. But, if the argument(s) is assigned zero or negative, say W = 0, then the excel freezes completely. I want to stop the execution of UDF or display errors if the argument(s) is zero or negative and prevent the file from freezing. Please help
Function myfunc(Q, W, n, s As Double) As Double
Dim Q_Cal As Double
' to initialize the loop
D = 0.001
Q_Cal = 0.001
While Q_Cal < Q
D = D + 0.001
Q_Cal = ((W * D) / n) * ((W * D) / (2 * D + W)) ^ (2 / 3) * s ^ 0.5
Wend
myfunc = Round(D, 3)
End Function

Related

Problem with changing the variable inside of a Do Until loop

x = 0
Do Until x = Step
SrcVol = (Vol / DilPoints)
DilVol = Vol - SrcVol
Vol = 0.75 * Vol
Wb1.Sheets(1).Range("D4").Offset((2 * x) + k - 1, 0) = SrcVol
Wb1.Sheets(1).Range("D5").Offset((2 * x) + k - 1, 0) = DilVol
DilPoints = Range("D8").Offset(x, 0)
x = x + 1
Loop
Hello,
I am trying to offset this range in my VBA code and the DilPoints value gets lost after the offset. I have tried everything but the loop keeps dividing by zero after the first iteration of the loop. How do you make sure the value stays around and continues to collect data from other cells and not just default to zero. I have used the .Select and it makes the value go to -1.

Why is a ByVal function changing my variable?

Calling divsig(h) results in changes to h. But divsig is a function that takes a matrix by value and not by reference. How can this happen?
I'm trying to use the sig/divsig functions on matrices of data, for example:
DenseMatrix 4x4-Double ' h before divsig(h)
0.5 0.5 0.5 0.5
0.568811 0.995811 0.418727 0.987232
0.65701 0.269138 0.990942 0.99298
0.716466 0.988705 0.98747 0.999909
divsig(h)
DenseMatrix 4x4-Double ' h after divsig
0.25 0.25 0.25 0.25
0.245265 0.00417185 0.243395 0.0126045
0.225348 0.196703 0.00897602 0.00697036
0.203142 0.0111678 0.0123732 9.14075E-05
Makes no sense to me what so ever, i'm even setting up a new variable called matrix in the function instead of editing 'mat' it's self.
Function divsig(ByVal mat As LinearAlgebra.Double.Matrix)
Dim matrix = mat
For _x = 0 To matrix.RowCount() - 1
For _y = 0 To matrix.ColumnCount() - 1
matrix(_x, _y) = derivsigmoid(matrix(_x, _y))
Next
Next
Return matrix
End Function
Function sigmoid(ByVal x As Double) As Double
Return 1 / (1 + Math.Exp(-x))
End Function
Function derivsigmoid(ByVal x As Double) As Double
Return x * (1 - x)
End Function
Function sig(ByVal mat As LinearAlgebra.Double.Matrix)
Dim matrix = mat
For _x = 0 To matrix.RowCount() - 1
For _y = 0 To matrix.ColumnCount() - 1
matrix(_x, _y) = sigmoid(matrix(_x, _y))
Next
Next
Return matrix
End Function
I have fixed it, turns out matrixes are classes which means passing them ByVal passes the reference anyway. I fixed it by replacing the Dim matrix = mat with
Dim matrix As LinearAlgebra.Double.Matrix = LinearAlgebra.Double.Matrix.Build.DenseOfMatrix(mat)
So matrix becomes a copy of mat instead of just giving the same reference a different identifier.

Excel VBA function error

I write this code in the module:
Public Function first()
If (x + 1 < 0) Or (1 - 2 * Sin(x) < 0) Or Sqr(1 - 2 * Sin(x)) = 0 Then
first = "error"
Else
first = Sqr(x + 1) / Sqr(1 - 2 * Sin(x))
End If
End Function
It gives an error with certain values:
Where is the problem?
I'm pretty sure that your intention is to evaluate Sin(x) where x is measured in degrees (if for no other reason than that evaluating at radians which are whole numbers other than 0 is quite rare), but the function Sin(x) works with radians. You can use the function Randians() to fix this:
Public Function first(ByVal x As Double) As Double
x = Application.Radians(x)
If (x + 1 < 0) Or (1 - 2 * Sin(x) < 0) Or Sqr(1 - 2 * Sin(x)) = 0 Then
first = "error"
Else
first = Sqr(x + 1) / Sqr(1 - 2 * Sin(x))
End If
End Function
Then, for example, first(7) evaluates to 1.218130941.
When x is 7, Sin(x) is equal to 0.656986598718789.
When you plug this into the formula 1 - 2 * Sin(x), you get -0.313973197437578.
You cannot take the square root (i.e. Sqr(...)) of a negative number. I would suggest adding Abs(...) as a wrapper to guarantee a positive number but I have no idea what you are ultimately trying to accomplish.

Math equation in Excel using two variables

Please help me this. This should be simple but I am stuck.
Lets say:
a=0.9162904
b=0.8473002
b-a=-0.0689902
r=-1.21E-22
pa=1 /(1+EXP(-1*(a+(r)))) = 0.714285647
pb=1 /(1+EXP(-1*(b+(r)))) = 0.700000491
pb=pa=-0.014285155
Now let's say that only r and (b-a) is given to me.
What is the formula to calculate (pb-pa)?
You cannot calculate pb - pa from b-a and r. To see this let's call d = b-a. Then d is given (you cannot change it). Now, your equations can be written as
pa = 1 / (1 + exp(-a-r))
pb = 1 / (1 + exp(-b-r))
or
pa = 1 / (1 + exp(-r)exp(-a))
pb = 1 / (1 + exp(-r-d)exp(-a))
because b = d+a.
Now put
C = exp(-r)
D = exp(-r-d)
these two quantities are constants (i.e., they are given). However, a is not a constant so let's emphasize this by putting
x = exp(-a)
which means that x can be given any positive value. With these notations,
pa = 1 / (1 + C x)
pb = 1 / (1 + D x)
and
pb - pa = 1 / (1 + C x) - (1 / (1 + D x))
which depends on x for any values of d and r except the very particular case where C = D, which only happens if r = 0.

How to implement Frobenius pseudoprime algorithm?

Someone told me that the Frobenius pseudoprime algorithm take three times longer to run than the Miller–Rabin primality test but has seven times the resolution. So then if one where to run the former ten times and the later thirty times, both would take the same time to run, but the former would provide about 233% more analyse power. In trying to find out how to perform the test, the following paper was discovered with the algorithm at the end:
A Simple Derivation for the Frobenius Pseudoprime Test
There is an attempt at implementing the algorithm below, but the program never prints out a number. Could someone who is more familiar with the math notation or algorithm verify what is going on please?
Edit 1: The code below has corrections added, but the implementation for compute_wm_wm1 is missing. Could someone explain the recursive definition from an algorithmic standpoint? It is not "clicking" for me.
Edit 2: The erroneous code has been removed, and an implementation of the compute_wm_wm1 function has been added below. It appears to work but may require further optimization to be practical.
from random import SystemRandom
from fractions import gcd
random = SystemRandom().randrange
def find_prime_number(bits, test):
number = random((1 << bits - 1) + 1, 1 << bits, 2)
while True:
for _ in range(test):
if not frobenius_pseudoprime(number):
break
else:
return number
number += 2
def frobenius_pseudoprime(integer):
assert integer & 1 and integer >= 3
a, b, d = choose_ab(integer)
w1 = (a ** 2 * extended_gcd(b, integer)[0] - 2) % integer
m = (integer - jacobi_symbol(d, integer)) >> 1
wm, wm1 = compute_wm_wm1(w1, m, integer)
if w1 * wm != 2 * wm1 % integer:
return False
b = pow(b, (integer - 1) >> 1, integer)
return b * wm % integer == 2
def choose_ab(integer):
a, b = random(1, integer), random(1, integer)
d = a ** 2 - 4 * b
while is_square(d) or gcd(2 * d * a * b, integer) != 1:
a, b = random(1, integer), random(1, integer)
d = a ** 2 - 4 * b
return a, b, d
def is_square(integer):
if integer < 0:
return False
if integer < 2:
return True
x = integer >> 1
seen = set([x])
while x * x != integer:
x = (x + integer // x) >> 1
if x in seen:
return False
seen.add(x)
return True
def extended_gcd(n, d):
x1, x2, y1, y2 = 0, 1, 1, 0
while d:
n, (q, d) = d, divmod(n, d)
x1, x2, y1, y2 = x2 - q * x1, x1, y2 - q * y1, y1
return x2, y2
def jacobi_symbol(n, d):
j = 1
while n:
while not n & 1:
n >>= 1
if d & 7 in {3, 5}:
j = -j
n, d = d, n
if n & 3 == 3 == d & 3:
j = -j
n %= d
return j if d == 1 else 0
def compute_wm_wm1(w1, m, n):
a, b = 2, w1
for shift in range(m.bit_length() - 1, -1, -1):
if m >> shift & 1:
a, b = (a * b - w1) % n, (b * b - 2) % n
else:
a, b = (a * a - 2) % n, (a * b - w1) % n
return a, b
print('Probably prime:\n', find_prime_number(300, 10))
You seem to have misunderstood the algorithm completely due to not being familiar with the notation.
def frobenius_pseudoprime(integer):
assert integer & 1 and integer >= 3
a, b, d = choose_ab(integer)
w1 = (a ** 2 // b - 2) % integer
That comes from the line
W0 ≡ 2 (mod n) and W1 ≡ a2b−1 − 2 (mod n)
But the b-1 doesn't mean 1/b here, but the modular inverse of b modulo n, i.e. an integer c with b·c ≡ 1 (mod n). You can most easily find such a c by continued fraction expansion of b/n or, equivalently, but with slightly more computation, by the extended Euclidean algorithm. Since you're probably not familiar with continued fractions, I recommend the latter.
m = (integer - d // integer) // 2
comes from
n − (∆/n) = 2m
and misunderstands the Jacobi symbol as a fraction/division (admittedly, I have displayed it here even more like a fraction, but since the site doesn't support LaTeX rendering, we'll have to make do).
The Jacobi symbol is a generalisation of the Legendre symbol - denoted identically - which indicates whether a number is a quadratic residue modulo an odd prime (if n is a quadratic residue modulo p, i.e. there is a k with k^2 ≡ n (mod p) and n is not a multiple of p, then (n/p) = 1, if n is a multiple of p, then (n/p) = 0, otherwise (n/p) = -1). The Jacobi symbol lifts the restriction that the 'denominator' be an odd prime and allows arbitrary odd numbers as 'denominators'. Its value is the product of the Legendre symbols with the same 'numerator' for all primes dividing n (according to multiplicity). More on that, and how to compute Jacobi symbols efficiently in the linked article.
The line should correctly read
m = (integer - jacobi_symbol(d,integer)) // 2
The following lines I completely fail to understand, logically, here should follow the calculation of
Wm and Wm+1 using the recursion
W2j ≡ Wj2 − 2 (mod n)
W2j+1 ≡ WjWj+1 − W1 (mod n)
An efficient method of using that recursion to compute the required values is given around formula (11) of the PDF.
w_m0 = w1 * 2 // m % integer
w_m1 = w1 * 2 // (m + 1) % integer
w_m2 = (w_m0 * w_m1 - w1) % integer
The remainder of the function is almost correct, except of course that it now gets the wrong data due to earlier misunderstandings.
if w1 * w_m0 != 2 * w_m2:
The (in)equality here should be modulo integer, namely if (w1*w_m0 - 2*w_m2) % integer != 0.
return False
b = pow(b, (integer - 1) // 2, integer)
return b * w_m0 % integer == 2
Note, however, that if n is a prime, then
b^((n-1)/2) ≡ (b/n) (mod n)
where (b/n) is the Legendre (or Jacobi) symbol (for prime 'denominators', the Jacobi symbol is the Legendre symbol), hence b^((n-1)/2) ≡ ±1 (mod n). So you could use that as an extra check, if Wm is not 2 or n-2, n can't be prime, nor can it be if b^((n-1)/2) (mod n) is not 1 or n-1.
Probably computing b^((n-1)/2) (mod n) first and checking whether that's 1 or n-1 is a good idea, since if that check fails (that is the Euler pseudoprime test, by the way) you don't need the other, no less expensive, computations anymore, and if it succeeds, it's very likely that you need to compute it anyway.
Regarding the corrections, they seem correct, except for one that made a glitch I previously overlooked possibly worse:
if w1 * wm != 2 * wm1 % integer:
That applies the modulus only to 2 * wm1.
Concerning the recursion for the Wj, I think it is best to explain with a working implementation, first in toto for easy copy and paste:
def compute_wm_wm1(w1,m,n):
a, b = 2, w1
bits = int(log(m,2)) - 2
if bits < 0:
bits = 0
mask = 1 << bits
while mask <= m:
mask <<= 1
mask >>= 1
while mask > 0:
if (mask & m) != 0:
a, b = (a*b-w1)%n, (b*b-2)%n
else:
a, b = (a*a-2)%n, (a*b-w1)%n
mask >>= 1
return a, b
Then with explanations in between:
def compute_wm_wm1(w1,m,n):
We need the value of W1, the index of the desired number, and the number by which to take the modulus as input. The value W0 is always 2, so we don't need that as a parameter.
Call it as
wm, wm1 = compute_wm_wm1(w1,m,integer)
in frobenius_pseudoprime (aside: not a good name, most of the numbers returning True are real primes).
a, b = 2, w1
We initialise a and b to W0 and W1 respectively. At each point, a holds the value of Wj and b the value of Wj+1, where j is the value of the bits of m so far consumed. For example, with m = 13, the values of j, a and b develop as follows:
consumed remaining j a b
1101 0 w_0 w_1
1 101 1 w_1 w_2
11 01 3 w_3 w_4
110 1 6 w_6 w_7
1101 13 w_13 w_14
The bits are consumed left-to-right, so we have to find the first set bit of m and place our 'pointer' right before it
bits = int(log(m,2)) - 2
if bits < 0:
bits = 0
mask = 1 << bits
I subtracted a bit from the computed logarithm just to be entirely sure that we don't get fooled by a floating point error (by the way, using log limits you to numbers of at most 1024 bits, about 308 decimal digits; if you want to treat larger numbers, you have to find the base-2 logarithm of m in a different way, using log was the simplest way, and it's just a proof of concept, so I used that here).
while mask <= m:
mask <<= 1
Shift the mask until it's greater than m,so the set bit points just before m's first set bit. Then shift one position back, so we point at the bit.
mask >>= 1
while mask > 0:
if (mask & m) != 0:
a, b = (a*b-w1)%n, (b*b-2)%n
If the next bit is set, the value of the initial portion of consumed bits of m goes from j to 2*j+1, so the next values of the W sequence we need are W2j+1 for a and W2j+2 for b. By the above recursion formula,
W_{2j+1} = W_j * W_{j+1} - W_1 (mod n)
W_{2j+2} = W_{j+1}^2 - 2 (mod n)
Since a was Wj and b was Wj+1, a becomes (a*b - W_1) % n and b becomes (b * b - 2) % n.
else:
a, b = (a*a-2)%n, (a*b-w1)%n
If the next bit is not set, the value of the initial portion of consumed bits of m goes from j to 2*j, so a becomes W2j = (Wj2 - 2) (mod n), and b becomes
W2j+1 = (Wj * Wj+1 - W1) (mod n).
mask >>= 1
Move the pointer to the next bit. When we have moved past the final bit, mask becomes 0 and the loop ends. The initial portion of consumed bits of m is now all of m's bits, so the value is of course m.
Then we can
return a, b
Some additional remarks:
def find_prime_number(bits, test):
while True:
number = random(3, 1 << bits, 2)
for _ in range(test):
if not frobenius_pseudoprime(number):
break
else:
return number
Primes are not too frequent among the larger numbers, so just picking random numbers is likely to take a lot of attempts to hit one. You will probably find a prime (or probable prime) faster if you pick one random number and check candidates in order.
Another point is that such a test as the Frobenius test is disproportionally expensive to find that e.g. a multiple of 3 is composite. Before using such a test (or a Miller-Rabin test, or a Lucas test, or an Euler test, ...), you should definitely do a bit of trial division to weed out most of the composites and do the work only where it has a fighting chance of being worth it.
Oh, and the is_square function isn't prepared to deal with arguments less than 2, divide-by-zero errors lurk there,
def is_square(integer):
if integer < 0:
return False
if integer < 2:
return True
x = integer // 2
should help.

Resources