0

I am trying to write an iterative procedure using the GEE Code Editor. I initially calculate a variable "AR" and if this variable is greater than a specified threshold, then an iterative procedure is repeated until the AR value is below the threshold value. I am uncertain about the most efficient way to achieve this result given the client/server constraints of the IDE. In my example, I need to use a .getInfo() call to retrieve the AR value, or else it will not be recognized and passed into the while loop. Unless there is a different way to do this? I understand this is not the best practice, especially within the loop. Please see my example code below...

var calculate_adjustment_ratio = function(x, y){
  
  // ENTER TOTAL FROM MODELED DEFORESTATION
  var modeled_deforestation = ee.Number(x)

  // ENTER EXPECTED AMOUNT OF DEFORESTATION
  var expected_deforestation = ee.Number(y)

  // CALCULATE ADJUSTMENT RATIO
  var AR = expected_deforestation.divide(modeled_deforestation)
  print(AR, 'Adjustment Ratio')
  
  return AR
}

// ENTER INITIAL INPUT PARAMETERS TO CALCULATE THE ADJUSMENT RATIO
var modeled_deforestation = 1.75
var expected_deforestation = 3

// CALCULATE INITIAL ADJUSTMENT RATIO (AR)
var AR = calculate_adjustment_ratio(modeled_deforestation,expected_deforestation).getInfo()

//////////////////////////////////////////////////////////////////////////

var update_modeled_deforestation = function(modeled_deforestation, update_deforestation){
  var updated = ee.Number(modeled_deforestation).add(ee.Number(update_deforestation))
  return updated
}

//////////////////////////////////////////////////////////////////////////

var maxIterations = 10
var iterationCount = 0
var adjustmentValue = 0.5

// IF THE INITIAL AR IS GREATER THAN 1.00001, ITERATE LOOP UNTIL AR >= 1.00001
while (AR > 1.00001 && iterationCount <= maxIterations) {
  var modeled_deforestation_new = update_modeled_deforestation(modeled_deforestation, adjustmentValue)
  AR = calculate_adjustment_ratio(modeled_deforestation_new,expected_deforestation).getInfo()
  iterationCount++
  adjustmentValue = adjustmentValue + 0.5;
  
  // Print intermediate AR value
  print("Intermediate AR (iteration " + iterationCount + "):", AR);
}

if (iterationCount <= maxIterations) {
  print("AR should be less than 1.00001")
} else {
  print("Maximum number of iterations reached");
}

1 Answer 1

1

I typically use iterate(). It is essentially the same as JavaScript's reduce(). It takes two arguments, the first is a function that will be invoked for each element in a list/collection, getting passed the element itself and an accumulated value. The returned value in this function will be the next accumulated value, or the resulting value of iterate() if it is the last element in the list/collection. Second argument is the initial value, the one being passed to the function together with the first element in your list/collection.

There is no way to short-cut it like you do with while(). All iterations will always be completed.

Here's how you can use it - I might have gotten your specific algorithm wrong, but you should get the idea.

var modeled_initial = 1.75
var expected = ee.Number(3)
var maxIterations = 9

var adjustmentValues = ee.List.sequence({start: 0.5, step: 0.5, count: maxIterations})

var finalModel = ee.Number(
  adjustmentValues
    .iterate( // iterate() is essentially a JavaScript reduce()
      function (adjustment, modeled) {
        // Arguments must always be cast to correct type
        adjustment = ee.Number(adjustment)
        modeled = ee.Number(modeled)
        var AR = ee.Number(expected).divide(modeled)
        // Instead of short cutting once you reach your AR threshold, 
        // just don't do any update when that is the case
        return ee.Algorithms.If(
          AR.gt(1.00001),
          modeled.add(adjustment),
          modeled
        )
      },
      modeled_initial // First
    )
)
print(finalModel)

https://code.earthengine.google.com/0a212c55e4ad2cb0fa1c565ca0c5235f

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.