def spa_derivT(i, j, k, V, g):
    left_deriv = hcl.scalar(0, "left_deriv")
    right_deriv = hcl.scalar(0, "right_deriv")

    dim_idx = 2

    u_i = V[i, j, k]

    with hcl.if_(k == 0):
        u_i_minus_1 = hcl.scalar(0, "u_i_minus_1")

        u_i_minus_1[0] = V[i, j, V.shape[dim_idx] - 1]

        u_i_plus_1 = V[i, j, k + 1]
        u_i_plus_2 = V[i, j, k + 2]

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1[0]) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.elif_(k == V.shape[dim_idx] - 1):
        u_i_plus_1 = hcl.scalar(0, "u_i_plus_1")
        u_i_plus_2 = hcl.scalar(0, "u_i_plus_2")

        u_i_plus_1[0] = V[i, j, 0]
        u_i_plus_2[0] = V[i, j, 1]

        u_i_minus_1 = V[i, j, k - 1]

        D1_i_plus_half = (u_i_plus_1[0] - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2[0]
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1[0]) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.elif_(k == V.shape[dim_idx] - 2):
        u_i_plus_2 = hcl.scalar(0, "u_i_plus_2")

        u_i_plus_1 = V[i, j, k + 1]
        u_i_plus_2[0] = V[i, j, 0]

        u_i_minus_1 = V[i, j, k - 1]

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2[0]
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.else_():
        u_i_minus_1 = V[i, j, k - 1]

        u_i_plus_1 = V[i, j, k + 1]
        u_i_plus_2 = V[i, j, k + 2]

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    return left_deriv[0], right_deriv[0]
示例#2
0
 def maxVWithCStraint(i, j, k, l, m, n):
     with hcl.if_(V_new[i, j, k, l, m, n] < obstacle[i, j, k, l, m, n]):
         V_new[i, j, k, l, m, n] = obstacle[i, j, k, l, m, n]
示例#3
0
 def maxVWithV0(i, j, k, l, m, n): # Take the max
     with hcl.if_(V_new[i, j, k, l, m, n] < l0[i, j, k, l, m, n]):
         V_new[i, j, k, l, m, n] = l0[i, j, k, l, m, n]
示例#4
0
 def maxVWithCStraint(i, j, k, l, m, n):
     with hcl.if_(V_new[i, j, k, l, m, n] < 5.0):
         V_new[i, j, k, l, m, n] = 1.0
示例#5
0
    def update(l, prototype, prototypeCounter, max):
        hcl.print((l + 1),
                  "%d:Use hard examples to update the prototype counters.\n")

        ###data preparation
        distance = hcl.compute((pack_train.shape[1], ),
                               lambda x: 0,
                               'distance',
                               dtype=hcl.UInt(bw))
        pre_dist = hcl.compute((pack_train.shape[1], ), lambda x: 0,
                               "pre_dist")
        hamming_dist = hcl.compute((numClasses, ), lambda x: 0, "hamming_dist")
        m = hcl.reduce_axis(0, pack_train.shape[1], "m")
        ###

        with hcl.for_(0, pack_train.shape[0]) as i:
            hcl.print((i), "%d suc\n")
            pack_proto = hcl.pack(prototype,
                                  axis=1,
                                  dtype=hcl.UInt(bw),
                                  name="pack_proto")
            with hcl.for_(0, numClasses) as n:
                #Do hdc multiplication(XOR) on sample[i]'s hdv and prototype[n]'s hdv (elementwise on the high-bit data)
                hcl.update(distance,
                           lambda x: pack_train[i][x] ^ pack_proto[n][x])
                #Calculate the hamming distance of the two vectors by adding 1s
                hcl.update(pre_dist, lambda x: popcount(distance[x]))
                hcl.print((), "sum of 1s suc")
                hamming_dist[n] = hcl.sum(pre_dist[m], axis=m)

            #Find the one having the least hamming distance and choose it's label as the predicted label
            pred = hcl.scalar(0, 'pred')
            with hcl.for_(0, hamming_dist.shape[0]) as j:
                with hcl.if_(hamming_dist[j] < hamming_dist[pred]):
                    pred.v = j

            #Adjust the proto vectors by adding the sample vector on its label proto hdv and substrct it on its predicted proto hdv
            with hcl.if_(pred.v != trainLabels[i]):
                max[trainLabels[i]] += 1
                max[pred] -= 1
                with hcl.for_(0, dim) as m:
                    with hcl.if_(hdTrainData[i][m] == 1):
                        ###########
                        prototypeCounter[trainLabels[i]][m] += 1
                        prototypeCounter[pred][m] -= 1
                    # prototypeCounter[trainLabels[i]][m] += hdTrainData[i][m]
                    # prototypeCounter[pred][m] -= hdTrainData[i][m]
                    with hcl.if_(max[trainLabels[i]] % 2 == 0):
                        with hcl.if_(prototypeCounter[trainLabels[i]][m] -
                                     max[trainLabels[i]] / 2 == 0):
                            prototype[trainLabels[i]][m] &= 1
                    with hcl.else_():
                        prototype[trainLabels[i]][m] = hcl.select(
                            prototypeCounter[trainLabels[i]][m] -
                            max[trainLabels[i]] / 2 > 0, 1, 0)

                    with hcl.if_(max[pred] % 2 == 0):
                        with hcl.if_(prototypeCounter[pred][m] -
                                     max[pred] / 2 == 0):
                            prototype[pred][m] &= 1
                    with hcl.else_():
                        prototype[pred][m] = hcl.select(
                            prototypeCounter[pred][m] - max[pred] / 2 > 0, 1,
                            0)

        #print the accuracy
        hcl.mutate(
            (1, ),
            lambda x: test_hdc_accu(prototype, pack_train, trainLabels, 1),
            'training_update')
        hcl.mutate(
            (1, ),
            lambda x: test_hdc_accu(prototype, pack_test, testLabels, 2),
            'testing_update')
示例#6
0
 def kernel(A):
     with hcl.for_(0, 10) as i:
         with hcl.if_(i > 5):
             hcl.break_()
         A[i] = i
示例#7
0
 def kernel(A):
     with hcl.if_(A[0] > 5):
         A[0] = 5
示例#8
0
def spa_derivX1_5d(i, j, k, l, m, V,
                   g):  # Left -> right == Outer Most -> Inner Most
    left_deriv = hcl.scalar(0, "left_deriv")
    right_deriv = hcl.scalar(0, "right_deriv")

    dim_idx = 0

    u_i = V[i, j, k, l, m]

    with hcl.if_(i == 0):
        u_i_minus_1 = hcl.scalar(0, "u_i_minus_1")

        u_i_plus_1 = V[i + 1, j, k, l, m]
        u_i_plus_2 = V[i + 2, j, k, l, m]

        u_i_minus_1[0] = u_i + my_abs(u_i_plus_1 - u_i) * my_sign(u_i)

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1[0]) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.elif_(i == V.shape[dim_idx] - 1):
        u_i_plus_1 = hcl.scalar(0, "u_i_plus_1")
        u_i_plus_2 = hcl.scalar(0, "u_i_plus_2")

        u_i_minus_1 = V[i - 1, j, k, l, m]

        u_i_plus_1[0] = u_i + my_abs(u_i - u_i_minus_1) * my_sign(u_i)
        u_i_plus_2[0] = u_i_plus_1[0] + my_abs(u_i_plus_1[0] - u_i) * my_sign(
            u_i_plus_1[0])

        D1_i_plus_half = (u_i_plus_1[0] - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2[0]
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1[0]) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.elif_(i == V.shape[dim_idx] - 2):
        u_i_plus_2 = hcl.scalar(0, "u_i_plus_2")

        u_i_plus_1 = V[i + 1, j, k, l, m]

        u_i_minus_1 = V[i - 1, j, k, l, m]

        u_i_plus_2[0] = u_i_plus_1 + my_abs(u_i_plus_1 -
                                            u_i) * my_sign(u_i_plus_1)

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2[0]
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.else_():
        u_i_minus_1 = V[i - 1, j, k, l, m]

        u_i_plus_1 = V[i + 1, j, k, l, m]
        u_i_plus_2 = V[i + 2, j, k, l, m]

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    return left_deriv[0], right_deriv[0]
示例#9
0
    def graph_create(V_new, V_init, x1, x2, x3, x4, t, l0, probe):
        # Specify intermediate tensors
        deriv_diff1 = hcl.compute(V_init.shape, lambda *x:0, "deriv_diff1")
        deriv_diff2 = hcl.compute(V_init.shape, lambda *x:0, "deriv_diff2")
        deriv_diff3 = hcl.compute(V_init.shape, lambda *x:0, "deriv_diff3")
        deriv_diff4 = hcl.compute(V_init.shape, lambda *x:0, "deriv_diff4")

        # Maximum derivative for each dim
        max_deriv1 = hcl.scalar(-1e9, "max_deriv1")
        max_deriv2 = hcl.scalar(-1e9, "max_deriv2")
        max_deriv3 = hcl.scalar(-1e9, "max_deriv3")
        max_deriv4 = hcl.scalar(-1e9, "max_deriv4")

        # Min derivative for each dim
        min_deriv1 = hcl.scalar(1e9, "min_deriv1")
        min_deriv2 = hcl.scalar(1e9, "min_deriv2")
        min_deriv3 = hcl.scalar(1e9, "min_deriv3")
        min_deriv4 = hcl.scalar(1e9, "min_deriv4")

        # These variables are used to dissipation calculation
        max_alpha1 = hcl.scalar(-1e9, "max_alpha1")
        max_alpha2 = hcl.scalar(-1e9, "max_alpha2")
        max_alpha3 = hcl.scalar(-1e9, "max_alpha3")
        max_alpha4 = hcl.scalar(-1e9, "max_alpha4")

        def step_bound():  # Function to calculate time step
            stepBoundInv = hcl.scalar(0, "stepBoundInv")
            stepBound = hcl.scalar(0, "stepBound")
            stepBoundInv[0] = max_alpha1[0] / g.dx[0] + max_alpha2[0] / g.dx[1] + max_alpha3[0] / g.dx[2] + max_alpha4[0] / \
                              g.dx[3]

            stepBound[0] = 0.8 / stepBoundInv[0]
            with hcl.if_(stepBound > t[1] - t[0]):
                stepBound[0] = t[1] - t[0]

            # Update the lower time ranges
            t[0] = t[0] + stepBound[0]
            # t[0] = min_deriv2[0]
            return stepBound[0]

        # Min with V_before
        def minVWithVInit(i, j, k, l):
            with hcl.if_(V_new[i, j, k, l] > V_init[i, j, k, l]):
                V_new[i, j, k, l] = V_init[i, j, k, l]

        def maxVWithVInit(i, j, k, l):
            with hcl.if_(V_new[i, j, k, l] < V_init[i, j, k, l]):
                V_new[i, j, k, l] = V_init[i, j, k, l]

        def maxVWithV0(i, j, k, l):  # Take the max
            with hcl.if_(V_new[i, j, k, l] < l0[i, j, k, l]):
                V_new[i, j, k, l] = l0[i, j, k, l]

        def minVWithV0(i, j, k, l):
            with hcl.if_(V_new[i, j, k, l] > l0[i, j, k, l]):
                V_new[i, j, k, l] = l0[i, j, k, l]

        # Calculate Hamiltonian for every grid point in V_init
        with hcl.Stage("Hamiltonian"):
            with hcl.for_(0, V_init.shape[0], name="i") as i:
                with hcl.for_(0, V_init.shape[1], name="j") as j:
                    with hcl.for_(0, V_init.shape[2], name="k") as k:
                        with hcl.for_(0, V_init.shape[3], name="l") as l:
                            # Variables to calculate dV_dx
                            dV_dx1_L = hcl.scalar(0, "dV_dx1_L")
                            dV_dx1_R = hcl.scalar(0, "dV_dx1_R")
                            dV_dx1 = hcl.scalar(0, "dV_dx1")
                            dV_dx2_L = hcl.scalar(0, "dV_dx2_L")
                            dV_dx2_R = hcl.scalar(0, "dV_dx2_R")
                            dV_dx2 = hcl.scalar(0, "dV_dx2")
                            dV_dx3_L = hcl.scalar(0, "dV_dx3_L")
                            dV_dx3_R = hcl.scalar(0, "dV_dx3_R")
                            dV_dx3 = hcl.scalar(0, "dV_dx3")
                            dV_dx4_L = hcl.scalar(0, "dV_dx4_L")
                            dV_dx4_R = hcl.scalar(0, "dV_dx4_R")
                            dV_dx4 = hcl.scalar(0, "dV_dx4")

                            # No tensor slice operation
                            # dV_dx_L[0], dV_dx_R[0] = spa_derivX(i, j, k)
                            dV_dx1_L[0], dV_dx1_R[0] = spa_derivX1_4d(i, j, k, l, V_init, g)
                            dV_dx2_L[0], dV_dx2_R[0] = spa_derivX2_4d(i, j, k, l, V_init, g)
                            dV_dx3_L[0], dV_dx3_R[0] = spa_derivX3_4d(i, j, k, l, V_init, g)
                            dV_dx4_L[0], dV_dx4_R[0] = spa_derivX4_4d(i, j, k, l, V_init, g)

                            # Saves spatial derivative diff into tables
                            deriv_diff1[i, j, k, l] = dV_dx1_R[0] - dV_dx1_L[0]
                            deriv_diff2[i, j, k, l] = dV_dx2_R[0] - dV_dx2_L[0]
                            deriv_diff3[i, j, k, l] = dV_dx3_R[0] - dV_dx3_L[0]
                            deriv_diff4[i, j, k, l] = dV_dx4_R[0] - dV_dx4_L[0]

                            # Calculate average gradient
                            dV_dx1[0] = (dV_dx1_L + dV_dx1_R) / 2
                            dV_dx2[0] = (dV_dx2_L + dV_dx2_R) / 2
                            dV_dx3[0] = (dV_dx3_L + dV_dx3_R) / 2
                            dV_dx4[0] = (dV_dx4_L + dV_dx4_R) / 2

                            #probe[i,j,k,l] = dV_dx2[0]
                            # Find optimal control
                            uOpt = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k], x4[l]),
                                                      (dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0]))

                            # Find optimal disturbance
                            dOpt = my_object.optDstb((dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0]))

                            # Find rates of changes based on dynamics equation
                            dx1_dt, dx2_dt, dx3_dt, dx4_dt = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]), uOpt, dOpt)

                            # Calculate Hamiltonian terms:
                            V_new[i, j, k, l] = -(
                                        dx1_dt * dV_dx1[0] + dx2_dt * dV_dx2[0] + dx3_dt * dV_dx3[0] + dx4_dt * dV_dx4[0])
                            # Debugging
                            # V_new[i, j, k, l] = dV_dx2[0]
                            probe[i, j, k, l] = V_init[i, j, k, l]

                            # Get derivMin
                            with hcl.if_(dV_dx1_L[0] < min_deriv1[0]):
                                min_deriv1[0] = dV_dx1_L[0]
                            with hcl.if_(dV_dx1_R[0] < min_deriv1[0]):
                                min_deriv1[0] = dV_dx1_R[0]

                            with hcl.if_(dV_dx2_L[0] < min_deriv2[0]):
                                min_deriv2[0] = dV_dx2_L[0]
                            with hcl.if_(dV_dx2_R[0] < min_deriv2[0]):
                                min_deriv2[0] = dV_dx2_R[0]

                            with hcl.if_(dV_dx3_L[0] < min_deriv3[0]):
                                min_deriv3[0] = dV_dx3_L[0]
                            with hcl.if_(dV_dx3_R[0] < min_deriv3[0]):
                                min_deriv3[0] = dV_dx3_R[0]

                            with hcl.if_(dV_dx4_L[0] < min_deriv4[0]):
                                min_deriv4[0] = dV_dx4_L[0]
                            with hcl.if_(dV_dx4_R[0] < min_deriv4[0]):
                                min_deriv4[0] = dV_dx4_R[0]

                            # Get derivMax
                            with hcl.if_(dV_dx1_L[0] > max_deriv1[0]):
                                max_deriv1[0] = dV_dx1_L[0]
                            with hcl.if_(dV_dx1_R[0] > max_deriv1[0]):
                                max_deriv1[0] = dV_dx1_R[0]

                            with hcl.if_(dV_dx2_L[0] > max_deriv2[0]):
                                max_deriv2[0] = dV_dx2_L[0]
                            with hcl.if_(dV_dx2_R[0] > max_deriv2[0]):
                                max_deriv2[0] = dV_dx2_R[0]

                            with hcl.if_(dV_dx3_L[0] > max_deriv3[0]):
                                max_deriv3[0] = dV_dx3_L[0]
                            with hcl.if_(dV_dx3_R[0] > max_deriv3[0]):
                                max_deriv3[0] = dV_dx3_R[0]

                            with hcl.if_(dV_dx4_L[0] > max_deriv4[0]):
                                max_deriv4[0] = dV_dx4_L[0]
                            with hcl.if_(dV_dx4_R[0] > max_deriv4[0]):
                                max_deriv4[0] = dV_dx4_R[0]

        # Calculate dissipation amount

        with hcl.Stage("Dissipation"):
            #dOptU = hcl.compute((4,), lambda x: 0, "dOptU")
            # Storing alphas
            dOptL1 = hcl.scalar(0, "dOptL1")
            dOptL2 = hcl.scalar(0, "dOptL2")
            dOptL3 = hcl.scalar(0, "dOptL3")
            dOptL4 = hcl.scalar(0, "dOptL4")
            # Find UPPER BOUND optimal disturbance
            dOptU1 = hcl.scalar(0, "dOptL1")
            dOptU2 = hcl.scalar(0, "dOptL2")
            dOptU3 = hcl.scalar(0, "dOptL3")
            dOptU4 = hcl.scalar(0, "dOptL4")

            alpha1 = hcl.scalar(0, "alpha1")
            alpha2 = hcl.scalar(0, "alpha2")
            alpha3 = hcl.scalar(0, "alpha3")
            alpha4 = hcl.scalar(0, "alpha4")
            # Find LOWER BOUND optimal disturbance
            dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0] = my_object.optDstb((min_deriv1[0], min_deriv2[0], \
                                                                            min_deriv3[0], min_deriv4[0]))

            dOptU1[0], dOptL2[0], dOptL3[0], dOptL4[0] = my_object.optDstb((max_deriv1[0], max_deriv2[0], \
                                                                            max_deriv3[0], max_deriv4[0]))
            uOptL1 = hcl.scalar(0, "uOptL1")
            uOptL2 = hcl.scalar(0, "uOptL2")
            uOptL3 = hcl.scalar(0, "uOptL3")
            uOptL4 = hcl.scalar(0, "uOptL4")

            # Find UPPER BOUND optimal disturbance
            uOptU1 = hcl.scalar(0, "uOptU1")
            uOptU2 = hcl.scalar(0, "uOptU2")
            uOptU3 = hcl.scalar(0, "uOptU3")
            uOptU4 = hcl.scalar(0, "uOptU4")

            with hcl.for_(0, V_init.shape[0], name="i") as i:
                with hcl.for_(0, V_init.shape[1], name="j") as j:
                    with hcl.for_(0, V_init.shape[2], name="k") as k:
                        with hcl.for_(0, V_init.shape[3], name="l") as l:
                            dx_LL1 = hcl.scalar(0, "dx_LL1")
                            dx_LL2 = hcl.scalar(0, "dx_LL2")
                            dx_LL3 = hcl.scalar(0, "dx_LL3")
                            dx_LL4 = hcl.scalar(0, "dx_LL4")

                            dx_UL1 = hcl.scalar(0, "dx_UL1")
                            dx_UL2 = hcl.scalar(0, "dx_UL2")
                            dx_UL3 = hcl.scalar(0, "dx_UL3")
                            dx_UL4 = hcl.scalar(0, "dx_UL4")

                            dx_UU1 = hcl.scalar(0, "dx_UU1")
                            dx_UU2 = hcl.scalar(0, "dx_UU2")
                            dx_UU3 = hcl.scalar(0, "dx_UU3")
                            dx_UU4 = hcl.scalar(0, "dx_UU4")

                            dx_LU1 = hcl.scalar(0, "dx_LU1")
                            dx_LU2 = hcl.scalar(0, "dx_LU2")
                            dx_LU3 = hcl.scalar(0, "dx_LU3")
                            dx_LU4 = hcl.scalar(0, "dx_LU4")

                            # Find LOWER BOUND optimal control
                            uOptL1[0], uOptL2[0], uOptL3[0], uOptL4[0]= my_object.opt_ctrl(t, (x1[i], x2[j], x3[k], x4[l]),
                                                                      (min_deriv1[0], min_deriv2[0], min_deriv3[0],
                                                                       min_deriv4[0]))

                            # Find UPPER BOUND optimal control
                            uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[0] = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k], x4[l]),
                                                                      (max_deriv1[0], max_deriv2[0], max_deriv3[0],
                                                                       max_deriv4[0]))

                            # Find magnitude of rates of changes
                            dx_LL1[0], dx_LL2[0], dx_LL3[0], dx_LL4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]),
                                                                                            (uOptL1[0], uOptL2[0],uOptL3[0], uOptL4[0]),\
                                                                                            (dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0]))
                            dx_LL1[0] = my_abs(dx_LL1[0])
                            dx_LL2[0] = my_abs(dx_LL2[0])
                            dx_LL3[0] = my_abs(dx_LL3[0])
                            dx_LL4[0] = my_abs(dx_LL4[0])

                            dx_LU1[0], dx_LU2[0], dx_LU3[0], dx_LU4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]),
                                                                                            (uOptL1[0], uOptL2[0],uOptL3[0], uOptL4[0]), \
                                                                                            (dOptU1[0], dOptU2[0], dOptU3[0], dOptU4[0]))
                            dx_LU1[0] = my_abs(dx_LU1[0])
                            dx_LU2[0] = my_abs(dx_LU2[0])
                            dx_LU3[0] = my_abs(dx_LU3[0])
                            dx_LU4[0] = my_abs(dx_LU4[0])

                            # Calculate alpha
                            alpha1[0] = my_max(dx_LL1[0], dx_LU1[0])
                            alpha2[0] = my_max(dx_LL2[0], dx_LU2[0])
                            alpha3[0] = my_max(dx_LL3[0], dx_LU3[0])
                            alpha4[0] = my_max(dx_LL4[0], dx_LU4[0])

                            #dx_UL3 = hcl.scalar(0, "dx_UL3")
                            # dx_UL1[0], dx_UL2[0], dx_UL3[0], dx_UL4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]),
                            #                                                                 uOptU, dOptL)
                            dx_UL1[0], dx_UL2[0], dx_UL3[0], dx_UL4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]),\
                                                                                            (uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[0]), \
                                                                                            (dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0]))
                            dx_UL1[0] = my_abs(dx_UL1[0])
                            dx_UL2[0] = my_abs(dx_UL2[0])
                            dx_UL3[0] = my_abs(dx_UL3[0])
                            dx_UL4[0] = my_abs(dx_UL4[0])
                            # Calculate alpha
                            alpha1[0] = my_max(alpha1[0], dx_UL1[0])
                            alpha2[0] = my_max(alpha2[0], dx_UL2[0])
                            alpha3[0] = my_max(alpha3[0], dx_UL3[0])
                            alpha4[0] = my_max(alpha4[0], dx_UL4[0])

                            dx_UU1[0], dx_UU2[0], dx_UU3[0], dx_UU4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]),
                                                                                            (uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[0]),\
                                                                                            (dOptU1[0], dOptU2[0], dOptU3[0], dOptU4[0]))
                            dx_UU1[0] = my_abs(dx_UU1[0])
                            dx_UU2[0] = my_abs(dx_UU2[0])
                            dx_UU3[0] = my_abs(dx_UU3[0])
                            dx_UU4[0] = my_abs(dx_UU4[0])
                            # Calculate alpha
                            alpha1[0] = my_max(alpha1[0], dx_UU1[0])
                            alpha2[0] = my_max(alpha2[0], dx_UU2[0])
                            alpha3[0] = my_max(alpha3[0], dx_UU3[0])
                            alpha4[0] = my_max(alpha4[0], dx_UU4[0])

                            diss = hcl.scalar(0, "diss")
                            diss[0] = 0.5 * (
                                        deriv_diff1[i, j, k, l] * alpha1[0] + deriv_diff2[i, j, k, l] * alpha2[0] + deriv_diff3[
                                    i, j, k, l] * alpha3[0] + deriv_diff4[i, j, k, l] * alpha4[0])
                            #probe[i, j, k, l] = alpha1[0]
                            #V_init[i, j, k, l] + 0.00749716 * V_new[i,j,k,l]

                            # Finally
                            V_new[i, j, k, l] = -(V_new[i, j, k, l] - diss[0])
                            #probe[i, j, k, l] = V_new[i, j, k, l]*0.00749716
                            #probe[i, j, k, l] = V_init[i, j, k, l] + V_new[i, j, k, l] *0.00749716
                            # Get maximum alphas in each dimension

                            # Calculate alphas
                            with hcl.if_(alpha1[0] > max_alpha1[0]):
                                max_alpha1[0] = alpha1[0]
                            with hcl.if_(alpha2[0] > max_alpha2[0]):
                                max_alpha2[0] = alpha2[0]
                            with hcl.if_(alpha3[0] > max_alpha3[0]):
                                max_alpha3[0] = alpha3[0]
                            with hcl.if_(alpha4[0] > max_alpha4[0]):
                                max_alpha4[0] = alpha4[0]

                                # Determine time step
        delta_t = hcl.compute((1,), lambda x: step_bound(), name="delta_t")
        # Integrate
        result = hcl.update(V_new, lambda i, j, k, l: V_init[i, j, k, l] + V_new[i, j, k, l] * delta_t[0])
        # Different computation method check
        if compMethod == 'maxVWithV0':
            result = hcl.update(V_new, lambda i, j, k, l: maxVWithV0(i, j, k, l))
        if compMethod == 'minVWithV0':
            result = hcl.update(V_new, lambda i, j, k, l: minVWithV0(i, j, k, l))
        if compMethod == 'minVWithVInit':
            result = hcl.update(V_new, lambda i, j, k, l: minVWithVInit(i, j, k, l))
        if compMethod == 'maxVWithVInit':
            result = hcl.update(V_new, lambda i, j, k, l: maxVWithVInit(i, j, k, l))

        # Copy V_new to V_init
        hcl.update(V_init, lambda i, j, k, l: V_new[i, j, k, l])
        return result
 def maxVWithV0(i, j, k):  # Take the max
     with hcl.if_(V_new[i, j, k] < l0[i, j, k]):
         V_new[i, j, k] = l0[i, j, k]
 def minVWithV0(i, j, k):
     with hcl.if_(V_new[i, j, k] > l0[i, j, k]):
         V_new[i, j, k] = l0[i, j, k]
 def maxVWithVInit(i, j, k):
     with hcl.if_(V_new[i, j, k] < V_init[i, j, k]):
         V_new[i, j, k] = V_init[i, j, k]
 def minVWithVInit(i, j, k):
     with hcl.if_(V_new[i, j, k] > V_init[i, j, k]):
         V_new[i, j, k] = V_init[i, j, k]
    def graph_create(V_new, V_init, x1, x2, x3, t, l0):
        # Specify intermediate tensors
        deriv_diff1 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff1")
        deriv_diff2 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff2")
        deriv_diff3 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff3")

        # Maximum derivative for each dim
        max_deriv1 = hcl.scalar(-1e9, "max_deriv1")
        max_deriv2 = hcl.scalar(-1e9, "max_deriv2")
        max_deriv3 = hcl.scalar(-1e9, "max_deriv3")

        # Min derivative for each dim
        min_deriv1 = hcl.scalar(1e9, "min_deriv1")
        min_deriv2 = hcl.scalar(1e9, "min_deriv2")
        min_deriv3 = hcl.scalar(1e9, "min_deriv3")

        # These variables are used to dissipation calculation
        max_alpha1 = hcl.scalar(-1e9, "max_alpha1")
        max_alpha2 = hcl.scalar(-1e9, "max_alpha2")
        max_alpha3 = hcl.scalar(-1e9, "max_alpha3")

        def step_bound():  # Function to calculate time step
            stepBoundInv = hcl.scalar(0, "stepBoundInv")
            stepBound = hcl.scalar(0, "stepBound")
            stepBoundInv[0] = max_alpha1[0] / g.dx[0] + max_alpha2[0] / g.dx[
                1] + max_alpha3[0] / g.dx[2]
            stepBound[0] = 0.8 / stepBoundInv[0]
            with hcl.if_(stepBound > t[1] - t[0]):
                stepBound[0] = t[1] - t[0]
            t[0] = t[0] + stepBound[0]
            return stepBound[0]

            # Min with V_before
        def minVWithVInit(i, j, k):
            with hcl.if_(V_new[i, j, k] > V_init[i, j, k]):
                V_new[i, j, k] = V_init[i, j, k]

        def maxVWithVInit(i, j, k):
            with hcl.if_(V_new[i, j, k] < V_init[i, j, k]):
                V_new[i, j, k] = V_init[i, j, k]

        def maxVWithV0(i, j, k):  # Take the max
            with hcl.if_(V_new[i, j, k] < l0[i, j, k]):
                V_new[i, j, k] = l0[i, j, k]

        def minVWithV0(i, j, k):
            with hcl.if_(V_new[i, j, k] > l0[i, j, k]):
                V_new[i, j, k] = l0[i, j, k]

        # Calculate Hamiltonian for every grid point in V_init
        with hcl.Stage("Hamiltonian"):
            with hcl.for_(
                    0, V_init.shape[0], name="i"
            ) as i:  # Plus 1 as for loop count stops at V_init.shape[0]
                with hcl.for_(0, V_init.shape[1], name="j") as j:
                    with hcl.for_(0, V_init.shape[2], name="k") as k:
                        # Variables to calculate dV_dx
                        dV_dx_L = hcl.scalar(0, "dV_dx_L")
                        dV_dx_R = hcl.scalar(0, "dV_dx_R")
                        dV_dx = hcl.scalar(0, "dV_dx")
                        # Variables to calculate dV_dy
                        dV_dy_L = hcl.scalar(0, "dV_dy_L")
                        dV_dy_R = hcl.scalar(0, "dV_dy_R")
                        dV_dy = hcl.scalar(0, "dV_dy")
                        # Variables to calculate dV_dtheta
                        dV_dT_L = hcl.scalar(0, "dV_dT_L")
                        dV_dT_R = hcl.scalar(0, "dV_dT_R")
                        dV_dT = hcl.scalar(0, "dV_dT")
                        # Variables to keep track of dynamics
                        # dx_dt = hcl.scalar(0, "dx_dt")
                        # dy_dt = hcl.scalar(0, "dy_dt")
                        # dtheta_dt = hcl.scalar(0, "dtheta_dt")

                        # No tensor slice operation
                        dV_dx_L[0], dV_dx_R[0] = spa_derivX(i, j, k, V_init, g)
                        dV_dy_L[0], dV_dy_R[0] = spa_derivY(i, j, k, V_init, g)
                        dV_dT_L[0], dV_dT_R[0] = spa_derivT(i, j, k, V_init, g)

                        # Saves spatial derivative diff into tables
                        deriv_diff1[i, j, k] = dV_dx_R[0] - dV_dx_L[0]
                        deriv_diff2[i, j, k] = dV_dy_R[0] - dV_dy_L[0]
                        deriv_diff3[i, j, k] = dV_dT_R[0] - dV_dT_L[0]

                        # Calculate average gradient
                        dV_dx[0] = (dV_dx_L + dV_dx_R) / 2
                        dV_dy[0] = (dV_dy_L + dV_dy_R) / 2
                        dV_dT[0] = (dV_dT_L + dV_dT_R) / 2

                        # Use method of DubinsCar to solve optimal control instead
                        uOpt = my_object.opt_ctrl(
                            t, (x1[i], x2[j], x3[k]),
                            (dV_dx[0], dV_dy[0], dV_dT[0]))
                        dOpt = my_object.optDstb(
                            t, (x1[i], x2[j], x3[k]),
                            (dV_dx[0], dV_dy[0], dV_dT[0]))

                        # Calculate dynamical rates of changes
                        dx_dt, dy_dt, dtheta_dt = my_object.dynamics(
                            t, (x1[i], x2[j], x3[k]), uOpt, dOpt)

                        # Calculate Hamiltonian terms:
                        V_new[i, j,
                              k] = -(dx_dt * dV_dx[0] + dy_dt * dV_dy[0] +
                                     dtheta_dt * dV_dT[0])
                        #probe[i, j, k] = V_new[i, j, k]

                        # Get derivMin
                        with hcl.if_(dV_dx_L[0] < min_deriv1[0]):
                            min_deriv1[0] = dV_dx_L[0]
                        with hcl.if_(dV_dx_R[0] < min_deriv1[0]):
                            min_deriv1[0] = dV_dx_R[0]

                        with hcl.if_(dV_dy_L[0] < min_deriv2[0]):
                            min_deriv2[0] = dV_dy_L[0]
                        with hcl.if_(dV_dy_R[0] < min_deriv2[0]):
                            min_deriv2[0] = dV_dy_R[0]

                        with hcl.if_(dV_dT_L[0] < min_deriv3[0]):
                            min_deriv3[0] = dV_dT_L[0]
                        with hcl.if_(dV_dT_R[0] < min_deriv3[0]):
                            min_deriv3[0] = dV_dT_R[0]

                        # Get derivMax
                        with hcl.if_(dV_dx_L[0] > max_deriv1[0]):
                            max_deriv1[0] = dV_dx_L[0]
                        with hcl.if_(dV_dx_R[0] > max_deriv1[0]):
                            max_deriv1[0] = dV_dx_R[0]

                        with hcl.if_(dV_dy_L[0] > max_deriv2[0]):
                            max_deriv2[0] = dV_dy_L[0]
                        with hcl.if_(dV_dy_R[0] > max_deriv2[0]):
                            max_deriv2[0] = dV_dy_R[0]

                        with hcl.if_(dV_dT_L[0] > max_deriv3[0]):
                            max_deriv3[0] = dV_dT_L[0]
                        with hcl.if_(dV_dT_R[0] > max_deriv3[0]):
                            max_deriv3[0] = dV_dT_R[0]

        # Calculate the dissipation
        with hcl.Stage("Dissipation"):
            # Storing alphas
            dOptL1 = hcl.scalar(0, "dOptL1")
            dOptL2 = hcl.scalar(0, "dOptL2")
            dOptL3 = hcl.scalar(0, "dOptL3")
            # Find UPPER BOUND optimal disturbance
            dOptU1 = hcl.scalar(0, "dOptU1")
            dOptU2 = hcl.scalar(0, "dOptU2")
            dOptU3 = hcl.scalar(0, "dOptU3")

            alpha1 = hcl.scalar(0, "alpha1")
            alpha2 = hcl.scalar(0, "alpha2")
            alpha3 = hcl.scalar(0, "alpha3")

            # Lower bound optimal control
            uOptL1 = hcl.scalar(0, "uOptL1")
            uOptL2 = hcl.scalar(0, "uOptL2")
            uOptL3 = hcl.scalar(0, "uOptL3")

            # Find UPPER BOUND optimal disturbance
            uOptU1 = hcl.scalar(0, "uOptU1")
            uOptU2 = hcl.scalar(0, "uOptU2")
            uOptU3 = hcl.scalar(0, "uOptU3")

            with hcl.for_(0, V_init.shape[0], name="i") as i:
                with hcl.for_(0, V_init.shape[1], name="j") as j:
                    with hcl.for_(0, V_init.shape[2], name="k") as k:
                        dx_LL1 = hcl.scalar(0, "dx_LL1")
                        dx_LL2 = hcl.scalar(0, "dx_LL2")
                        dx_LL3 = hcl.scalar(0, "dx_LL3")

                        dx_UL1 = hcl.scalar(0, "dx_UL1")
                        dx_UL2 = hcl.scalar(0, "dx_UL2")
                        dx_UL3 = hcl.scalar(0, "dx_UL3")

                        dx_UU1 = hcl.scalar(0, "dx_UU1")
                        dx_UU2 = hcl.scalar(0, "dx_UU2")
                        dx_UU3 = hcl.scalar(0, "dx_UU3")

                        dx_LU1 = hcl.scalar(0, "dx_LU1")
                        dx_LU2 = hcl.scalar(0, "dx_LU2")
                        dx_LU3 = hcl.scalar(0, "dx_LU3")

                        # Find LOWER BOUND optimal disturbance
                        dOptL1[0], dOptL2[0], dOptL3[0] = my_object.optDstb(t,  (x1[i], x2[j], x3[k]),\
                                                                            (min_deriv1[0], min_deriv2[0],min_deriv3[0]))
                        # probe[i, j, k] = dOptL1[0] + dOptL2[0] + dOptL3[0]


                        dOptU1[0], dOptU2[0], dOptU3[0] = my_object.optDstb(t, (x1[i], x2[j], x3[k]),\
                                                                            (max_deriv1[0], max_deriv2[0],max_deriv3[0]))
                        # probe[i, j, k] = dOptL1[0] + dOptL2[0] + dOptL3[0]

                        # Find LOWER BOUND optimal control
                        uOptL1[0], uOptL2[0], uOptL3[0] = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k]), \
                                                                                        (min_deriv1[0], min_deriv2[0],min_deriv3[0]))
                        # probe[i, j, k] = uOptL1[0] + uOptL2[0] + uOptL3[0]

                        # Find UPPER BOUND optimal control
                        uOptU1[0], uOptU2[0], uOptU3[0] = my_object.opt_ctrl(
                            t, (x1[i], x2[j], x3[k]),
                            (max_deriv1[0], max_deriv2[0], max_deriv3[0]))
                        #probe[i, j, k] = uOptU1[0] + uOptU2[0] + uOptU3[0]

                        # Find magnitude of rates of changes
                        dx_LL1[0], dx_LL2[0], dx_LL3[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k]),
                                                                                        (uOptL1[0], uOptL2[0], uOptL3[0]), \
                                                                                        (dOptL1[0], dOptL2[0], dOptL3[0]))
                        dx_LL1[0] = my_abs(dx_LL1[0])
                        dx_LL2[0] = my_abs(dx_LL2[0])
                        dx_LL3[0] = my_abs(dx_LL3[0])
                        #probe[i, j, k] = dx_LL1[0] + dx_LL2[0] + dx_LL3[0]

                        dx_LU1[0], dx_LU2[0], dx_LU3[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k]),
                                                                                        (uOptL1[0], uOptL2[0], uOptL3[0]), \
                                                                                        (dOptU1[0], dOptU2[0], dOptU3[0]))
                        dx_LU1[0] = my_abs(dx_LU1[0])
                        dx_LU2[0] = my_abs(dx_LU2[0])
                        dx_LU3[0] = my_abs(dx_LU3[0])

                        # Calculate alpha
                        alpha1[0] = my_max(dx_LL1[0], dx_LU1[0])
                        alpha2[0] = my_max(dx_LL2[0], dx_LU2[0])
                        alpha3[0] = my_max(dx_LL3[0], dx_LU3[0])

                        # dx_UL3 = hcl.scalar(0, "dx_UL3")
                        # dx_UL1[0], dx_UL2[0], dx_UL3[0], dx_UL4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]),
                        #                                                                 uOptU, dOptL)
                        dx_UL1[0], dx_UL2[0], dx_UL3[0]= my_object.dynamics(t, (x1[i], x2[j], x3[k]),\
                                                                                            (uOptU1[0], uOptU2[0], uOptU3[0]), \
                                                                                            (dOptL1[0], dOptL2[0], dOptL3[0]))
                        dx_UL1[0] = my_abs(dx_UL1[0])
                        dx_UL2[0] = my_abs(dx_UL2[0])
                        dx_UL3[0] = my_abs(dx_UL3[0])

                        # Calculate alpha
                        alpha1[0] = my_max(alpha1[0], dx_UL1[0])
                        alpha2[0] = my_max(alpha2[0], dx_UL2[0])
                        alpha3[0] = my_max(alpha3[0], dx_UL3[0])

                        dx_UU1[0], dx_UU2[0], dx_UU3[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k]),
                                                                                            (uOptU1[0], uOptU2[0], uOptU3[0]),\
                                                                                            (dOptU1[0], dOptU2[0], dOptU3[0]))
                        dx_UU1[0] = my_abs(dx_UU1[0])
                        dx_UU2[0] = my_abs(dx_UU2[0])
                        dx_UU3[0] = my_abs(dx_UU3[0])
                        # Calculate alpha
                        alpha1[0] = my_max(alpha1[0], dx_UU1[0])
                        alpha2[0] = my_max(alpha2[0], dx_UU2[0])
                        alpha3[0] = my_max(alpha3[0], dx_UU3[0])
                        #probe[i, j, k] = alpha1[0] + alpha2[0] + alpha3[0]

                        diss = hcl.scalar(0, "diss")
                        diss[0] = 0.5 * (deriv_diff1[i, j, k] * alpha1[0] +
                                         deriv_diff2[i, j, k] * alpha2[0] +
                                         deriv_diff3[i, j, k] * alpha3[0])
                        # probe[i, j, k] = alpha2[0]
                        # Finally
                        V_new[i, j, k] = -(V_new[i, j, k] - diss[0])
                        # probe[i, j, k] = alpha3[0]
                        # Get maximum alphas in each dimension

                        # Calculate alphas
                        with hcl.if_(alpha1[0] > max_alpha1[0]):
                            max_alpha1[0] = alpha1[0]
                        with hcl.if_(alpha2[0] > max_alpha2[0]):
                            max_alpha2[0] = alpha2[0]
                        with hcl.if_(alpha3[0] > max_alpha3[0]):
                            max_alpha3[0] = alpha3[0]

        # Determine time step
        delta_t = hcl.compute((1, ), lambda x: step_bound(), name="delta_t")
        # Integrate
        result = hcl.update(
            V_new,
            lambda i, j, k: V_init[i, j, k] + V_new[i, j, k] * delta_t[0])

        # Different computation method check
        if compMethod == 'maxVWithV0':
            result = hcl.update(V_new, lambda i, j, k: maxVWithV0(i, j, k))
        if compMethod == 'minVWithV0':
            result = hcl.update(V_new, lambda i, j, k: minVWithV0(i, j, k))
        if compMethod == 'minVWithVInit':
            result = hcl.update(V_new, lambda i, j, k: minVWithVInit(i, j, k))
        if compMethod == 'maxVWithVInit':
            result = hcl.update(V_new, lambda i, j, k: maxVWithVInit(i, j, k))

        # Copy V_new to V_init
        hcl.update(V_init, lambda i, j, k: V_new[i, j, k])
        return result
示例#15
0
 def maxVWithVInit(i, j, k, l, m):
     with hcl.if_(V_new[i, j, k, l, m] < V_init[i, j, k, l, m]):
         V_new[i, j, k, l, m] = V_init[i, j, k, l, m]
示例#16
0
 def minVWithVInit(i, j, k, l):
     with hcl.if_(V_new[i, j, k, l] > V_init[i, j, k, l]):
         V_new[i, j, k, l] = V_init[i, j, k, l]
示例#17
0
 def kernel(A):
     with hcl.if_(A[0] > 5):
         A[0] = 5
     with hcl.elif_(A[0] > 3):
         A[0] = 3
示例#18
0
 def maxVWithVInit(i, j, k, l):
     with hcl.if_(V_new[i, j, k, l] < V_init[i, j, k, l]):
         V_new[i, j, k, l] = V_init[i, j, k, l]
示例#19
0
 def kernel(A):
     with hcl.for_(0, 10) as i:
         with hcl.for_(0, 10) as j:
             with hcl.if_(j >= i):
                 hcl.break_()
             A[i] += j
示例#20
0
 def maxVWithV0(i, j, k, l):  # Take the max
     with hcl.if_(V_new[i, j, k, l] < l0[i, j, k, l]):
         V_new[i, j, k, l] = l0[i, j, k, l]
示例#21
0
 def kernel(A):
     with hcl.if_(A[0] > 5):
         A[0] = 5
     with hcl.else_():
         A[0] = -1
示例#22
0
 def minVWithV0(i, j, k, l):
     with hcl.if_(V_new[i, j, k, l] > l0[i, j, k, l]):
         V_new[i, j, k, l] = l0[i, j, k, l]
示例#23
0
 def minVWithVInit(i, j, k, l, m, n):
     with hcl.if_(V_new[i, j, k, l, m, n] > V_init[i, j, k, l, m, n]):
         V_new[i, j, k, l, m, n] = V_init[i, j, k, l, m, n]
示例#24
0
    def graph_create(V_new, V_init, x1, x2, x3, x4, x5, t, l0):
        # Specify intermediate tensors
        deriv_diff1 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff1")
        deriv_diff2 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff2")
        deriv_diff3 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff3")
        deriv_diff4 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff4")
        deriv_diff5 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff5")

        # Maximum derivative for each dim
        max_deriv1 = hcl.scalar(-1e9, "max_deriv1")
        max_deriv2 = hcl.scalar(-1e9, "max_deriv2")
        max_deriv3 = hcl.scalar(-1e9, "max_deriv3")
        max_deriv4 = hcl.scalar(-1e9, "max_deriv4")
        max_deriv5 = hcl.scalar(-1e9, "max_deriv5")

        # Min derivative for each dim
        min_deriv1 = hcl.scalar(1e9, "min_deriv1")
        min_deriv2 = hcl.scalar(1e9, "min_deriv2")
        min_deriv3 = hcl.scalar(1e9, "min_deriv3")
        min_deriv4 = hcl.scalar(1e9, "min_deriv4")
        min_deriv5 = hcl.scalar(1e9, "min_deriv5")

        # These variables are used to dissipation calculation
        max_alpha1 = hcl.scalar(-1e9, "max_alpha1")
        max_alpha2 = hcl.scalar(-1e9, "max_alpha2")
        max_alpha3 = hcl.scalar(-1e9, "max_alpha3")
        max_alpha4 = hcl.scalar(-1e9, "max_alpha4")
        max_alpha5 = hcl.scalar(-1e9, "max_alpha5")

        def step_bound():  # Function to calculate time step
            stepBoundInv = hcl.scalar(0, "stepBoundInv")
            stepBound = hcl.scalar(0, "stepBound")
            stepBoundInv[0] = max_alpha1[0] / g.dx[0] + max_alpha2[0] / g.dx[1] + max_alpha3[0] / g.dx[2] + max_alpha4[
                0] / g.dx[3] \
                              + max_alpha5[0] / g.dx[4]

            stepBound[0] = 0.8 / stepBoundInv[0]
            with hcl.if_(stepBound > t[1] - t[0]):
                stepBound[0] = t[1] - t[0]

            # Update the lower time ranges
            t[0] = t[0] + stepBound[0]
            # t[0] = min_deriv2[0]
            return stepBound[0]

        def maxVWithV0(i, j, k, l, m):  # Take the max
            with hcl.if_(V_new[i, j, k, l, m] < l0[i, j, k, l, m]):
                V_new[i, j, k, l, m] = l0[i, j, k, l, m]

        def minVWithV0(i, j, k, l, m):  # Take the max
            with hcl.if_(V_new[i, j, k, l, m] > l0[i, j, k, l, m]):
                V_new[i, j, k, l, m] = l0[i, j, k, l, m]

        # Min with V_before
        def minVWithVInit(i, j, k, l, m):
            with hcl.if_(V_new[i, j, k, l, m] > V_init[i, j, k, l, m]):
                V_new[i, j, k, l, m] = V_init[i, j, k, l, m]

        def maxVWithVInit(i, j, k, l, m):
            with hcl.if_(V_new[i, j, k, l, m] < V_init[i, j, k, l, m]):
                V_new[i, j, k, l, m] = V_init[i, j, k, l, m]

        # Calculate Hamiltonian for every grid point in V_init
        with hcl.Stage("Hamiltonian"):
            with hcl.for_(0, V_init.shape[0], name="i") as i:
                with hcl.for_(0, V_init.shape[1], name="j") as j:
                    with hcl.for_(0, V_init.shape[2], name="k") as k:
                        with hcl.for_(0, V_init.shape[3], name="l") as l:
                            with hcl.for_(0, V_init.shape[4], name="m") as m:
                                # Variables to calculate dV_dx
                                dV_dx1_L = hcl.scalar(0, "dV_dx1_L")
                                dV_dx1_R = hcl.scalar(0, "dV_dx1_R")
                                dV_dx1 = hcl.scalar(0, "dV_dx1")
                                dV_dx2_L = hcl.scalar(0, "dV_dx2_L")
                                dV_dx2_R = hcl.scalar(0, "dV_dx2_R")
                                dV_dx2 = hcl.scalar(0, "dV_dx2")
                                dV_dx3_L = hcl.scalar(0, "dV_dx3_L")
                                dV_dx3_R = hcl.scalar(0, "dV_dx3_R")
                                dV_dx3 = hcl.scalar(0, "dV_dx3")
                                dV_dx4_L = hcl.scalar(0, "dV_dx4_L")
                                dV_dx4_R = hcl.scalar(0, "dV_dx4_R")
                                dV_dx4 = hcl.scalar(0, "dV_dx4")
                                dV_dx5_L = hcl.scalar(0, "dV_dx5_L")
                                dV_dx5_R = hcl.scalar(0, "dV_dx5_R")
                                dV_dx5 = hcl.scalar(0, "dV_dx5")

                                # No tensor slice operation
                                # dV_dx_L[0], dV_dx_R[0] = spa_derivX(i, j, k)
                                if accuracy == "low":
                                    dV_dx1_L[0], dV_dx1_R[0] = spa_derivX1_5d(
                                        i, j, k, l, m, V_init, g)
                                    dV_dx2_L[0], dV_dx2_R[0] = spa_derivX2_5d(
                                        i, j, k, l, m, V_init, g)
                                    dV_dx3_L[0], dV_dx3_R[0] = spa_derivX3_5d(
                                        i, j, k, l, m, V_init, g)
                                    dV_dx4_L[0], dV_dx4_R[0] = spa_derivX4_5d(
                                        i, j, k, l, m, V_init, g)
                                    dV_dx5_L[0], dV_dx5_R[0] = spa_derivX5_5d(
                                        i, j, k, l, m, V_init, g)
                                if accuracy == "high":
                                    dV_dx1_L[0], dV_dx1_R[
                                        0] = secondOrderX1_5d(
                                            i, j, k, l, m, V_init, g)
                                    dV_dx2_L[0], dV_dx2_R[
                                        0] = secondOrderX2_5d(
                                            i, j, k, l, m, V_init, g)
                                    dV_dx3_L[0], dV_dx3_R[
                                        0] = secondOrderX3_5d(
                                            i, j, k, l, m, V_init, g)
                                    dV_dx4_L[0], dV_dx4_R[
                                        0] = secondOrderX4_5d(
                                            i, j, k, l, m, V_init, g)
                                    dV_dx5_L[0], dV_dx5_R[
                                        0] = secondOrderX5_5d(
                                            i, j, k, l, m, V_init, g)

                                # Saves spatial derivative diff into tables
                                deriv_diff1[i, j, k, l,
                                            m] = dV_dx1_R[0] - dV_dx1_L[0]
                                deriv_diff2[i, j, k, l,
                                            m] = dV_dx2_R[0] - dV_dx2_L[0]
                                deriv_diff3[i, j, k, l,
                                            m] = dV_dx3_R[0] - dV_dx3_L[0]
                                deriv_diff4[i, j, k, l,
                                            m] = dV_dx4_R[0] - dV_dx4_L[0]
                                deriv_diff5[i, j, k, l,
                                            m] = dV_dx5_R[0] - dV_dx5_L[0]

                                # Calculate average gradient
                                dV_dx1[0] = (dV_dx1_L + dV_dx1_R) / 2
                                dV_dx2[0] = (dV_dx2_L + dV_dx2_R) / 2
                                dV_dx3[0] = (dV_dx3_L + dV_dx3_R) / 2
                                dV_dx4[0] = (dV_dx4_L + dV_dx4_R) / 2
                                dV_dx5[0] = (dV_dx5_L + dV_dx5_R) / 2

                                # Find optimal control
                                uOpt = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k], x4[l], x5[m]), \
                                (dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0], dV_dx5[0]))
                                # Find optimal disturbance
                                dOpt = my_object.opt_dstb(t, (x1[i], x2[j], x3[k], x4[l], x5[m]), \
                                (dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0], dV_dx5[0]))

                                # Find rates of changes based on dynamics equation
                                dx1_dt, dx2_dt, dx3_dt, dx4_dt, dx5_dt = my_object.dynamics(
                                    t, (x1[i], x2[j], x3[k], x4[l], x5[m]),
                                    uOpt, dOpt)

                                # Calculate Hamiltonian terms:
                                V_new[i, j, k, l, m] = -(
                                    dx1_dt * dV_dx1[0] + dx2_dt * dV_dx2[0] +
                                    dx3_dt * dV_dx3[0] + dx4_dt * dV_dx4[0] +
                                    dx5_dt * dV_dx5[0])

                                # Get derivMin
                                with hcl.if_(dV_dx1_L[0] < min_deriv1[0]):
                                    min_deriv1[0] = dV_dx1_L[0]
                                with hcl.if_(dV_dx1_R[0] < min_deriv1[0]):
                                    min_deriv1[0] = dV_dx1_R[0]

                                with hcl.if_(dV_dx2_L[0] < min_deriv2[0]):
                                    min_deriv2[0] = dV_dx2_L[0]
                                with hcl.if_(dV_dx2_R[0] < min_deriv2[0]):
                                    min_deriv2[0] = dV_dx2_R[0]

                                with hcl.if_(dV_dx3_L[0] < min_deriv3[0]):
                                    min_deriv3[0] = dV_dx3_L[0]
                                with hcl.if_(dV_dx3_R[0] < min_deriv3[0]):
                                    min_deriv3[0] = dV_dx3_R[0]

                                with hcl.if_(dV_dx4_L[0] < min_deriv4[0]):
                                    min_deriv4[0] = dV_dx4_L[0]
                                with hcl.if_(dV_dx4_R[0] < min_deriv4[0]):
                                    min_deriv4[0] = dV_dx4_R[0]

                                with hcl.if_(dV_dx5_L[0] < min_deriv5[0]):
                                    min_deriv5[0] = dV_dx5_L[0]
                                with hcl.if_(dV_dx5_R[0] < min_deriv5[0]):
                                    min_deriv5[0] = dV_dx5_R[0]

                                # Get derivMax
                                with hcl.if_(dV_dx1_L[0] > max_deriv1[0]):
                                    max_deriv1[0] = dV_dx1_L[0]
                                with hcl.if_(dV_dx1_R[0] > max_deriv1[0]):
                                    max_deriv1[0] = dV_dx1_R[0]

                                with hcl.if_(dV_dx2_L[0] > max_deriv2[0]):
                                    max_deriv2[0] = dV_dx2_L[0]
                                with hcl.if_(dV_dx2_R[0] > max_deriv2[0]):
                                    max_deriv2[0] = dV_dx2_R[0]

                                with hcl.if_(dV_dx3_L[0] > max_deriv3[0]):
                                    max_deriv3[0] = dV_dx3_L[0]
                                with hcl.if_(dV_dx3_R[0] > max_deriv3[0]):
                                    max_deriv3[0] = dV_dx3_R[0]

                                with hcl.if_(dV_dx4_L[0] > max_deriv4[0]):
                                    max_deriv4[0] = dV_dx4_L[0]
                                with hcl.if_(dV_dx4_R[0] > max_deriv4[0]):
                                    max_deriv4[0] = dV_dx4_R[0]

                                with hcl.if_(dV_dx5_L[0] > max_deriv5[0]):
                                    max_deriv5[0] = dV_dx5_L[0]
                                with hcl.if_(dV_dx5_R[0] > max_deriv5[0]):
                                    max_deriv5[0] = dV_dx5_R[0]

        # Calculate dissipation amount
        with hcl.Stage("Dissipation"):
            uOptL1 = hcl.scalar(0, "uOptL1")
            uOptL2 = hcl.scalar(0, "uOptL2")
            uOptL3 = hcl.scalar(0, "uOptL3")
            uOptL4 = hcl.scalar(0, "uOptL4")
            uOptL5 = hcl.scalar(0, "uOptL5")

            uOptU1 = hcl.scalar(0, "uOptU1")
            uOptU2 = hcl.scalar(0, "uOptU2")
            uOptU3 = hcl.scalar(0, "uOptU3")
            uOptU4 = hcl.scalar(0, "uOptU4")
            uOptU5 = hcl.scalar(0, "uOptU5")

            dOptL1 = hcl.scalar(0, "dOptL1")
            dOptL2 = hcl.scalar(0, "dOptL2")
            dOptL3 = hcl.scalar(0, "dOptL3")
            dOptL4 = hcl.scalar(0, "dOptL4")
            dOptL5 = hcl.scalar(0, "dOptL5")

            dOptU1 = hcl.scalar(0, "dOptU1")
            dOptU2 = hcl.scalar(0, "dOptU2")
            dOptU3 = hcl.scalar(0, "dOptU3")
            dOptU4 = hcl.scalar(0, "dOptU4")
            dOptU5 = hcl.scalar(0, "dOptU5")

            # Storing alphas
            alpha1 = hcl.scalar(0, "alpha1")
            alpha2 = hcl.scalar(0, "alpha2")
            alpha3 = hcl.scalar(0, "alpha3")
            alpha4 = hcl.scalar(0, "alpha4")
            alpha5 = hcl.scalar(0, "alpha5")
            """ 
                NOTE: If optimal adversarial disturbance is not dependent on states
                , the below approximate LOWER/UPPER BOUND optimal disturbance is  accurate.
                If that's not the case, move the next two statements into the nested loops and modify the states passed in 
                as my_object.opt_dstb(t, (x1[i], x2[j], x3[k], x4[l], ...), ...).
                The reason we don't have this line in the nested loop by default is to avoid redundant computations
                for certain systems where disturbance are not dependent on states.
                In general, dissipation amount can just be approximates.  
            """

            # Find LOWER BOUND optimal disturbance
            dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0], dOptL5[0] = my_object.opt_dstb(t, (x1[0], x2[0], x3[0], x4[0], x5[0]), \
                                                    (min_deriv1[0], min_deriv2[0], min_deriv3[0], min_deriv4[0], min_deriv5[0]))
            # Find UPPER BOUND optimal disturbance
            dOptU1[0], dOptU2[0], dOptU3[0], dOptU4[0], dOptU5[0] = my_object.opt_dstb(t, (x1[0], x2[0], x3[0], x4[0], x5[0]), \
                                                    (max_deriv1[0], max_deriv2[0], max_deriv3[0], max_deriv4[0], max_deriv5[0]))
            with hcl.for_(0, V_init.shape[0], name="i") as i:
                with hcl.for_(0, V_init.shape[1], name="j") as j:
                    with hcl.for_(0, V_init.shape[2], name="k") as k:
                        with hcl.for_(0, V_init.shape[3], name="l") as l:
                            with hcl.for_(0, V_init.shape[4], name="m") as m:
                                dx_LL1 = hcl.scalar(0, "dx_LL1")
                                dx_LL2 = hcl.scalar(0, "dx_LL2")
                                dx_LL3 = hcl.scalar(0, "dx_LL3")
                                dx_LL4 = hcl.scalar(0, "dx_LL4")
                                dx_LL5 = hcl.scalar(0, "dx_LL5")

                                dx_UL1 = hcl.scalar(0, "dx_UL1")
                                dx_UL2 = hcl.scalar(0, "dx_UL2")
                                dx_UL3 = hcl.scalar(0, "dx_UL3")
                                dx_UL4 = hcl.scalar(0, "dx_UL4")
                                dx_UL5 = hcl.scalar(0, "dx_UL5")
                                #
                                dx_LU1 = hcl.scalar(0, "dx_LU1")
                                dx_LU2 = hcl.scalar(0, "dx_LU2")
                                dx_LU3 = hcl.scalar(0, "dx_LU3")
                                dx_LU4 = hcl.scalar(0, "dx_LU4")
                                dx_LU5 = hcl.scalar(0, "dx_LU5")

                                dx_UU1 = hcl.scalar(0, "dx_UU1")
                                dx_UU2 = hcl.scalar(0, "dx_UU2")
                                dx_UU3 = hcl.scalar(0, "dx_UU3")
                                dx_UU4 = hcl.scalar(0, "dx_UU4")
                                dx_UU5 = hcl.scalar(0, "dx_UU5")

                                # Find LOWER BOUND optimal control
                                uOptL1[0], uOptL2[0], uOptL3[0], uOptL4[0], uOptL5[0] = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k], x4[l], x5[m]), \
                                                                        (min_deriv1[0], min_deriv2[0], min_deriv3[0], min_deriv4[0], min_deriv5[0]))
                                # Find UPPER BOUND optimal control
                                uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[0], uOptU5[0] = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k], x4[l], x5[m]), \
                                                                        (max_deriv1[0], max_deriv2[0], max_deriv3[0], max_deriv4[0], max_deriv5[0]))

                                # Get upper bound and lower bound rates of changes
                                dx_LL1[0], dx_LL2[0], dx_LL3[0], dx_LL4[0], dx_LL5[0] = my_object.dynamics(t, \
                                (x1[i], x2[j], x3[k], x4[l], x5[m]), (uOptL1[0], uOptL2[0], uOptL3[0], uOptL4[0], uOptL5[0]),
                                                                    (dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0], dOptL5[0]))
                                # Get absolute value of each
                                dx_LL1[0] = my_abs(dx_LL1[0])
                                dx_LL2[0] = my_abs(dx_LL2[0])
                                dx_LL3[0] = my_abs(dx_LL3[0])
                                dx_LL4[0] = my_abs(dx_LL4[0])
                                dx_LL5[0] = my_abs(dx_LL5[0])

                                dx_UL1[0], dx_UL2[0], dx_UL3[0], dx_UL4[0], dx_UL5[0] = my_object.dynamics(t, \
                                (x1[i], x2[j], x3[k], x4[l], x5[m]), (uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[0], uOptU5[0]),
                                                            (dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0], dOptL5[0]))
                                # Get absolute value of each
                                dx_UL1[0] = my_abs(dx_UL1[0])
                                dx_UL2[0] = my_abs(dx_UL2[0])
                                dx_UL3[0] = my_abs(dx_UL3[0])
                                dx_UL4[0] = my_abs(dx_UL4[0])
                                dx_UL5[0] = my_abs(dx_UL5[0])

                                # Set maximum alphas
                                alpha1[0] = my_max(dx_UL1[0], dx_LL1[0])
                                alpha2[0] = my_max(dx_UL2[0], dx_LL2[0])
                                alpha3[0] = my_max(dx_UL3[0], dx_LL3[0])
                                alpha4[0] = my_max(dx_UL4[0], dx_LL4[0])
                                alpha5[0] = my_max(dx_UL5[0], dx_LL5[0])

                                dx_LU1[0], dx_LU2[0], dx_LU3[0], dx_LU4[0], dx_LU5[0] = my_object.dynamics(t, \
                                (x1[i], x2[j], x3[k], x4[l], x5[m]), (uOptL1[0], uOptL2[0], uOptL3[0], uOptL4[0], uOptL5[0]),
                                (dOptU1[0], dOptU2[0], dOptU3[0], dOptU4[0], dOptU5[0]))
                                # Get absolute value of each
                                dx_LU1[0] = my_abs(dx_LU1[0])
                                dx_LU2[0] = my_abs(dx_LU2[0])
                                dx_LU3[0] = my_abs(dx_LU3[0])
                                dx_LU4[0] = my_abs(dx_LU4[0])
                                dx_LU5[0] = my_abs(dx_LU5[0])

                                alpha1[0] = my_max(alpha1[0], dx_LU1[0])
                                alpha2[0] = my_max(alpha2[0], dx_LU2[0])
                                alpha3[0] = my_max(alpha3[0], dx_LU3[0])
                                alpha4[0] = my_max(alpha4[0], dx_LU4[0])
                                alpha5[0] = my_max(alpha5[0], dx_LU5[0])

                                dx_UU1[0], dx_UU2[0], dx_UU3[0], dx_UU4[0], dx_UU5[0] = my_object.dynamics(t, \
                                (x1[i], x2[j], x3[k], x4[l], x5[m]), (uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[0], uOptU5[0]),
                                (dOptU1[0], dOptU2[0], dOptU3[0], dOptU4[0], dOptU5[0]))
                                dx_UU1[0] = my_abs(dx_UU1[0])
                                dx_UU2[0] = my_abs(dx_UU2[0])
                                dx_UU3[0] = my_abs(dx_UU3[0])
                                dx_UU4[0] = my_abs(dx_UU4[0])
                                dx_UU5[0] = my_abs(dx_UU5[0])

                                alpha1[0] = my_max(alpha1[0], dx_UU1[0])
                                alpha2[0] = my_max(alpha2[0], dx_UU2[0])
                                alpha3[0] = my_max(alpha3[0], dx_UU3[0])
                                alpha4[0] = my_max(alpha4[0], dx_UU4[0])
                                alpha5[0] = my_max(alpha5[0], dx_UU5[0])

                                diss = hcl.scalar(0, "diss")
                                diss[0] = 0.5 * (deriv_diff1[i, j, k, l, m] * alpha1[0] + deriv_diff2[
                                    i, j, k, l, m] * alpha2[0] \
                                                 + deriv_diff3[i, j, k, l, m] * alpha3[0] + deriv_diff4[
                                                     i, j, k, l, m] * alpha4[0] \
                                                 + deriv_diff5[i, j, k, l, m] * alpha5[0] )

                                # Finally
                                V_new[i, j, k, l,
                                      m] = -(V_new[i, j, k, l, m] - diss[0])
                                # Get maximum alphas in each dimension

                                # Calculate alphas
                                with hcl.if_(alpha1 > max_alpha1):
                                    max_alpha1[0] = alpha1[0]
                                with hcl.if_(alpha2 > max_alpha2):
                                    max_alpha2[0] = alpha2[0]
                                with hcl.if_(alpha3 > max_alpha3):
                                    max_alpha3[0] = alpha3[0]
                                with hcl.if_(alpha4 > max_alpha4):
                                    max_alpha4[0] = alpha4[0]
                                with hcl.if_(alpha5 > max_alpha5):
                                    max_alpha5[0] = alpha5[0]

        # Determine time step
        delta_t = hcl.compute((1, ), lambda x: step_bound(), name="delta_t")
        # hcl.update(t, lambda x: t[x] + delta_t[x])

        # Integrate
        # if compMethod == 'HJ_PDE':
        result = hcl.update(
            V_new, lambda i, j, k, l, m: V_init[i, j, k, l, m] + V_new[
                i, j, k, l, m] * delta_t[0])
        if compMethod == 'maxVWithV0':
            result = hcl.update(
                V_new, lambda i, j, k, l, m: maxVWithV0(i, j, k, l, m))
        if compMethod == 'minVWithV0':
            result = hcl.update(
                V_new, lambda i, j, k, l, m: minVWithV0(i, j, k, l, m))
        if compMethod == 'maxVWithVInit':
            result = hcl.update(
                V_new, lambda i, j, k, l, m: maxVWithVInit(i, j, k, l, m))
        if compMethod == 'minVWithVInit':
            result = hcl.update(
                V_new, lambda i, j, k, l, m: minVWithVInit(i, j, k, l, m))
        # Copy V_new to V_init
        hcl.update(V_init, lambda i, j, k, l, m: V_new[i, j, k, l, m])
        return result
