Following the previous post the OptShearCap3600 function has been modified to give correct results with negative bending moments. The revised spreadsheet and Python code can be downloaded from:
Typical output with negative moment input:

Following the previous post the OptShearCap3600 function has been modified to give correct results with negative bending moments. The revised spreadsheet and Python code can be downloaded from:
Typical output with negative moment input:

The py_UMom spreadsheet has been updated with further revisions to the py_OptShearCap3600 function. The new version can be downloaded from:
For more information on the other functions in the spreadsheet see: py_UMom spreadsheet and OptShearCap3600 function.
The changes to the py_OptShearCap 3600 function are:
The revised input and typical output is shown in the screenshots below:


Examples comparing the different longitudinal force options with different levels of shear reinforcement are shown below. The 4 options in each graph are:
The first case has shear reinforcement just adequate for the input V*:

Increasing the shear reinforcement greatly increases the shear range with unconservative unreduced bending capacity when the AS 5100 calculation is used with no limit on Vus:

When the shear reinforcement is reduced below the level required for the input shear force the critical forces are all in the range where shear capacity governs the failure mode, and all four options give the same shear capacity:

I recently read an article about connecting Python to the new Mojo language:
The article had some code examples, including code to plot the Mandelbrot set, comparing plain Python, Python with Numpy, and Mojo, and what particularly interested me was that the code with Numpy was about 4 times faster than plain Python, whereas I had found Numpy for this task was slower than Python, as reported here: Computing and plotting the Mandelbrot set in Excel …
I have now updated the matplot-mandelbrot spreadsheet to include revised Numpy code, based upon on the code at the link above, and found that the Numpy code went from up to about 2 times slower to 3-4 times faster.
The updated spreadsheet and Python code can be downloaded from: FastMandelbrot.zip

The Numba code using Guvectorize remains by far the fastest, but the revised Python + Numpy code is now much faster than the plain Python. The original code loops through the results array cell by cell, converting the coordinates to a complex number then calling a plain Python routine to do the calculations:
def mandelbrot_set1(xmin,xmax,ymin,ymax,width,height,maxiter):
r1 = np.linspace(xmin, xmax, width)
r2 = np.linspace(ymin, ymax, height)
n3 = np.empty((width,height))
for i in range(width):
for j in range(height):
n3[i,j] = mandelbrot(r1[i] + 1j*r2[j],maxiter)
res = (r1,r2,n3)
return res
The revised code generates an array of complex numbers in a single operation, then generates the Mandelbrot values with a Numpy vectorized computation:
def mandelbrot8(x, y, maxiter, out = 0):
"""Generates a Mandelbrot set using NumPy for vectorized computation."""
c = x[:, np.newaxis] + 1j * y[np.newaxis, :]
z = np.zeros_like(c, dtype=np.complex128)
image = np.zeros(c.shape, dtype=int)
for n in range(maxiter):
not_diverged = np.abs(z) <= 2
image[not_diverged] = n
z[not_diverged] = z[not_diverged]**2 + c[not_diverged]
image[np.abs(z) <= 2] = maxiter
return image
The spreadsheet plots the calculated shape with chosen colour properties to full scale:

or scaled up by 100,000:

or 1,000,000:

or by 10,000,000:

or by 100,000,000:

and more, but after 1 billion, the image starts to lose resolution using 64 bit floats.
For those who want to go further, visit YouTube:
“The deepest Mandelbrot zoom ever! This zoom is over 24-hours long, uploaded to YouTube in 11 parts. It will finish on a mini-Mandelbrot. As such, I am claiming a world record for the deepest Mandelbrot video! I have kept to the traditional colouring style for this one. The first video may seem a little repetitive at first, but this builds more interesting shapes later into the zoom. You’re welcome to skip ahead a little. Consider playing your own music while you let this one roll. Sit back, relax, and soak it in. (The last minute also generates a cool optical illusion with the pattern it finishes on).”
Continuing from the previous post, this post looks at the polynomial functions in the revised py_Numpy spreadsheet. The updated code and spreadsheet can be downloaded from:
The available functions call the Numpy functions for solution and evaluation of polynomials, plus some additional functions with closed-form solutions for polynomials of up to quartic order. The available functions for finding the roots of polynomial equations are shown below (click on any image for full-size view):


Numpy iterative functions:
Closed-form functions:
Calculation times for 100,000 iterations are shown in the screenshot below, with plain Python code, and with the Numba JIT compiler.

More functions:



The py_Numpy spreadsheet and associated code has been updated, with two new functions, links to the Numpy on-line help updated, and updates to sorting and polynomial functions. The updated code and spreadsheet can be downloaded from:
Updated Numpy files included in: py_SciPy.zip
Note that the Numpy code comes in 2 versions: pyNumpy-noJIT.py and pyNumpy-jit.py. The pyNumpy-jit.py requires the Numba just-in-time compiler to be installed, which provides very much faster results for maths intensive operations, compared with plain Python code. The default pyNumpy.py module is currently a copy of the noJIT version.
The py_SciPy download contains full open-source Python code and example spreadsheets for a wide range of Scipy functions, as well as the Numpy functions covered in this post. For more details, see the series of posts starting at: Scipy functions with Excel and pyxll. Also see Python and pyxll for details of the pyxll add-in, required to link my Python code to Excel.
This post will look at the two new functions, py_Where and py_Split, which can be found on the Array Functions tab of the py_Numpy spreadsheet. The other changes will be covered in the following post.
The py_Where function calls the Numpy “where”:
numpy.where(condition, [x, y, ]/)
Return elements chosen from x or y depending on condition.
The x, y return values are optional, and where omitted the function returns an array with the base 0 index values of the data values that satisfy the given condition, as shown in Column D below:

For this case the required inputs are:
The output is a single column array with the base 0 index of the data values that satisfy the condition, in this case those that are <= 13.
Where x and y are specified typical output is shown in Column G above. Where the condition is satisfied x (‘Hearts’) is returned, and otherwise y (‘Spades’).
The py_Split function splits the data into a number of smaller arrays at the specified locations:

The sub-arrays are returned as rows, with empty cells displaying #N/A.
The Numpy help on the function (and most of the other functions in py_Numpy) can be displayed by clicking on ‘Help on this function’ in the bottom-left corner of the function dialog box:
