nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/finitedifferences/TwoPointApproximation.java
public static INDArray[] adjustSchemeToBounds(INDArray x,INDArray h,int numSteps,INDArray lowerBound,INDArray upperBound) {
        INDArray oneSided = Nd4j.onesLike(h);
        if(and(lowerBound.eq(Double.NEGATIVE_INFINITY),upperBound.eq(Double.POSITIVE_INFINITY)).sumNumber().doubleValue() > 0) {
            return new INDArray[] {h,oneSided};
        }
        INDArray hTotal = h.mul(numSteps);
        INDArray hAdjusted = h.dup();
        INDArray lowerDist = x.sub(lowerBound);
        INDArray upperBound2 = upperBound.sub(x);

        INDArray central = and(greaterThanOrEqual(lowerDist,hTotal),greaterThanOrEqual(upperBound2,hTotal));
        INDArray forward = and(greaterThanOrEqual(upperBound,lowerDist),not(central));
        hAdjusted.put(forward,min(h.get(forward),upperBound2.get(forward).mul(0.5).divi(numSteps)));
        oneSided.put(forward,Nd4j.scalar(1.0));

        INDArray backward = and(upperBound2.lt(lowerBound),not(central));
        hAdjusted.put(backward,min(h.get(backward),lowerDist.get(backward).mul(0.5).divi(numSteps)));
        oneSided.put(backward,Nd4j.scalar(1.0));

        INDArray minDist = min(upperBound2,lowerDist).divi(numSteps);
        INDArray adjustedCentral = and(not(central),lessThanOrEqual(abs(hAdjusted),minDist));
        hAdjusted.put(adjustedCentral,minDist.get(adjustedCentral));
        oneSided.put(adjustedCentral,Nd4j.scalar(0.0));
        return new INDArray[] {hAdjusted,oneSided};
    }
public static INDArray[] adjustSchemeToBounds(INDArray x,INDArray h,int numSteps,INDArray lowerBound,INDArray upperBound) {
        INDArray oneSided = Nd4j.onesLike(h);
        if(and(lowerBound.eq(Double.NEGATIVE_INFINITY),upperBound.eq(Double.POSITIVE_INFINITY)).sumNumber().doubleValue() > 0) {
            return new INDArray[] {h,oneSided};
        }
        INDArray hTotal = h.mul(numSteps);
        INDArray hAdjusted = h.dup();
        INDArray lowerDist = x.sub(lowerBound);
        INDArray upperBound2 = upperBound.sub(x);

        INDArray central = and(greaterThanOrEqual(lowerDist,hTotal),greaterThanOrEqual(upperBound2,hTotal));
        INDArray forward = and(greaterThanOrEqual(upperBound,lowerDist),not(central));
        hAdjusted.put(forward,min(h.get(forward),upperBound2.get(forward).mul(0.5).divi(numSteps)));
        oneSided.put(forward,Nd4j.scalar(1.0));

        INDArray backward = and(upperBound2.lt(lowerBound),not(central));
        hAdjusted.put(backward,min(h.get(backward),lowerDist.get(backward).mul(0.5).divi(numSteps)));
        oneSided.put(backward,Nd4j.scalar(1.0));

        INDArray minDist = min(upperBound2,lowerDist).divi(numSteps);
        INDArray adjustedCentral = and(not(central),lessThanOrEqual(abs(hAdjusted),minDist));
        hAdjusted.put(adjustedCentral,minDist.get(adjustedCentral));
        oneSided.put(adjustedCentral,Nd4j.scalar(0.0));
        return new INDArray[] {hAdjusted,oneSided};
    }
public static INDArray [ ] adjustSchemeToBounds ( INDArray x , INDArray h , int numSteps , INDArray lowerBound , INDArray upperBound ) { INDArray oneSided = Nd4j . onesLike ( h ) ; if ( and ( lowerBound . eq ( Double . NEGATIVE_INFINITY ) , upperBound . eq ( Double . POSITIVE_INFINITY ) ) . sumNumber ( ) . doubleValue ( ) > 0 ) { return new INDArray [ ] { h , oneSided } ; } INDArray hTotal = h . mul ( numSteps ) ; INDArray hAdjusted = h . dup ( ) ; INDArray lowerDist = x . sub ( lowerBound ) ; INDArray upperBound2 = upperBound . sub ( x ) ; INDArray central = and ( greaterThanOrEqual ( lowerDist , hTotal ) , greaterThanOrEqual ( upperBound2 , hTotal ) ) ; INDArray forward = and ( greaterThanOrEqual ( upperBound , lowerDist ) , not ( central ) ) ; hAdjusted . put ( forward , min ( h . get ( forward ) , upperBound2 . get ( forward ) . mul ( 0.5 ) . divi ( numSteps ) ) ) ; oneSided . put ( forward , Nd4j . scalar ( 1.0 ) ) ; INDArray backward = and ( upperBound2 . lt ( lowerBound ) , not ( central ) ) ; hAdjusted . put ( backward , min ( h . get ( backward ) , lowerDist . get ( backward ) . mul ( 0.5 ) . divi ( numSteps ) ) ) ; oneSided . put ( backward , Nd4j . scalar ( 1.0 ) ) ; INDArray minDist = min ( upperBound2 , lowerDist ) . divi ( numSteps ) ; INDArray adjustedCentral = and ( not ( central ) , lessThanOrEqual ( abs ( hAdjusted ) , minDist ) ) ; hAdjusted . put ( adjustedCentral , minDist . get ( adjustedCentral ) ) ; oneSided . put ( adjustedCentral , Nd4j . scalar ( 0.0 ) ) ; return new INDArray [ ] { hAdjusted , oneSided } ; }
Adjust final scheme to presence of bounds

Returns (in this order):
adjusted hypothesis, whether to use onesided as an int mask array
@param x the point to estimate the derivative
@param h the finite difference steps
@param numSteps Number of h steps in 1 direction
to implement finite difference scheme.

@param lowerBound Lower bounds for independent variable variable
@param upperBound Upper bounds for independent variable
@return
Adjust final scheme to presence of bounds