Problem: Coriolis Distance and Geostrophic Velocity Calculation

The problem aims to develop core functional modules for geostrophic flow velocity calculation and validation, covering Coriolis parameter computation, great-circle distance measurement, velocity solving, abnormal data filtering and result verification, to provide reliable basic calculation support for marine geographic data analysis scenarios.


Input/Output: The problem receives the following input data: 1) double-type single latitude values, 2) four double-type values representing the latitude and longitude of two geospatial points (lat1, lon1, lat2, lon2), 3) std::vector<double> type batch latitude sequence, 4) three double-type values for geostrophic velocity calculation (delta integral, Coriolis parameter, distance), 5) std::vector<std::vector<double>> type 2D velocity array, 6) double-type velocity filtering threshold. The problem first initializes pre-declared global function pointers by executing problem_1_01 and problem_1_02 sequentially. It then generates the following outputs: double-type single Coriolis parameter, double-type great-circle distance between two points, std::vector<double> type batch Coriolis calculation results, double-type geostrophic velocity, std::vector<std::vector<double>> type filtered velocity array, bool-type validation result indicating whether all velocities are within a reasonable range. Each input parameter set maps to the corresponding output returned by the matched function pointer.

Required dependencies:

Sub-steps:
step_number: 1
step_description_prompt: Please use C++ to generate a function named problem_1_01. Implement Coriolis parameter calculation logic, Haversine formula for great-circle distance between two latitude/longitude points, and batch Coriolis calculation function inside it. Assign the three pre-declared global function pointers correctly, use the given global physical constants as required.
function_header: void problem_1_01() 
test_cases: int main() {
    // Initialize by calling problem_1_01 to set function pointers
    problem_1_01();

    std::cout << "========================================\n";
    std::cout << "Problem 1-Subproblem 1: Coriolis Parameter and Distance Calculation\n";
    std::cout << "========================================\n";
    
    bool test1_passed = false, test2_passed = false, test3_passed = false;
    
    
    {
        double f_equator = sw_f_ptr(0.0);
        double f_midlat = sw_f_ptr(30.0);
        double f_highlat = sw_f_ptr(60.0);
        double f_near_pole = sw_f_ptr(89.5);
        
        
        double expected_midlat = 2.0 * OMEGA * sin(30.0 * DEG2RAD);
        double expected_highlat = 2.0 * OMEGA * sin(60.0 * DEG2RAD);
        double expected_near_pole = 2.0 * OMEGA * sin(89.5 * DEG2RAD);
        
        test1_passed = (std::abs(f_equator) < 1e-12 && 
                       std::abs(f_midlat - expected_midlat) < 1e-9 &&
                       std::abs(f_highlat - expected_highlat) < 1e-8 &&
                       std::abs(f_near_pole - expected_near_pole) < 1e-7);
        if (test1_passed) {
            std::cout << "correct\n";
        } else {
            std::cout << "wrong\n";
        }
    }
    
    
    {
        double dist_same = calculate_distance_ptr(30.0, 120.0, 30.0, 120.0);
        double dist_near = calculate_distance_ptr(30.0, 120.0, 30.1, 120.0);
        double dist_far = calculate_distance_ptr(0.0, 0.0, 0.0, 180.0);
        double dist_cross_dateline = calculate_distance_ptr(30.0, 179.9, 30.0, -179.9);
        
        
        double lat_rad = 30.0 * DEG2RAD;
        double dlat_rad = 0.1 * DEG2RAD;
        double a_near = sin(dlat_rad/2) * sin(dlat_rad/2) + cos(lat_rad) * cos(lat_rad) * 0.0;
        double expected_near = EARTH_RADIUS * 2.0 * atan2(sqrt(a_near), sqrt(1.0 - a_near));
        
        double expected_far = EARTH_RADIUS * PI;  
        
        test2_passed = (std::abs(dist_same) < 1e-8 &&
                       std::abs(dist_near - expected_near) < 0.1 &&
                       std::abs(dist_far - expected_far) < 1000.0 &&
                       dist_cross_dateline < 20000.0 && dist_cross_dateline > 19000.0);
        if (test2_passed) {
            std::cout << "correct\n";
        } else {
            std::cout << "wrong\n";
        }
    }
    
    
    {
        std::vector<double> latitudes = {-89.9, -60.0, -30.0, 0.0, 30.0, 60.0, 89.9};
        std::vector<double> coriolis = calculate_coriolis_batch_ptr(latitudes);
        
        
        std::vector<double> expected;
        for (double lat : latitudes) {
            double lat_clamped = lat;
            if (lat_clamped > 89.999) lat_clamped = 89.999;
            if (lat_clamped < -89.999) lat_clamped = -89.999;
            double f = 2.0 * OMEGA * sin(lat_clamped * DEG2RAD);
            if (std::abs(f) < 1e-10) f = 0.0;
            expected.push_back(f);
        }
        
        
        bool symmetry_ok = true;
        for (size_t i = 0; i < latitudes.size() / 2; ++i) {
            size_t j = latitudes.size() - 1 - i;
            if (std::abs(coriolis[i] + coriolis[j]) > 1e-9) {
                symmetry_ok = false;
                break;
            }
        }
        
        
        bool all_match = true;
        for (size_t i = 0; i < coriolis.size(); ++i) {
            double tol = (std::abs(expected[i]) < 1e-10) ? 1e-12 : 1e-9;
            if (std::abs(coriolis[i] - expected[i]) > tol) {
                all_match = false;
                break;
            }
        }
        
        test3_passed = (coriolis.size() == 7 && all_match && symmetry_ok);
        if (test3_passed) {
            std::cout << "correct\n";
        } else {
            std::cout << "wrong\n";
        }
    }
    
    std::cout << "\n========================================\n";
    if (test1_passed && test2_passed && test3_passed) {
        std::cout << "Completely correct!\n";
    }
    std::cout << "========================================\n";
    
    return 0;
}

