// Path: src/main/java/org/esa/s3tbx/ArrayMath.java
// public static double[] a_abs(double[] x, double[] y) {
//     Assert.argument(x.length == y.length);
//     double[] z = new double[x.length];
//     for (int i = 0; i < x.length; i++) {
//         z[i] = abs(x[i] - y[i]);
//     }
//     return z;
// }
// 
// Path: src/main/java/org/esa/s3tbx/ArrayMath.java
// public static double[] a_exp(double[] x) {
//     return DoubleStream.of(x).map(Math::exp).toArray();
// }
// 
// Path: src/main/java/org/esa/s3tbx/ArrayMath.java
// public static double a_max(double[] x) {
//     double max = Double.NEGATIVE_INFINITY;
//     for (double v : x) {
//         max = Math.max(max, v);
//     }
//     return max;
// }


import org.esa.snap.core.nn.NNffbpAlphaTabFast;
import org.esa.snap.core.util.BitSetter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import static java.lang.Math.abs;
import static java.lang.Math.acos;
import static java.lang.Math.cos;
import static java.lang.Math.exp;
import static java.lang.Math.log;
import static java.lang.Math.max;
import static java.lang.Math.pow;
import static java.lang.Math.sin;
import static java.lang.Math.toDegrees;
import static java.lang.Math.toRadians;
import static org.esa.s3tbx.ArrayMath.a_abs;
import static org.esa.s3tbx.ArrayMath.a_exp;
import static org.esa.s3tbx.ArrayMath.a_max;
                rpath_nn = a_exp(log_rpath_nn);
            }

            // (9.4.5) NN compute transmittance from rtosa
            transd_nn = new double[0];
            transu_nn = new double[0];
            double[] trans_nn = nn_rtosa_trans.get().calc(nn_in);
            // cloud flag test @865
            flags = BitSetter.setFlag(flags, FLAG_INDEX_CLOUD, trans_nn[7] < thresh_cloudTransD);
            if (outputTdown || deriveRwFromPathAndTransmittance) {
                transd_nn = Arrays.copyOfRange(trans_nn, 0, r_tosa_ur.length);
            }
            if (outputTup || deriveRwFromPathAndTransmittance) {
                transu_nn = Arrays.copyOfRange(trans_nn, r_tosa_ur.length, trans_nn.length);
            }

            // (9.4.6)
            double[] log_rw;
            if(deriveRwFromPathAndTransmittance) {
                // needs outputRpath & outputTdown & outputTup
                log_rw = new double[r_tosa.length];
                for (int i = 0; i < r_tosa.length; i++) {
                    log_rw[i] = r_tosa[i] - rpath_nn[i] / (transu_nn[i] * transd_nn[i]);
                }
            }else {
                log_rw = nn_rtosa_rw.get().calc(nn_in);
            }

            rwa = new double[0];
            if (outputRwa) {
// Path: src/main/java/org/esa/s3tbx/ArrayMath.java
// public static double[] a_abs(double[] x, double[] y) {
//     Assert.argument(x.length == y.length);
//     double[] z = new double[x.length];
//     for (int i = 0; i < x.length; i++) {
//         z[i] = abs(x[i] - y[i]);
//     }
//     return z;
// }
// 
// Path: src/main/java/org/esa/s3tbx/ArrayMath.java
// public static double[] a_exp(double[] x) {
//     return DoubleStream.of(x).map(Math::exp).toArray();
// }
// 
// Path: src/main/java/org/esa/s3tbx/ArrayMath.java
// public static double a_max(double[] x) {
//     double max = Double.NEGATIVE_INFINITY;
//     for (double v : x) {
//         max = Math.max(max, v);
//     }
//     return max;
// }


// Path: src/main/java/org/esa/s3tbx/c2rcc/landsat8/C2rccLandsat8Algorithm.java
import org.esa.snap.core.nn.NNffbpAlphaTabFast;
import org.esa.snap.core.util.BitSetter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import static java.lang.Math.abs;
import static java.lang.Math.acos;
import static java.lang.Math.cos;
import static java.lang.Math.exp;
import static java.lang.Math.log;
import static java.lang.Math.max;
import static java.lang.Math.pow;
import static java.lang.Math.sin;
import static java.lang.Math.toDegrees;
import static java.lang.Math.toRadians;
import static org.esa.s3tbx.ArrayMath.a_abs;
import static org.esa.s3tbx.ArrayMath.a_exp;
import static org.esa.s3tbx.ArrayMath.a_max;

                rpath_nn = a_exp(log_rpath_nn);
            }

            // (9.4.5) NN compute transmittance from rtosa
            transd_nn = new double[0];
            transu_nn = new double[0];
            double[] trans_nn = nn_rtosa_trans.get().calc(nn_in);
            // cloud flag test @865
            flags = BitSetter.setFlag(flags, FLAG_INDEX_CLOUD, trans_nn[7] < thresh_cloudTransD);
            if (outputTdown || deriveRwFromPathAndTransmittance) {
                transd_nn = Arrays.copyOfRange(trans_nn, 0, r_tosa_ur.length);
            }
            if (outputTup || deriveRwFromPathAndTransmittance) {
                transu_nn = Arrays.copyOfRange(trans_nn, r_tosa_ur.length, trans_nn.length);
            }

            // (9.4.6)
            double[] log_rw;
            if(deriveRwFromPathAndTransmittance) {
                // needs outputRpath & outputTdown & outputTup
                log_rw = new double[r_tosa.length];
                for (int i = 0; i < r_tosa.length; i++) {
                    log_rw[i] = r_tosa[i] - rpath_nn[i] / (transu_nn[i] * transd_nn[i]);
                }
            }else {
                log_rw = nn_rtosa_rw.get().calc(nn_in);
            }

            rwa = new double[0];
            if (outputRwa) {
                rwa = a_exp(log_rw);