DOUBLE_INDEFINITE_INTEGRAL
Python Code
from flojoy import flojoy, OrderedTriple, Matrix
import numpy as np
def contains_only_numbers(column, colName):
for i in range(0, len(column)):
if not isinstance(column.item(i), (int, float)):
raise ValueError(
f"The value {column.item(i)} in column {colName} is of type {type(column.item(i))}. The OrderedTriple need to contain only int or float values."
)
@flojoy
def DOUBLE_INDEFINITE_INTEGRAL(
default: OrderedTriple, width: int = 3, height: int = 3
) -> Matrix:
"""Compute the indefinite integral of an OrderedTriple (x,y,z).
The width and height parameters represent the number of columns and rows, respectively, that the x, y, and z reshaped matrices will have.
Here it is important to note that the length of x, y, and z is the same, and that the width times the height needs to be equal to the length of x, y, and z.
It computes the double integral approximation according to given dimensions of the matrices, and returns a matrix where each cell represents the volume up to the given point.
Inputs
------
default : OrderedTriple
Input from which we use x, y, and z to compute the integral.
Parameters
----------
width : int
Number of columns of the 3 matrices generated by reshaping the x, y, and z columns of the OrderedTriple.
height : int
Number of rows of the 3 matrices generated by reshaping the x, y, and z columns of the OrderedTriple.
Returns
-------
Matrix
The matrix that contains the volume up to that point in each cell.
"""
if np.divide(len(default.x), width) == height:
contains_only_numbers(default.x, "x")
contains_only_numbers(default.y, "y")
contains_only_numbers(default.z, "z")
input_x = np.reshape(default.x, (height, width))
input_y = np.reshape(default.y, (height, width))
input_z = np.reshape(default.z, (height, width))
else:
raise ArithmeticError(
f"Cannot reshape size {len(default.x)} in a matrix of {width} by {height}. Please enter appropriate width and height."
)
integrate = np.zeros_like(input_x)
for i in range(1, len(input_x)):
for j in range(1, width):
cal = (
(input_x[i][j] - input_x[i][j - 1])
* (input_y[i][j] - input_y[i - 1][j])
/ 4
)
result = cal * (
input_z[i - 1][j - 1]
+ input_z[i][j - 1]
+ input_z[i - 1][j]
+ input_z[i][j]
)
integrate[i][j] = result
result = np.copy(integrate)
for i in range(1, len(integrate)):
for j in range(1, width):
if i == 1:
result[i][j] = result[i][j - 1] + result[i][j]
elif j == 1:
result[i][j] = result[i - 1][j] + result[i][j]
else:
result[i][j] = (
result[i][j - 1]
+ result[i - 1][j]
+ result[i][j]
- result[i - 1][j - 1]
)
return Matrix(m=result)
Example
In this example we use the R_DATASET
node with the parameter DNase, the DF_2_ORDEREDTRIPLE
node with parameters x=1, y=0, z=2 and we also set the parameters of the DOUBLE_INDEFINITE_INTEGRAL
node to width=16 and height=11.
The random dataset DNase is a good set for this example since it’s columns (as an OrderedTriple) have length 176 which is 16 times 11 and we can see in the table of this OrderedTriple that we have the same 16 x values used on each 11 different y values. Then we decide for the width to be 16 and the height to be 11 reshape the matrices.
Then the DOUBLE_INDEFINITE_INTEGRAL
node will reshape the 3 columns in matrices and use them to output a matrix of the same dimension then the 3 reshape matrices. In this matrix we have computes in each cell the volume up to that given point.
We can observe it here in the SURFACE3D
node that indeed the volume goes higher and higher as the x and y values increase which is as expected since in the initial table of values for x, y and z we could see that they are also increasing. We can also see it with the values of the MATRIX_VIEW
node which are also increasing as they go further.