step_number: 2
step_description_prompt: Please use C++ to generate a function named problem_1_02.
This function implements three internal lambda functions: one for geostrophic velocity calculation with proper boundary value processing, one for filtering out velocities exceeding a given threshold, one for validating all velocities are within reasonable range. Assign these three lambdas to the three pre-declared global function pointers of matching types.
function_header: void problem_1_02() 
test_cases: int main() {
    // Initialize by calling problem_1_02 to set function pointers
    problem_1_02();

    std::cout << "========================================\n";
    std::cout << "Problem 1-Subproblem 2: Geostrophic Flow Velocity Calculation and Result Validation\n";
    std::cout << "========================================\n";
    
    bool test1_passed = false, test2_passed = false, test3_passed = false;
    
    
    {
        double velocity1 = calculate_geostrophic_velocity_ptr(100.0, 1e-4, 100000.0);
        double velocity2 = calculate_geostrophic_velocity_ptr(1e-3, 1e-6, 1000.0);  
        double velocity3 = calculate_geostrophic_velocity_ptr(1e6, 1e-4, 1e5);  
        double velocity_zero = calculate_geostrophic_velocity_ptr(100.0, 0.0, 100000.0);
        
        double expected_velocity1 = 10.0;
        double expected_velocity2 = 1.0;
        double expected_velocity3 = 100000.0;  // 1e6 / (1e-4 * 1e5) = 100000
        
        test1_passed = (std::abs(velocity1 - expected_velocity1) < 1e-12 &&
                       std::abs(velocity2 - expected_velocity2) < 1e-10 &&
                       std::abs(velocity3 - expected_velocity3) < 1e-10 &&
                       std::abs(velocity_zero) < 1e-12);
        if (test1_passed) {
            std::cout << "correct\n";
        } else {
            std::cout << "wrong\n";
        }
    }
    
    
    {
        std::vector<std::vector<double>> velocities = {{2.5, 4.0, 7.0, 6.0, -7.5, -6.0, 6.0000001}};
        double threshold = 6.0;
        auto filtered = filter_abnormal_velocities_ptr(velocities, threshold);
        
        
        bool exact_match = (std::abs(filtered[0][0] - 2.5) < 1e-12 &&
                           std::abs(filtered[0][1] - 4.0) < 1e-12 &&
                           std::abs(filtered[0][2]) < 1e-12 &&
                           std::abs(filtered[0][3] - 6.0) < 1e-12 &&
                           std::abs(filtered[0][4]) < 1e-12 &&
                           std::abs(filtered[0][5] - (-6.0)) < 1e-12 &&
                           std::abs(filtered[0][6]) < 1e-12);
        
        test2_passed = exact_match;
        if (test2_passed) {
            std::cout << "correct\n";
        } else {
            std::cout << "wrong\n";
        }
    }
    
    
    {
        std::vector<std::vector<double>> velocities = {{2.5, 4.0, 5.0}, {3.0, 6.0, 7.5}};
        
        double sum = 0.0;
        size_t count = 0;
        double max_val = velocities[0][0], min_val = velocities[0][0];
        
        for (const auto& row : velocities) {
            for (double v : row) {
                sum += v;
                count++;
                max_val = std::max(max_val, v);
                min_val = std::min(min_val, v);
            }
        }
        
        double mean = sum / count;
        
        
        double variance_sum = 0.0;
        for (const auto& row : velocities) {
            for (double v : row) {
                double diff = v - mean;
                variance_sum += diff * diff;
            }
        }
        double variance = variance_sum / count;
        double std_dev = sqrt(variance);
        
        double expected_mean = 28.0 / 6.0;  
        double expected_variance = ((2.5-expected_mean)*(2.5-expected_mean) +
                                   (4.0-expected_mean)*(4.0-expected_mean) +
                                   (5.0-expected_mean)*(5.0-expected_mean) +
                                   (3.0-expected_mean)*(3.0-expected_mean) +
                                   (6.0-expected_mean)*(6.0-expected_mean) +
                                   (7.5-expected_mean)*(7.5-expected_mean)) / 6.0;
        double expected_std_dev = sqrt(expected_variance);
        
        test3_passed = (std::abs(mean - expected_mean) < 1e-12 && 
                       std::abs(max_val - 7.5) < 1e-12 && 
                       std::abs(min_val - 2.5) < 1e-12 &&
                       std::abs(std_dev - expected_std_dev) < 1e-10);
        if (test3_passed) {
            std::cout << "correct\n";
        } else {
            std::cout << "wrong\n";
        }
    }
    
    std::cout << "\n========================================\n";
    if (test1_passed && test2_passed && test3_passed) {
        std::cout << "Completely correct!\n";
    }
    std::cout << "========================================\n";
    
    return 0;
}

General solution:

General tests: