def getPointsSpeed(dist, method_dict, n):

    method = method_dict['method']
    bnd = dist.range()
    a = bnd[0]  # lower boundary
    b = bnd[1]  # upper boundary
    a = a[0]  # get rid of the list
    b = b[0]  # get rid of the list

    if method == 'rect':

        X = np.linspace(a, b, n+1)
        dx = X[1]-X[0]
        x = X[:-1]+dx/2  # Take the midpoints of the bins
        # Get the weights associated with the points locations
        w = []
        for i in range(n):
            w.append(dist._cdf(X[i+1]) - dist._cdf(X[i]))

        w = np.array(w).flatten()

    if method == 'dakota':

        x, f = generate_speed_abscissas_ordinates(a, b, dist)
        updateDakotaFile(method_dict, n, x, f)
        # run Dakota file to get the points locations
        x, w = getSamplePoints(method_dict['dakota_filename'])
        assert len(x) == 1, 'Should only be returning the speeds'
        x = np.array(x[0])

        # Rescale x
        x = (b-a)/2. + (b-a)/2.*x + a

    if method == 'chaospy':
        x, w = cp.generate_quadrature(n-1, dist, rule='G')
        x = x[0]

    return x, w
Exemple #2
0
def getPoints(method_dict, n):

    method = method_dict['method']
    dist = method_dict['distribution']

    if dist._str() == 'Amalia windrose':  # For direction case
        # Modify the input range to start at max probability location
        # and account for zero probability regions.

        # f(x)
        #   |                   *
        #   |   ***            * *      **
        #   | **   *          *   **  **  *     ***
        #   |*      *        *      **     *  **   *
        #   |        *      *               **
        #   |         *    *
        # --+----------****-----+------------------+--
        #  lo          A  B     C                  hi    (x)
        bnd = dist.range()
        a = bnd[0]  # left boundary
        b = bnd[1]  # right boundary
        a = a[0]  # get rid of the list
        b = b[0]  # get rid of the list
        # Make sure the A, B, C values are the same than those in distribution
        A = 110  # Left boundary of zero probability region
        B = 140  # Right boundary of zero probability region
        C = 225  # Location of max probability
        r = b - a  # original range
        R = r - (B - A)  # modified range

        # Modify with offset, manually choose the offset you want
        N = method_dict['Noffset']  # N = 10
        i = method_dict['offset']  # i = [0, 1, 2, N-1]

        if method == 'rect':
            # the offset fits N points in the given dx interval
            dx = R / n
            offset = i * dx / N
            bounds = [a + offset, R + offset]
            x = np.linspace(bounds[0], bounds[1], n + 1)
            x = x[:-1] + dx / 2  # Take the midpoints of the bins
            # Modify x, to start from the max probability location
            x = modifyx(x, A, B, C, r)
            # Get the weights associated with the points locations
            w = getWeights(x, dx, dist)

        if method == 'dakota':
            # the offset modifies the starting point for 5 locations within the whole interval
            # Update dakota file with desired number of sample points
            # Use the y to set the abscissas, and the pdf to set the ordinates
            y = np.linspace(a, R, 51)  # play with the number here
            dy = y[1] - y[0]
            mid = y[:-1] + dy / 2
            # Modify the starting point C with offset
            offset = i * r / N
            C = (C + offset) % r
            # Make sure the offset is not between A and B
            if A < C and C < B:
                C = min([A, B], key=lambda x: abs(x - C)
                        )  # It doesn't really matter if C gets set to A or B

            ynew = modifyx(mid, A, B, C, r)
            f = dist.pdf(ynew)

            # Modify y to -1 to 1 range, I think makes dakota generation of polynomials easier
            y = 2 * y / 330 - 1
            updateDakotaFile(method_dict['dakota_filename'], n, y, f)
            # run Dakota file to get the points locations
            x, wd = getSamplePoints(method_dict['dakota_filename'])
            # Rescale x
            x = 330 / 2. + 330 / 2. * x
            # Call modify x with the new x.
            x = modifyx(x, A, B, C, r)
            # Get the weights associated with the points locations
            w = wd

        points = x
        weights = w

    else:  # This is mostly for speed case
        # Don't modify the range at all.
        bnd = dist.range()
        a = bnd[0]
        b = bnd[1]
        a = a[0]  # get rid of the list
        b = b[0]  # get rid of the list

        if method == 'rect':
            # the offset fits N points in the given dx interval
            # Modify with offset, manually choose the offset you want
            N = 5
            i = 0  # [-2, -1, 0, 1, 2] choose from for N=5, for general N [-int(np.floor(N/2)), ... , int(np.floor(N/2)+1]
            dx = (b - a) / n
            offset = i * dx / N
            bounds = [a + offset, b + offset]
            x = np.linspace(bounds[0], bounds[1], n + 1)
            x = x[:-1] + dx / 2  # Take the midpoints of the bins
            # Get the weights associated with the points locations
            w = []
            for xi in x:
                xleft = xi - dx / 2.
                xright = xi + dx / 2.
                if xleft < a:
                    # print 'I am in xleft'
                    xleft = a
                if xright > b:
                    # print 'I am in xright'
                    xright = b
                w.append(dist._cdf(xright) - dist._cdf(xleft))
            w = np.array(w).flatten()
            # print np.sum(w)
            # print dist._cdf(b)  # this value should weight dakota weights. b=30

        if method == 'dakota':
            # The offset doesn't really make sense for this case
            # Update dakota file with desired number of sample points
            # Use the y to set the abscissas, and the pdf to set the ordinates
            y = np.linspace(a, b, 51)  # play with the number here
            dy = y[1] - y[0]
            ymid = y[:-1] + dy / 2
            f = dist.pdf(ymid)
            # Modify y to -1 to 1 range, I think makes dakota generation of polynomials easier
            y = 2 * y / 30 - 1

            updateDakotaFile(method_dict['dakota_filename'], n, y, f)
            # run Dakota file to get the points locations
            x, wd = getSamplePoints(method_dict['dakota_filename'])
            # Rescale x
            x = 30 / 2. + 30 / 2. * x

            # Get the weights associated with the points locations
            w = wd * dist._cdf(
                b
            )  # The dakota weights assume all of the pdf is between 0-30 so we weigh it by the actual amount. This will correct the derivatives, need to also correct the mean and std values. These corrections are done in statisticsComponents.

        points = x
        weights = w
        # print weights
        # print np.sum(weights)

    return points, weights
def getPointsDirectionSpeed(dist, method_dict, n):

    method = method_dict['method']

    if method == 'rect':
        dist_dir = dist[0]
        dist_speed = dist[1]
        winddirections, weights_dir = getPointsDirection(dist_dir, method_dict, n)
        windspeeds, weights_speed = getPointsSpeed(dist_speed, method_dict, n)

        # Create a 1-dimensional vector of the tensor product
        wind_dir = []
        wind_spd = []
        weights = []
        for i in range(winddirections.size):
            for j in range(windspeeds.size):
                wind_dir.append(winddirections[i])
                wind_spd.append(windspeeds[j])
                weights.append(weights_dir[i]*weights_speed[j])

        winddirections = np.array(wind_dir)
        windspeeds = np.array(wind_spd)
        weights = np.array(weights)

    if method == 'dakota':

        bnd = dist.range()
        a = bnd[0]  # left boundary
        b = bnd[1]  # right boundary
        a_d = a[0] # the left boundary for the direction
        b_d = b[0] # the right boundary for the direction
        a_s = a[1] # the left boundary for the direction
        b_s = b[1] # the right boundary for the direction

        ###### Do direction work
        dist_dir = dist[0]

        if dist_dir._str() == 'Amalia windrose':

            # Make sure the A, B, C values are the same than those in distribution
            A, B = dist_dir.get_zero_probability_region()
            # A = 110  # Left boundary of zero probability region
            # B = 140  # Right boundary of zero probability region

            C = 225  # Location of max probability or desired starting location
            r = b_d-a_d  # original range
            R = r - (B-A) # modified range

            # Modify with offset, manually choose the offset you want
            N = method_dict['Noffset']  # N = 10
            i = method_dict['offset']  # i = [0, 1, 2, N-1]

            # Modify the starting point C with offset
            offset = i*r/N  # the offset modifies the starting point for N locations within the whole interval
            C = (C + offset) % r
            x_d, f_d = generate_direction_abscissas_ordinates(a_d, A, B, C, r, R, dist_dir)

        if dist_dir._str() == 'Amalia windrose raw':

            C = 225  # Location of max probability or desired starting location.
            R = b_d-a_d  # range 360

            # Modify with offset, manually choose the offset you want
            N = method_dict['Noffset']  # N = 10
            i = method_dict['offset']  # i = [0, 1, 2, N-1]

            offset = i*R/N  # the offset modifies the starting point for N locations within the whole interval
            C = (C + offset) % R

            # Use the y to set the abscissas, and the pdf to set the ordinates
            y = np.linspace(a_d, R, 51)  # play with the number here
            dy = y[1]-y[0]
            mid = y[:-1]+dy/2

            # Modify the mid to start from the max probability location
            ynew = (mid+C) % R

            f_d = dist_dir.pdf(ynew)

            # Modify y to -1 to 1 range, I think makes dakota generation of polynomials easier
            x_d = 2*(y-a_d) / R - 1

        ####### Do the speed work
        dist_speed = dist[1]
        x_s, f_s = generate_speed_abscissas_ordinates(a_s, b_s, dist_speed)

        # Update the dakota file
        updateDakotaFile(method_dict, n, [x_d, x_s], [f_d, f_s])

        # run Dakota file to get the points locations
        # This one also needs to work for the 1 and 2d cases.
        x, w = getSamplePoints(method_dict['dakota_filename'])
        assert len(x) == 2, 'Should be returning the directions and speeds'
        x_d = np.array(x[0])
        x_s = np.array(x[1])

        # Do stuff for the direction case
        if dist_dir._str() == 'Amalia windrose':
            # Rescale x
            x_d = R*x_d/2. + R/2. + a_d  # R = 330
            # Call modify x with the new x.
            x_d = modifyx(x_d, A, B, C, r)
        if dist_dir._str() == 'Amalia windrose raw':
            # Rescale x
            x_d = R*x_d/2. + R/2. + a_d  # R = 360
            # Call modify x with the new x.
            x_d = (x_d+C) % R

        # Do stuff for the speed case
        # Rescale x
        x_s = (b_s-a_s)/2. + (b_s-a_s)/2.*x_s + a_s

        winddirections = x_d
        windspeeds = x_s
        weights = w

    return winddirections, windspeeds, weights
def getPointsRawAmaliaDistribution(dist, method_dict, n):

    method = method_dict['method']
    bnd = dist.range()
    a = bnd[0]  # left boundary
    b = bnd[1]  # right boundary
    a = a[0]  # get rid of the list
    b = b[0]  # get rid of the list

    C = 225  # Location of max probability or desired starting location.
    R = b-a  # range 360

    # Modify with offset, manually choose the offset you want
    N = method_dict['Noffset']  # N = 10
    i = method_dict['offset']  # i = [0, 1, 2, N-1]

    if method == 'rect':
        # the offset fits N points in the given dx interval
        dx = R/n
        offset = i*dx/N  # make sure this is float
        bounds = [a+offset, R+offset]
        x = np.linspace(bounds[0], bounds[1], n+1)
        x = x[:-1]+dx/2  # Take the midpoints of the bins
        # Modify x, to start from the max probability location
        x = (x+C) % R
        # Get the weights associated with the points locations
        w = getWeights(x, dx, dist)

    if method == 'dakota':

        # Modify the starting point C with offset
        offset = i*R/N  # the offset modifies the starting point for N locations within the whole interval
        C = (C + offset) % R
        # Use the y to set the abscissas, and the pdf to set the ordinates
        y = np.linspace(a, R, 51)  # play with the number here
        dy = y[1]-y[0]
        mid = y[:-1]+dy/2

        # Modify the mid to start from the max probability location
        ynew = (mid+C) % R

        f = dist.pdf(ynew)

        # Modify y to -1 to 1 range, I think makes dakota generation of polynomials easier
        x = 2*(y-a) / R - 1

        updateDakotaFile(method_dict, n, x, f)
        # run Dakota file to get the points locations
        x, w = getSamplePoints(method_dict['dakota_filename'])
        assert len(x) == 1, 'Should only be returning the directions'
        x = np.array(x[0])
        # Rescale x
        x = R*x/2. + R/2. + a

        # Call modify x with the new x.
        x = (x+C) % R

    if method == 'chaospy':
        # I need to adjust the starting position and all of that.
        x, w = cp.generate_quadrature(n-1, dist, rule='G')
        x = x[0]

    return x, w
def getPointsModifiedAmaliaDistribution(dist, method_dict, n):

    # Modify the input range to start at max probability location
    # and account for zero probability regions.

    # f(x)
    #   |                   *
    #   |   ***            * *      **
    #   | **   *          *   **  **  *     ***
    #   |*      *        *      **     *  **   *
    #   |        *      *               **
    #   |         *    *
    # --+----------****-----+------------------+--
    #  lo          A  B     C                  hi    (x)

    method = method_dict['method']
    bnd = dist.range()
    a = bnd[0]  # left boundary
    b = bnd[1]  # right boundary
    a = a[0]  # get rid of the list
    b = b[0]  # get rid of the list
    # Make sure the A, B, C values are the same than those in distribution
    A, B = dist.get_zero_probability_region()
    # A = 110  # Left boundary of zero probability region
    # B = 140  # Right boundary of zero probability region

    C = 225  # Location of max probability or desired starting location.  Don't put this between A and B.
    r = b-a  # original range
    R = r - (B-A) # modified range

    # Modify with offset, manually choose the offset you want
    N = method_dict['Noffset']  # N = 10
    i = method_dict['offset']  # i = [0, 1, 2, N-1]

    if method == 'rect':
        # the offset fits N points in the given dx interval
        dx = R/n
        offset = i*dx/N  # make sure this is float
        bounds = [a+offset, R+offset]
        x = np.linspace(bounds[0], bounds[1], n+1)
        x = x[:-1]+dx/2  # Take the midpoints of the bins
        # Modify x, to start from the max probability location
        x = modifyx(x, A, B, C, r)
        # Get the weights associated with the points locations
        w = getWeights(x, dx, dist)

    if method == 'dakota':

        # Modify the starting point C with offset
        offset = i*r/N  # the offset modifies the starting point for N locations within the whole interval
        C = (C + offset) % r
        x, f = generate_direction_abscissas_ordinates(a, A, B, C, r, R, dist)
        updateDakotaFile(method_dict, n, x, f)
        # run Dakota file to get the points locations
        x, w = getSamplePoints(method_dict['dakota_filename'])
        assert len(x) == 1, 'Should only be returning the directions'
        x = np.array(x[0])
        # Rescale x
        x = R*x/2. + R/2. + a
        # x = (330/2. + 330/2.*x  # Should be in terms of the variables
        # Call modify x with the new x.
        x = modifyx(x, A, B, C, r)

    if method == 'chaospy':
        # I need to adjust the starting position and all of that.
        x, w = cp.generate_quadrature(n-1, dist, rule='G')
        x = x[0]

    return x, w