Use Custom Function (@finite_math) to Handle NaNs in ENERGY 2100

Use @finite_math macro in equations with divide by, log, or exponents.

@finite_math:

  • Is a custom macro used in ENERGY 2100 to eliminate NaNs
  • It checks for undefined values, such as division by 0, logs of negative numbers, exp0^0, and it replaces these values with 0's.

Example:

for tech in Techs

  @finite_math MU[tech] = MMSFx[tech]/MAW[tech]

end

What are NaNs?

In Julia, NaN stands for "Not a Number" and is a special floating-point value used to represent undefined or unrepresentable numerical results, such as the result of 0/0 or square root of -1. It is a standard feature of IEEE 754 floating-point arithmetic, designed to allow computations to continue without crashing, rather than halting execution when an indeterminate result occurs. 

Here is a detailed breakdown of NaNs in Julia:


1. Key Characteristics

Type: NaN is a Float64 or Float32 value, not a separate type. It cannot be used with integers.

Propagation: NaN acts as a "data virus" - any arithmetic operation involving a NaN will result in NaN.

Comparison: NaN is never equal to anything, including itself. NaN == NaN returns false.

Equality Check: To check if a value is NaN, use isnan(x) instead of x == NaN.

Identity: isequal(NaN, NaN) is true, even though NaN == NaN is false. 

2. NaN vs. Missing

It is crucial to distinguish NaN from missing in Julia

NaN (Not a Number): Represents a failed numerical calculation

missing: Represents a value that is unknown or missing from a dataset (e.g., a survey response not filled in).

Difference: NaN is a valid number type (Float), while missing is a special object that can be part of a Union{Missing, Float64} type. 

3. How to Use NaNs

Creating NaN: You can type NaN directly, or use NaN64 / NaN32.

Checking for NaN:

julia>x = 0.0 / 0.0

isnan(x) # Returns true

Filtering NaNs: You can remove NaNs from data using filter(!isnan, array).

Ignoring NaNs in Calculations: Standard functions like sum() or mean() will return NaN if one is present. To ignore them, you can use packages like NaNMath.jl or filter them out.