示例#25
0
 def reducer_body(x, y):
     with hcl.if_(x > 5):
         hcl.return_(y + 1)
     with hcl.else_():
         hcl.return_(y + 2)
示例#26
0
 def minVWithV0(i, j, k, l, m):  # Take the max
     with hcl.if_(V_new[i, j, k, l, m] > l0[i, j, k, l, m]):
         V_new[i, j, k, l, m] = l0[i, j, k, l, m]
示例#27
0
def graph_6D(V_new, V_init, deriv_diff1, deriv_diff2, deriv_diff3, deriv_diff4, deriv_diff5, deriv_diff6,
             x1, x2, x3, x4, x5, x6 ,t , l0, obstacle):
    # Maximum derivative for each dim
    max_deriv1 = hcl.scalar(-1e9, "max_deriv1")
    max_deriv2 = hcl.scalar(-1e9, "max_deriv2")
    max_deriv3 = hcl.scalar(-1e9, "max_deriv3")
    max_deriv4 = hcl.scalar(-1e9, "max_deriv4")
    max_deriv5 = hcl.scalar(-1e9, "max_deriv5")
    max_deriv6 = hcl.scalar(-1e9, "max_deriv6")
    
    # Min derivative for each dim
    min_deriv1 = hcl.scalar(1e9, "min_deriv1")
    min_deriv2 = hcl.scalar(1e9, "min_deriv2")
    min_deriv3 = hcl.scalar(1e9, "min_deriv3")
    min_deriv4 = hcl.scalar(1e9, "min_deriv4")
    min_deriv5 = hcl.scalar(1e9, "min_deriv5")
    min_deriv6 = hcl.scalar(1e9, "min_deriv6")
    
    # These variables are used to dissipation calculation
    max_alpha1 = hcl.scalar(-1e9, "max_alpha1")
    max_alpha2 = hcl.scalar(-1e9, "max_alpha2")
    max_alpha3 = hcl.scalar(-1e9, "max_alpha3")
    max_alpha4 = hcl.scalar(-1e9, "max_alpha4")
    max_alpha5 = hcl.scalar(-1e9, "max_alpha5")
    max_alpha6 = hcl.scalar(-1e9, "max_alpha6")
    
    def step_bound(): # Function to calculate time step
        stepBoundInv = hcl.scalar(0, "stepBoundInv")
        stepBound    = hcl.scalar(0, "stepBound")
        stepBoundInv[0] = max_alpha1[0]/g.dx[0] + max_alpha2[0]/g.dx[1] + max_alpha3[0]/g.dx[2] + max_alpha4[0]/g.dx[3] \
                            + max_alpha5[0]/g.dx[4] + max_alpha6[0]/g.dx[5]

        stepBound[0] = 0.8/stepBoundInv[0]
        with hcl.if_(stepBound > t[1] - t[0]):
            stepBound[0] = t[1] - t[0]

        # Update the lower time ranges
        t[0] = t[0] + stepBound[0]
        #t[0] = min_deriv2[0]
        return stepBound[0]

    def maxVWithV0(i, j, k, l, m, n): # Take the max
        with hcl.if_(V_new[i, j, k, l, m, n] < l0[i, j, k, l, m, n]):
            V_new[i, j, k, l, m, n] = l0[i, j, k, l, m, n]

    # Max(V, g )
    def maxVWithCStraint(i, j, k, l, m, n):
        with hcl.if_(V_new[i, j, k, l, m, n] < obstacle[i, j, k, l, m, n]):
            V_new[i, j, k, l, m, n] = obstacle[i, j, k, l, m, n]
            
    # Calculate Hamiltonian for every grid point in V_init
    with hcl.Stage("Hamiltonian"):
        with hcl.for_(0, V_init.shape[0], name="i") as i:
            with hcl.for_(0, V_init.shape[1], name="j") as j:
                with hcl.for_(0, V_init.shape[2], name="k") as k:
                    with hcl.for_(0, V_init.shape[3], name="l") as l:
                        with hcl.for_(0, V_init.shape[4], name="m") as m:
                            with hcl.for_(0, V_init.shape[5], name="n") as n:
                                #Variables to calculate dV_dx
                                dV_dx1_L = hcl.scalar(0, "dV_dx1_L")
                                dV_dx1_R = hcl.scalar(0, "dV_dx1_R")
                                dV_dx1 = hcl.scalar(0, "dV_dx1")
                                dV_dx2_L = hcl.scalar(0, "dV_dx2_L")
                                dV_dx2_R = hcl.scalar(0, "dV_dx2_R")
                                dV_dx2 = hcl.scalar(0, "dV_dx2")
                                dV_dx3_L = hcl.scalar(0, "dV_dx3_L")
                                dV_dx3_R = hcl.scalar(0, "dV_dx3_R")
                                dV_dx3 = hcl.scalar(0, "dV_dx3")
                                dV_dx4_L = hcl.scalar(0, "dV_dx4_L")
                                dV_dx4_R = hcl.scalar(0, "dV_dx4_R")
                                dV_dx4 = hcl.scalar(0, "dV_dx4")
                                dV_dx5_L = hcl.scalar(0, "dV_dx5_L")
                                dV_dx5_R = hcl.scalar(0, "dV_dx5_R")
                                dV_dx5 = hcl.scalar(0, "dV_dx5")
                                dV_dx6_L = hcl.scalar(0, "dV_dx6_L")
                                dV_dx6_R = hcl.scalar(0, "dV_dx6_R")
                                dV_dx6 = hcl.scalar(0, "dV_dx6")

                                # No tensor slice operation
                                #dV_dx_L[0], dV_dx_R[0] = spa_derivX(i, j, k)
                                dV_dx1_L[0], dV_dx1_R[0] = spa_derivX6_6d(i, j, k, l, m, n, V_init, g)
                                dV_dx2_L[0], dV_dx2_R[0] = spa_derivX5_6d(i, j, k, l, m, n, V_init, g)
                                dV_dx3_L[0], dV_dx3_R[0] = spa_derivX4_6d(i, j, k, l, m, n, V_init, g)
                                dV_dx4_L[0], dV_dx4_R[0] = spa_derivX3_6d(i, j, k, l, m, n, V_init, g)
                                dV_dx5_L[0], dV_dx5_R[0] = spa_derivX2_6d(i, j, k, l, m, n, V_init, g)
                                dV_dx6_L[0], dV_dx6_R[0] = spa_derivX1_6d(i, j, k, l, m, n, V_init, g)

                                # Saves spatial derivative diff into tables
                                deriv_diff1[i, j, k, l, m, n] = dV_dx1_R[0] - dV_dx1_L[0]
                                deriv_diff2[i, j, k, l, m, n] = dV_dx2_R[0] - dV_dx2_L[0]
                                deriv_diff3[i, j, k, l, m, n] = dV_dx3_R[0] - dV_dx3_L[0]
                                deriv_diff4[i, j, k, l, m, n] = dV_dx4_R[0] - dV_dx4_L[0]
                                deriv_diff5[i, j, k, l, m, n] = dV_dx5_R[0] - dV_dx5_L[0]
                                deriv_diff6[i, j, k, l, m, n] = dV_dx6_R[0] - dV_dx6_L[0]

                                #Calculate average gradient
                                dV_dx1[0] = (dV_dx1_L + dV_dx1_R) / 2
                                dV_dx2[0] = (dV_dx2_L + dV_dx2_R) / 2
                                dV_dx3[0] = (dV_dx3_L + dV_dx3_R) / 2
                                dV_dx4[0] = (dV_dx4_L + dV_dx4_R) / 2
                                dV_dx5[0] = (dV_dx5_L + dV_dx5_R) / 2
                                dV_dx6[0] = (dV_dx6_L + dV_dx6_R) / 2


                                # Find optimal control
                                uOpt = my_object.opt_ctrl(t,(x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), (dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0], dV_dx5[0], dV_dx6[0]))
                                # Find optimal disturbance
                                dOpt = my_object.opt_dstb((dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0], dV_dx5[0], dV_dx6[0]))

                                # Find rates of changes based on dynamics equation
                                dx1_dt, dx2_dt, dx3_dt, dx4_dt, dx5_dt, dx6_dt = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOpt, dOpt)

                                # Calculate Hamiltonian terms:
                                V_new[i, j, k, l, m, n] = -(dx1_dt * dV_dx1[0] + dx2_dt * dV_dx2[0] + dx3_dt * dV_dx3[0] + dx4_dt * dV_dx4[0] + dx5_dt * dV_dx5[0] + dx6_dt * dV_dx6[0])
                                
                                # Get derivMin
                                with hcl.if_(dV_dx1_L[0] < min_deriv1[0]):
                                    min_deriv1[0] = dV_dx1_L[0]
                                with hcl.if_(dV_dx1_R[0] < min_deriv1[0]):
                                    min_deriv1[0] = dV_dx1_R[0]

                                with hcl.if_(dV_dx2_L[0] < min_deriv2[0]):
                                    min_deriv2[0] = dV_dx2_L[0]
                                with hcl.if_(dV_dx2_R[0] < min_deriv2[0]):
                                    min_deriv2[0] = dV_dx2_R[0]

                                with hcl.if_(dV_dx3_L[0] < min_deriv3[0]):
                                    min_deriv3[0] = dV_dx3_L[0]
                                with hcl.if_(dV_dx3_R[0] < min_deriv3[0]):
                                    min_deriv3[0] = dV_dx3_R[0]

                                with hcl.if_(dV_dx4_L[0] < min_deriv4[0]):
                                    min_deriv4[0] = dV_dx4_L[0]
                                with hcl.if_(dV_dx4_R[0] < min_deriv4[0]):
                                    min_deriv4[0] = dV_dx4_R[0]

                                with hcl.if_(dV_dx5_L[0] < min_deriv5[0]):
                                    min_deriv5[0] = dV_dx5_L[0]
                                with hcl.if_(dV_dx5_R[0] < min_deriv5[0]):
                                    min_deriv5[0] = dV_dx5_R[0]

                                with hcl.if_(dV_dx6_L[0] < min_deriv6[0]):
                                    min_deriv6[0] = dV_dx6_L[0]
                                with hcl.if_(dV_dx6_R[0] < min_deriv6[0]):
                                    min_deriv6[0] = dV_dx6_R[0]

                                # Get derivMax
                                with hcl.if_(dV_dx1_L[0] > max_deriv1[0]):
                                    max_deriv1[0] = dV_dx1_L[0]
                                with hcl.if_(dV_dx1_R[0] > max_deriv1[0]):
                                    max_deriv1[0] = dV_dx1_R[0]

                                with hcl.if_(dV_dx2_L[0] > max_deriv2[0]):
                                    max_deriv2[0] = dV_dx2_L[0]
                                with hcl.if_(dV_dx2_R[0] > max_deriv2[0]):
                                    max_deriv2[0] = dV_dx2_R[0]

                                with hcl.if_(dV_dx3_L[0] > max_deriv3[0]):
                                    max_deriv3[0] = dV_dx3_L[0]
                                with hcl.if_(dV_dx3_R[0] > max_deriv3[0]):
                                    max_deriv3[0] = dV_dx3_R[0]

                                with hcl.if_(dV_dx4_L[0] > max_deriv4[0]):
                                    max_deriv4[0] = dV_dx4_L[0]
                                with hcl.if_(dV_dx4_R[0] > max_deriv4[0]):
                                    max_deriv4[0] = dV_dx4_R[0]

                                with hcl.if_(dV_dx5_L[0] > max_deriv5[0]):
                                    max_deriv5[0] = dV_dx5_L[0]
                                with hcl.if_(dV_dx5_R[0] > max_deriv5[0]):
                                    max_deriv5[0] = dV_dx5_R[0]

                                with hcl.if_(dV_dx6_L[0] > max_deriv6[0]):
                                    max_deriv6[0] = dV_dx6_L[0]
                                with hcl.if_(dV_dx6_R[0] > max_deriv6[0]):
                                    max_deriv6[0] = dV_dx6_R[0]

    # Calculate dissipation amount
    with hcl.Stage("Dissipation"):
        uOptL1 = hcl.scalar(0, "uOptL1")
        uOptL2 = hcl.scalar(0, "uOptL2")
        uOptL3 = hcl.scalar(0, "uOptL3")
        uOptL4 = hcl.scalar(0, "uOptL4")


        uOptU1 = hcl.scalar(0, "uOptU1")
        uOptU2 = hcl.scalar(0, "uOptU2")
        uOptU3 = hcl.scalar(0, "uOptU3")
        uOptU4 = hcl.scalar(0, "uOptU4")

        dOptL1 = hcl.scalar(0, "dOptL1")
        dOptL2 = hcl.scalar(0, "dOptL2")
        dOptL3 = hcl.scalar(0, "dOptL3")
        dOptL4 = hcl.scalar(0, "dOptL4")

        dOptU1 = hcl.scalar(0, "dOptU1")
        dOptU2 = hcl.scalar(0, "dOptU2")
        dOptU3 = hcl.scalar(0, "dOptU3")
        dOptU4 = hcl.scalar(0, "dOptU4")

        # Storing alphas
        alpha1 = hcl.scalar(0, "alpha1")
        alpha2 = hcl.scalar(0, "alpha2")
        alpha3 = hcl.scalar(0, "alpha3")
        alpha4 = hcl.scalar(0, "alpha4")
        alpha5 = hcl.scalar(0, "alpha5")
        alpha6 = hcl.scalar(0, "alpha6")

        # Find LOWER BOUND optimal disturbance
        dOptL = my_object.opt_dstb((min_deriv1[0], min_deriv2[0], min_deriv3[0], min_deriv4[0], min_deriv5[0], min_deriv6[0]))
        # Find UPPER BOUND optimal disturbance
        dOptU = my_object.opt_dstb((max_deriv1[0], max_deriv2[0], max_deriv3[0], max_deriv4[0], min_deriv5[0], min_deriv6[0]))
        with hcl.for_(0, V_init.shape[0], name="i") as i:
            with hcl.for_(0, V_init.shape[1], name="j") as j:
                with hcl.for_(0, V_init.shape[2], name="k") as k:
                    with hcl.for_(0, V_init.shape[3], name="l") as l:
                        with hcl.for_(0, V_init.shape[4], name="m") as m:
                            with hcl.for_(0, V_init.shape[5], name="n") as n:
                                dx_LL1 = hcl.scalar(0, "dx_LL1")
                                dx_LL2 = hcl.scalar(0, "dx_LL2")
                                dx_LL3 = hcl.scalar(0, "dx_LL3")
                                dx_LL4 = hcl.scalar(0, "dx_LL4")
                                dx_LL5 = hcl.scalar(0, "dx_LL5")
                                dx_LL6 = hcl.scalar(0, "dx_LL6")

                                dx_UL1 = hcl.scalar(0, "dx_UL1")
                                dx_UL2 = hcl.scalar(0, "dx_UL2")
                                dx_UL3 = hcl.scalar(0, "dx_UL3")
                                dx_UL4 = hcl.scalar(0, "dx_UL4")
                                dx_UL5 = hcl.scalar(0, "dx_UL5")
                                dx_UL6 = hcl.scalar(0, "dx_UL6")
                                #
                                dx_LU1 = hcl.scalar(0, "dx_LU1")
                                dx_LU2 = hcl.scalar(0, "dx_LU2")
                                dx_LU3 = hcl.scalar(0, "dx_LU3")
                                dx_LU4 = hcl.scalar(0, "dx_LU4")
                                dx_LU5 = hcl.scalar(0, "dx_LU5")
                                dx_LU6 = hcl.scalar(0, "dx_LU6")

                                dx_UU1 = hcl.scalar(0, "dx_UU1")
                                dx_UU2 = hcl.scalar(0, "dx_UU2")
                                dx_UU3 = hcl.scalar(0, "dx_UU3")
                                dx_UU4 = hcl.scalar(0, "dx_UU4")
                                dx_UU5 = hcl.scalar(0, "dx_UU5")
                                dx_UU6 = hcl.scalar(0, "dx_UU6")

                                # Find LOWER BOUND optimal control
                                uOptL = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), (min_deriv1[0], min_deriv2[0], min_deriv3[0], min_deriv4[0], min_deriv5[0], min_deriv6[0]))
                                # Find UPPER BOUND optimal control
                                uOptU = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), (max_deriv1[0], max_deriv2[0], max_deriv3[0], max_deriv4[0], max_deriv5[0], max_deriv6[0]))

                                # Get upper bound and lower bound rates of changes
                                dx_LL1[0], dx_LL2[0], dx_LL3[0], dx_LL4[0], dx_LL5[0], dx_LL6[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOptL, dOptL)
                                # Get absolute value of each
                                dx_LL1[0] = my_abs(dx_LL1[0])
                                dx_LL2[0] = my_abs(dx_LL2[0])
                                dx_LL3[0] = my_abs(dx_LL3[0])
                                dx_LL4[0] = my_abs(dx_LL4[0])
                                dx_LL5[0] = my_abs(dx_LL5[0])
                                dx_LL6[0] = my_abs(dx_LL6[0])

                                dx_UL1[0], dx_UL2[0], dx_UL3[0], dx_UL4[0], dx_UL5[0], dx_UL6[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOptU, dOptL)
                                # Get absolute value of each
                                dx_UL1[0] = my_abs(dx_UL1[0])
                                dx_UL2[0] = my_abs(dx_UL2[0])
                                dx_UL3[0] = my_abs(dx_UL3[0])
                                dx_UL4[0] = my_abs(dx_UL4[0])
                                dx_UL5[0] = my_abs(dx_UL5[0])
                                dx_UL6[0] = my_abs(dx_UL6[0])

                                # Set maximum alphas
                                alpha1[0] = my_max(dx_UL1[0], dx_LL1[0])
                                alpha2[0] = my_max(dx_UL2[0], dx_LL2[0])
                                alpha3[0] = my_max(dx_UL3[0], dx_LL3[0])
                                alpha4[0] = my_max(dx_UL4[0], dx_LL4[0])
                                alpha5[0] = my_max(dx_UL5[0], dx_LL5[0])
                                alpha6[0] = my_max(dx_UL6[0], dx_LL6[0])

                                dx_LU1[0], dx_LU2[0], dx_LU3[0], dx_LU4[0], dx_LU5[0], dx_LU6[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOptL, dOptU)
                                # Get absolute value of each
                                dx_LU1[0] = my_abs(dx_LU1[0])
                                dx_LU2[0] = my_abs(dx_LU2[0])
                                dx_LU3[0] = my_abs(dx_LU3[0])
                                dx_LU4[0] = my_abs(dx_LU4[0])
                                dx_LU5[0] = my_abs(dx_LU5[0])
                                dx_LU6[0] = my_abs(dx_LU6[0])

                                alpha1[0] = my_max(alpha1[0], dx_LU1[0])
                                alpha2[0] = my_max(alpha2[0], dx_LU2[0])
                                alpha3[0] = my_max(alpha3[0], dx_LU3[0])
                                alpha4[0] = my_max(alpha4[0], dx_LU4[0])
                                alpha5[0] = my_max(alpha5[0], dx_LU5[0])
                                alpha6[0] = my_max(alpha6[0], dx_LU6[0])

                                dx_UU1[0], dx_UU2[0], dx_UU3[0], dx_UU4[0], dx_UU5[0], dx_UU6[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOptU, dOptU)
                                dx_UU1[0] = my_abs(dx_UU1[0])
                                dx_UU2[0] = my_abs(dx_UU2[0])
                                dx_UU3[0] = my_abs(dx_UU3[0])
                                dx_UU4[0] = my_abs(dx_UU4[0])
                                dx_UU5[0] = my_abs(dx_UU5[0])
                                dx_UU6[0] = my_abs(dx_UU6[0])

                                alpha1[0] = my_max(alpha1[0], dx_UU1[0])
                                alpha2[0] = my_max(alpha2[0], dx_UU2[0])
                                alpha3[0] = my_max(alpha3[0], dx_UU3[0])
                                alpha4[0] = my_max(alpha4[0], dx_UU4[0])
                                alpha5[0] = my_max(alpha5[0], dx_UU5[0])
                                alpha6[0] = my_max(alpha6[0], dx_UU6[0])

                                diss = hcl.scalar(0, "diss")
                                diss[0] = 0.5*(deriv_diff1[i, j, k, l, m, n]*alpha1[0] + deriv_diff2[i, j, k, l, m, n]*alpha2[0] \
                                               + deriv_diff3[i, j, k, l, m, n]* alpha3[0] + deriv_diff4[i, j, k, l, m, n]* alpha4[0] \
                                               + deriv_diff5[i, j, k, l, m, n]* alpha5[0] + deriv_diff6[i, j, k, l, m, n]* alpha6[0])

                                # Finally
                                V_new[i, j, k, l, m, n] = -(V_new[i, j, k, l, m, n] - diss[0])
                                # Get maximum alphas in each dimension

                                # Calculate alphas
                                with hcl.if_(alpha1 > max_alpha1):
                                    max_alpha1[0] = alpha1[0]
                                with hcl.if_(alpha2 > max_alpha2):
                                    max_alpha2[0] = alpha2[0]
                                with hcl.if_(alpha3 > max_alpha3):
                                    max_alpha3[0] = alpha3[0]
                                with hcl.if_(alpha4 > max_alpha4):
                                    max_alpha4[0] = alpha4[0]
                                with hcl.if_(alpha5 > max_alpha5):
                                    max_alpha5[0] = alpha5[0]
                                with hcl.if_(alpha6 > max_alpha6):
                                    max_alpha6[0] = alpha6[0]


    # Determine time step
    delta_t = hcl.compute((1,), lambda x: step_bound(), name="delta_t")
    #hcl.update(t, lambda x: t[x] + delta_t[x])

    # Integrate
    #if compMethod == 'HJ_PDE':
    result = hcl.update(V_new, lambda i, j, k, l, m, n: V_init[i, j, k, l, m, n] + V_new[i, j, k, l, m, n] * delta_t[0])
    if compMethod == 'maxVWithV0':
        result = hcl.update(V_new, lambda i, j, k, l, m, n: maxVWithV0(i, j, k, l, m, n))
    if compMethod == 'maxVWithCStraint':
        result = hcl.update(V_new, lambda i, j, k, l, m, n: maxVWithCStraint(i, j, k, l, m, n))
    # Copy V_new to V_init
    hcl.update(V_init, lambda i, j, k, l, m, n: V_new[i, j, k, l, m, n])
    return result
示例#28
0
 def minVWithVInit(i, j, k, l, m):
     with hcl.if_(V_new[i, j, k, l, m] > V_init[i, j, k, l, m]):
         V_new[i, j, k, l, m] = V_init[i, j, k, l, m]
示例#29
0
 def solve_Vopt(Vopt, actions, intermeds, trans, interpV, gamma, epsilon,
                iVals, sVals, bounds, goal, ptsEachDim, count, maxIters,
                useNN, fillVal):
     reSweep = hcl.scalar(1, "reSweep")
     oldV = hcl.scalar(0, "oldV")
     newV = hcl.scalar(0, "newV")
     with hcl.while_(hcl.and_(reSweep[0] == 1, count[0] < maxIters[0])):
         reSweep[0] = 0
         # Perform value iteration by sweeping in direction 1
         with hcl.Stage("Sweep_1"):
             with hcl.for_(0, Vopt.shape[0], name="i") as i:
                 with hcl.for_(0, Vopt.shape[1], name="j") as j:
                     with hcl.for_(0, Vopt.shape[2], name="k") as k:
                         oldV[0] = Vopt[i, j, k]
                         updateVopt(MDP_object, i, j, k, iVals, sVals,
                                    actions, Vopt, intermeds, trans,
                                    interpV, gamma, bounds, goal,
                                    ptsEachDim, useNN, fillVal)
                         newV[0] = Vopt[i, j, k]
                         evaluateConvergence(newV, oldV, epsilon, reSweep)
             count[0] += 1
         # Perform value iteration by sweeping in direction 2
         with hcl.Stage("Sweep_2"):
             with hcl.if_(useNN[0] == 1):
                 with hcl.for_(1, Vopt.shape[0] + 1, name="i") as i:
                     with hcl.for_(1, Vopt.shape[1] + 1, name="j") as j:
                         with hcl.for_(1, Vopt.shape[2] + 1, name="k") as k:
                             i2 = Vopt.shape[0] - i
                             j2 = Vopt.shape[1] - j
                             k2 = Vopt.shape[2] - k
                             oldV[0] = Vopt[i2, j2, k2]
                             updateVopt(MDP_object, i2, j2, k2, iVals,
                                        sVals, actions, Vopt, intermeds,
                                        trans, interpV, gamma, bounds, goal,
                                        ptsEachDim, useNN, fillVal)
                             newV[0] = Vopt[i2, j2, k2]
                             evaluateConvergence(newV, oldV, epsilon,
                                                 reSweep)
                 count[0] += 1
         # Perform value iteration by sweeping in direction 3
         with hcl.Stage("Sweep_3"):
             with hcl.if_(useNN[0] == 1):
                 with hcl.for_(1, Vopt.shape[0] + 1, name="i") as i:
                     with hcl.for_(0, Vopt.shape[1], name="j") as j:
                         with hcl.for_(0, Vopt.shape[2], name="k") as k:
                             i2 = Vopt.shape[0] - i
                             oldV[0] = Vopt[i2, j, k]
                             updateVopt(MDP_object, i2, j, k, iVals, sVals,
                                        actions, Vopt, intermeds, trans,
                                        interpV, gamma, bounds, goal,
                                        ptsEachDim, useNN, fillVal)
                             newV[0] = Vopt[i2, j, k]
                             evaluateConvergence(newV, oldV, epsilon,
                                                 reSweep)
                 count[0] += 1
         # Perform value iteration by sweeping in direction 4
         with hcl.Stage("Sweep_4"):
             with hcl.if_(useNN[0] == 1):
                 with hcl.for_(0, Vopt.shape[0], name="i") as i:
                     with hcl.for_(1, Vopt.shape[1] + 1, name="j") as j:
                         with hcl.for_(0, Vopt.shape[2], name="k") as k:
                             j2 = Vopt.shape[1] - j
                             oldV[0] = Vopt[i, j2, k]
                             updateVopt(MDP_object, i, j2, k, iVals, sVals,
                                        actions, Vopt, intermeds, trans,
                                        interpV, gamma, bounds, goal,
                                        ptsEachDim, useNN, fillVal)
                             newV[0] = Vopt[i, j2, k]
                             evaluateConvergence(newV, oldV, epsilon,
                                                 reSweep)
                 count[0] += 1
         # Perform value iteration by sweeping in direction 5
         with hcl.Stage("Sweep_5"):
             with hcl.if_(useNN[0] == 1):
                 with hcl.for_(0, Vopt.shape[0], name="i") as i:
                     with hcl.for_(0, Vopt.shape[1], name="j") as j:
                         with hcl.for_(1, Vopt.shape[2] + 1, name="k") as k:
                             k2 = Vopt.shape[2] - k
                             oldV[0] = Vopt[i, j, k2]
                             updateVopt(MDP_object, i, j, k2, iVals, sVals,
                                        actions, Vopt, intermeds, trans,
                                        interpV, gamma, bounds, goal,
                                        ptsEachDim, useNN, fillVal)
                             newV[0] = Vopt[i, j, k2]
                             evaluateConvergence(newV, oldV, epsilon,
                                                 reSweep)
                 count[0] += 1
         # Perform value iteration by sweeping in direction 6
         with hcl.Stage("Sweep_6"):
             with hcl.if_(useNN[0] == 1):
                 with hcl.for_(1, Vopt.shape[0] + 1, name="i") as i:
                     with hcl.for_(1, Vopt.shape[1] + 1, name="j") as j:
                         with hcl.for_(0, Vopt.shape[2], name="k") as k:
                             i2 = Vopt.shape[0] - i
                             j2 = Vopt.shape[1] - j
                             oldV[0] = Vopt[i2, j2, k]
                             updateVopt(MDP_object, i2, j2, k, iVals, sVals,
                                        actions, Vopt, intermeds, trans,
                                        interpV, gamma, bounds, goal,
                                        ptsEachDim, useNN, fillVal)
                             newV[0] = Vopt[i2, j2, k]
                             evaluateConvergence(newV, oldV, epsilon,
                                                 reSweep)
                 count[0] += 1
         # Perform value iteration by sweeping in direction 7
         with hcl.Stage("Sweep_7"):
             with hcl.if_(useNN[0] == 1):
                 with hcl.for_(1, Vopt.shape[0] + 1, name="i") as i:
                     with hcl.for_(0, Vopt.shape[1], name="j") as j:
                         with hcl.for_(1, Vopt.shape[2] + 1, name="k") as k:
                             i2 = Vopt.shape[0] - i
                             k2 = Vopt.shape[2] - k
                             oldV[0] = Vopt[i2, j, k2]
                             updateVopt(MDP_object, i2, j, k2, iVals, sVals,
                                        actions, Vopt, intermeds, trans,
                                        interpV, gamma, bounds, goal,
                                        ptsEachDim, useNN, fillVal)
                             newV[0] = Vopt[i2, j, k2]
                             evaluateConvergence(newV, oldV, epsilon,
                                                 reSweep)
                 count[0] += 1
         # Perform value iteration by sweeping in direction 8
         with hcl.Stage("Sweep_8"):
             with hcl.if_(useNN[0] == 1):
                 with hcl.for_(0, Vopt.shape[0], name="i") as i:
                     with hcl.for_(1, Vopt.shape[1] + 1, name="j") as j:
                         with hcl.for_(1, Vopt.shape[2] + 1, name="k") as k:
                             j2 = Vopt.shape[1] - j
                             k2 = Vopt.shape[2] - k
                             oldV[0] = Vopt[i, j2, k2]
                             updateVopt(MDP_object, i, j2, k2, iVals, sVals,
                                        actions, Vopt, intermeds, trans,
                                        interpV, gamma, bounds, goal,
                                        ptsEachDim, useNN, fillVal)
                             newV[0] = Vopt[i, j2, k2]
                             evaluateConvergence(newV, oldV, epsilon,
                                                 reSweep)
                 count[0] += 1
def spa_derivY(i, j, k, V, g):
    left_deriv = hcl.scalar(0, "left_deriv")
    right_deriv = hcl.scalar(0, "right_deriv")

    dim_idx = 1

    u_i = V[i, j, k]

    with hcl.if_(j == 0):
        u_i_minus_1 = hcl.scalar(0, "u_i_minus_1")

        u_i_plus_1 = V[i, j + 1, k]
        u_i_plus_2 = V[i, j + 2, k]

        u_i_minus_1[0] = u_i + my_abs(u_i_plus_1 - u_i) * my_sign(u_i)

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1[0]) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.elif_(j == V.shape[dim_idx] - 1):
        u_i_plus_1 = hcl.scalar(0, "u_i_plus_1")
        u_i_plus_2 = hcl.scalar(0, "u_i_plus_2")

        u_i_minus_1 = V[i, j - 1, k]

        u_i_plus_1[0] = u_i + my_abs(u_i - u_i_minus_1) * my_sign(u_i)
        u_i_plus_2[0] = u_i_plus_1[0] + my_abs(u_i_plus_1[0] - u_i) * my_sign(
            u_i_plus_1[0])

        D1_i_plus_half = (u_i_plus_1[0] - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2[0]
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1[0]) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.elif_(j == V.shape[dim_idx] - 2):
        u_i_plus_2 = hcl.scalar(0, "u_i_plus_2")

        u_i_plus_1 = V[i, j + 1, k]

        u_i_minus_1 = V[i, j - 1, k]

        u_i_plus_2[0] = u_i_plus_1 + my_abs(u_i_plus_1 -
                                            u_i) * my_sign(u_i_plus_1)

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2[0]
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    with hcl.else_():
        u_i_minus_1 = V[i, j - 1, k]

        u_i_plus_1 = V[i, j + 1, k]
        u_i_plus_2 = V[i, j + 2, k]

        D1_i_plus_half = (u_i_plus_1 - u_i) / g.dx[dim_idx]
        D1_i_minus_half = (u_i - u_i_minus_1) / g.dx[dim_idx]

        Q1d_left = D1_i_minus_half
        Q1d_right = D1_i_plus_half

        D2_i = 0.5 * ((D1_i_plus_half - D1_i_minus_half) / g.dx[dim_idx])

        u_i_plus_1_plus_1 = u_i_plus_2
        D1_i_plus_1_plus_half = (u_i_plus_1_plus_1 -
                                 u_i_plus_1) / g.dx[dim_idx]
        D1_i_plus_1_minus_half = D1_i_plus_half
        D2_i_plus_1 = 0.5 * (
            (D1_i_plus_1_plus_half - D1_i_plus_1_minus_half) / g.dx[dim_idx])

        with hcl.if_(my_abs(D2_i) <= my_abs(D2_i_plus_1)):
            c = D2_i
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

        with hcl.else_():
            c = D2_i_plus_1
            Q2d = c * g.dx[dim_idx]

            left_deriv[0] = Q1d_left + Q2d
            right_deriv[0] = Q1d_right - Q2d

    return left_deriv[0], right_deriv[0]