Problem: Enhanced Single-Point IDW Interpolation

The problem involves implementing enhanced Inverse Distance Weighting (IDW) interpolation for a 2D point, which includes calculating Mahalanobis distances, efficiently selecting nearest neighbors, computing adaptive RBF weights, and returning the weighted sum of known values as the interpolated value.


Input/Output: The problem takes as inputs a 2D query point (x, y) represented by two doubles, a vector of known 2D points (each as a pair of doubles), a vector of known scalar values (doubles) corresponding to the known points, an integer number of neighbors (nNeighbors) to consider, and an optional 2D covariance matrix (vector of vectors of doubles) for Mahalanobis distance calculation. It processes the inputs by first computing squared Mahalanobis distances from the query point to all known points (using the identity matrix if the covariance matrix is invalid or singular), selecting the nNeighbors nearest points via quickselect, calculating an adaptive sigma as the maximum of half the median of nearest distances or 0.1, generating normalized RBF weights based on the distances and sigma, and computing the weighted sum of the known values of the nearest points. The output is a double representing the interpolated value at the query point.

Required dependencies:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <utility>
#include <numeric>
using namespace std;

Sub-steps:
step_number: 1
step_description_prompt: Please write a C++ function named calculateDistanceSquared that computes the squared Mahalanobis distance (or Euclidean distance if the covariance matrix is invalid/empty) from a 2D point (x, y) to each point in a list of known 2D points. The function takes two double values x, y, a const reference to a vector of pairs of doubles (knownPoints), and an optional const reference to a 2D vector of doubles (covMatrix) as the covariance matrix. It returns a vector of doubles containing the squared distances.

Function definition: std::vector<double> calculateDistanceSquared(double x, double y, const std::vector<std::pair<double, double>>& knownPoints, const std::vector<std::vector<double>>& covMatrix = std::vector<std::vector<double>>()).

Algorithm flow: 
1. Use an internal lambda to compute the inverse of the covariance matrix: if covMatrix is not 2x2, empty, or has a determinant with absolute value < 1e-10, return the identity matrix; otherwise calculate the inverse of the 2x2 matrix.
2. For each point in knownPoints:
   a. Calculate dx = x - point.first, dy = y - point.second.
   b. Compute squared distance: distSq = invCov[0][0] * dx*dx + (invCov[0][1] + invCov[1][0]) * dx*dy + invCov[1][1] * dy*dy.
3. Collect all distances in a vector and return it.

Include headers <iostream>, <vector>, <algorithm>, <cmath>, <numeric>. The internal lambda for covariance matrix inversion is part of the function; no external functions are required.
function_header: std::vector<double> calculateDistanceSquared( double x, double y, const std::vector<std::pair<double, double>>& knownPoints, const std::vector<std::vector<double>>& covMatrix = std::vector<std::vector<double>>()
test_cases: int main() {
    // Comparison function
    auto isEqual = [](double a, double b, double tolerance = 1e-6) {
        return std::abs(a - b) <= tolerance;
    };
    
    auto isEqualVec = [&isEqual](const std::vector<double>& a, const std::vector<double>& b, double tolerance = 1e-6) {
        if (a.size() != b.size()) return false;
        for (size_t i = 0; i < a.size(); ++i) {
            if (!isEqual(a[i], b[i], tolerance)) return false;
        }
        return true;
    };
    
    std::cout << "Subproblem 3.1: Calculate distance squared (Mahalanobis)" << std::endl;
    std::cout << "=========================================================" << std::endl << std::endl;
    
    int correctCount = 0;
    
    // Test case 1: Standard Euclidean (identity covariance)
    std::vector<std::pair<double, double>> points1 = {{0, 0}, {1, 1}, {2, 2}};
    std::vector<std::vector<double>> identity = {{1.0, 0.0}, {0.0, 1.0}};
    std::vector<double> result1 = calculateDistanceSquared(0.0, 0.0, points1, identity);
    std::vector<double> expected1 = {0.0, 2.0, 8.0};
    bool passed1 = isEqualVec(result1, expected1, 0.01);
    std::cout << "Test case 1: " << (passed1 ? "correct" : "wrong") << std::endl;
    if (passed1) correctCount++;
    
    // Test case 2: Different covariance
    std::vector<std::pair<double, double>> points2 = {{0, 0}, {50, 50}, {150, 150}};
    std::vector<std::vector<double>> cov2 = {{2.0, 0.0}, {0.0, 2.0}};  // Scaled covariance
    std::vector<double> result2 = calculateDistanceSquared(100.0, 100.0, points2, cov2);
    bool passed2 = (result2.size() == 3) && isEqual(result2[0], 10000.0, 0.01);
    std::cout << "Test case 2: " << (passed2 ? "correct" : "wrong") << std::endl;
    if (passed2) correctCount++;
    
    // Test case 3: Anisotropic covariance
    std::vector<std::pair<double, double>> points3 = {{0, 0}, {100, 0}, {0, 100}, {100, 100}};
    std::vector<std::vector<double>> cov3 = {{1.0, 0.5}, {0.5, 1.0}};  // Correlated covariance
    std::vector<double> result3 = calculateDistanceSquared(50.0, 50.0, points3, cov3);
    bool passed3 = (result3.size() == 4) && result3[0] > 0.0;
    std::cout << "Test case 3: " << (passed3 ? "correct" : "wrong") << std::endl;
    if (passed3) correctCount++;
    
    if (correctCount == 3) {
        std::cout << "Subproblem 3.1: Completely correct!" << std::endl;
    }
    
    return 0;
}



step_number: 2
step_description_prompt: Please write a C++ function named sortDistances that takes a const std::vector<double>& as input and returns a std::pair<std::vector<double>, std::vector<int>> containing sorted distances and their original indices with stable sort and tie-breaking by original index. The function definition is: std::pair<std::vector<double>, std::vector<int>> sortDistances(const std::vector<double>& distances);. Algorithm steps: 1. Create a std::vector<std::pair<double, int>> to store each distance and its original index. 2. Fill the vector by iterating over the input, pairing each distance with its index (cast to int). 3. Use std::stable_sort on the pairs vector with a lambda comparator: first compare distances (consider equal if absolute difference < 1e-10), then compare indices in ascending order if distances are equal. 4. Extract sorted distances and original indices from the sorted pairs into two vectors. 5. Return the pair of these two vectors. Assume all used standard library functions and types are available.
function_header: std::pair<std::vector<double>, std::vector<int>> sortDistances(const std::vector<double>& distances)
test_cases: int main() {
    // Comparison function
    auto isEqual = [](double a, double b, double tolerance = 1e-6) {
        return std::abs(a - b) <= tolerance;
    };
    
    auto isEqualVec = [&isEqual](const std::vector<double>& a, const std::vector<double>& b, double tolerance = 1e-6) {
        if (a.size() != b.size()) return false;
        for (size_t i = 0; i < a.size(); ++i) {
            if (!isEqual(a[i], b[i], tolerance)) return false;
        }
        return true;
    };
    
    std::cout << "Subproblem 3.2: Sort distances and get indices (stable sort)" << std::endl;
    std::cout << "=============================================================" << std::endl << std::endl;
    
    int correctCount = 0;
    
    // Test case 1
    std::vector<double> dists1 = {8.0, 2.0, 0.0};
    auto result1 = sortDistances(dists1);
    std::vector<double> expectedSorted1 = {0.0, 2.0, 8.0};
    std::vector<int> expectedIndices1 = {2, 1, 0};
    bool passed1 = isEqualVec(result1.first, expectedSorted1, 0.01) &&
                   result1.second == expectedIndices1;
    std::cout << "Test case 1: " << (passed1 ? "correct" : "wrong") << std::endl;
    if (passed1) correctCount++;
    
    // Test case 2
    std::vector<double> dists2 = {100.0, 25.0, 4.0, 1.0, 9.0};
    auto result2 = sortDistances(dists2);
    std::vector<double> expectedSorted2 = {1.0, 4.0, 9.0, 25.0, 100.0};
    std::vector<int> expectedIndices2 = {3, 2, 4, 1, 0};
    bool passed2 = isEqualVec(result2.first, expectedSorted2, 0.01) &&
                   result2.second == expectedIndices2;
    std::cout << "Test case 2: " << (passed2 ? "correct" : "wrong") << std::endl;
    if (passed2) correctCount++;
    
    // Test case 3: With equal values
    std::vector<double> dists3 = {64.0, 16.0, 4.0, 1.0, 36.0, 9.0};
    auto result3 = sortDistances(dists3);
    std::vector<double> expectedSorted3 = {1.0, 4.0, 9.0, 16.0, 36.0, 64.0};
    std::vector<int> expectedIndices3 = {3, 2, 5, 1, 4, 0};
    bool passed3 = isEqualVec(result3.first, expectedSorted3, 0.01) &&
                   result3.second == expectedIndices3;
    std::cout << "Test case 3: " << (passed3 ? "correct" : "wrong") << std::endl;
    if (passed3) correctCount++;
    
    if (correctCount == 3) {
        std::cout << "Subproblem 3.2: Completely correct!" << std::endl;
    }
    
    return 0;
}



step_number: 3
step_description_prompt: Please write a C++ function named selectNearestN that takes a const std::vector<double>& distances and an int n as parameters, and returns a std::pair<std::vector<double>, std::vector<int>>. The function selects the n smallest distances from the input vector, then returns two vectors: the first is the sorted list of these n smallest distances in ascending order, and the second is their corresponding original indices from the input vector.

Function definition:
std::pair<std::vector<double>, std::vector<int>> selectNearestN(const std::vector<double>& distances, int n);

Algorithm steps:
1. If the input distances vector is empty or n ≤ 0, return a pair of empty vectors.
2. If n ≥ distances.size(), create a vector of pairs (distance, original index) for all elements, sort the vector by distance in ascending order, then extract all distances and indices into the result vectors and return.
3. Otherwise:
   a. Create a vector of pairs where each pair contains an element from distances and its original index (type int).
   b. Use QuickSelect to ensure the first n elements are the smallest n:
      - Define a helper lambda quickSelectPartition that takes a vector of (double, int) pairs, left/right indices, and a pivotIndex. This lambda swaps the pivot element to the end of the range [left, right], uses a storeIndex (starting at left) to collect elements smaller than the pivot value, iterates from left to right-1 to swap smaller elements to storeIndex (incrementing storeIndex each time), then swaps the pivot back to storeIndex and returns the new pivot index.
      - Initialize left = 0, right = pairs.size() - 1. While left < right:
          - Set pivotIndex to (left + right) / 2.
          - newPivot = quickSelectPartition(pairs, left, right, pivotIndex).
          - Adjust left/right: if newPivot < n, left = newPivot + 1; if newPivot > n, right = newPivot - 1; if equal, break.
   c. Sort the first n elements of the pairs vector by distance in ascending order.
   d. Extract the first n elements from pairs: add their distances to the first result vector and their original indices to the second result vector.
4. Return the pair of result vectors.
function_header: std::pair<std::vector<double>, std::vector<int>> selectNearestN( const std::vector<double>& distances, int n )
test_cases: int main() {
    // Comparison function
    auto isEqual = [](double a, double b, double tolerance = 1e-6) {
        return std::abs(a - b) <= tolerance;
    };
    
    auto isEqualVec = [&isEqual](const std::vector<double>& a, const std::vector<double>& b, double tolerance = 1e-6) {
        if (a.size() != b.size()) return false;
        for (size_t i = 0; i < a.size(); ++i) {
            if (!isEqual(a[i], b[i], tolerance)) return false;
        }
        return true;
    };
    
    std::cout << "Subproblem 3.3: Select nearest N points (QuickSelect)" << std::endl;
    std::cout << "====================================================" << std::endl << std::endl;
    
    int correctCount = 0;
    
    // Test case 1
    std::vector<double> dists1 = {8.0, 2.0, 0.0, 18.0, 32.0};
    auto result1 = selectNearestN(dists1, 3);
    std::vector<double> expectedDist1 = {0.0, 2.0, 8.0};
    std::vector<int> expectedIdx1 = {2, 1, 0};
    bool passed1 = isEqualVec(result1.first, expectedDist1, 0.01) &&
                   result1.second == expectedIdx1;
    std::cout << "Test case 1: " << (passed1 ? "correct" : "wrong") << std::endl;
    if (passed1) correctCount++;
    
    // Test case 2
    std::vector<double> dists2 = {100.0, 25.0, 4.0, 1.0, 9.0};
    auto result2 = selectNearestN(dists2, 5);
    std::vector<double> expectedSorted2 = {1.0, 4.0, 9.0, 25.0, 100.0};
    bool passed2 = (result2.first.size() == 5) &&
                   isEqualVec(result2.first, expectedSorted2, 0.01);
    std::cout << "Test case 2: " << (passed2 ? "correct" : "wrong") << std::endl;
    if (passed2) correctCount++;
    
    // Test case 3
    std::vector<double> dists3 = {64.0, 16.0, 4.0, 1.0, 36.0, 9.0};
    auto result3 = selectNearestN(dists3, 2);
    std::vector<double> expectedDist3 = {1.0, 4.0};
    std::vector<int> expectedIdx3 = {3, 2};
    bool passed3 = isEqualVec(result3.first, expectedDist3, 0.01) &&
                   result3.second == expectedIdx3;
    std::cout << "Test case 3: " << (passed3 ? "correct" : "wrong") << std::endl;
    if (passed3) correctCount++;
    
    if (correctCount == 3) {
        std::cout << "Subproblem 3.3: Completely correct!" << std::endl;
    }
    
    return 0;
}



step_number: 4
step_description_prompt: Write a C++ function named calculateWeights that computes normalized RBF (Radial Basis Function) adaptive weights. It takes a const reference to a std::vector<double> of squared distances and an optional double parameter sigma (default 1.0), and returns a std::vector<double> of weights. The function signature is std::vector<double> calculateWeights(const std::vector<double>& distances, double sigma = 1.0). First, reserve space for the weights vector using reserve() with the size of distances. Then iterate over each squared distance in distances: compute the distance by std::sqrt(distSq). If the distance is less than 1e-10, push 1e10 to weights and add 1e10 to a sum variable; otherwise, compute the RBF weight as std::exp(-(dist * dist) / (sigma * sigma)), push it to weights and add it to the sum. After processing all elements, if sum > 0, normalize each weight in weights by dividing by sum. Return the weights vector. Functions like std::sqrt and std::exp are already defined.
function_header: std::vector<double> calculateWeights(const std::vector<double>& distances, double sigma = 1.0)
test_cases: int main() {
    // Comparison function
    auto isEqual = [](double a, double b, double tolerance = 1e-6) {
        return std::abs(a - b) <= tolerance;
    };
    
    std::cout << "Subproblem 3.4: Calculate weights (RBF)" << std::endl;
    std::cout << "========================================" << std::endl << std::endl;
    
    int correctCount = 0;
    
    // Test case 1: RBF weights
    std::vector<double> dists1 = {1.0, 4.0, 9.0};
    std::vector<double> result1 = calculateWeights(dists1, 2.0);
    bool passed1 = (result1.size() == 3) && 
                   isEqual(result1[0] + result1[1] + result1[2], 1.0, 0.001) &&
                   result1[0] > result1[1] && result1[1] > result1[2];
    std::cout << "Test case 1: " << (passed1 ? "correct" : "wrong") << std::endl;
    if (passed1) correctCount++;
    
    // Test case 2: Different sigma
    std::vector<double> dists2 = {0.25, 1.0, 4.0};
    std::vector<double> result2 = calculateWeights(dists2, 1.0);
    bool passed2 = (result2.size() == 3) && 
                   isEqual(result2[0] + result2[1] + result2[2], 1.0, 0.001);
    std::cout << "Test case 2: " << (passed2 ? "correct" : "wrong") << std::endl;
    if (passed2) correctCount++;
    
    // Test case 3: Small distances
    std::vector<double> dists3 = {16.0, 4.0, 1.0};
    std::vector<double> result3 = calculateWeights(dists3, 3.0);
    bool passed3 = (result3.size() == 3) && 
                   isEqual(result3[0] + result3[1] + result3[2], 1.0, 0.001);
    std::cout << "Test case 3: " << (passed3 ? "correct" : "wrong") << std::endl;
    if (passed3) correctCount++;
    
    if (correctCount == 3) {
        std::cout << "Subproblem 3.4: Completely correct!" << std::endl;
    }
    
    return 0;
}



step_number: 5
step_description_prompt: Please write a C++ function named idwInterpolation that implements single-point IDW interpolation with an adaptive power parameter (enhanced using Mahalanobis distance and adaptive sigma). The function definition is: double idwInterpolation(double x, double y, const std::vector<std::pair<double, double>>& knownPoints, const std::vector<double>& knownValues, int nNeighbors, const std::vector<std::vector<double>>& covMatrix = std::vector<std::vector<double>>()).  

Algorithm flow:  
1. Calculate squared Mahalanobis distances between (x,y) and all knownPoints using covMatrix—if covMatrix is invalid (not 2x2 or singular), use identity matrix for inverse covariance.  
2. Select nNeighbors nearest points based on distances (use quickselect for efficiency when nNeighbors < total points; sort all if nNeighbors ≥ total points).  
3. Compute adaptive sigma: take the median of the square roots of nearest distances, set sigma to max(medianDist * 0.5, 0.1).  
4. Compute RBF weights: weight = exp(-(distance²)/(sigma²)), normalize by sum (assign 1e10 to zero-distance weights).  
5. Return weighted sum of knownValues from nearest points using the weights.  

Helper functions (inverseCov, calculateDistanceSquared, quickSelectPartition, selectNearestN, calculateWeights) are pre-defined and do not need reimplementation.
function_header: double idwInterpolation( double x, double y, const std::vector<std::pair<double, double>>& knownPoints, const std::vector<double>& knownValues, int nNeighbors, const std::vector<std::vector<double>>& covMatrix = std::vector<std::vector<double>>()
test_cases: int main() {
    // Comparison function
    auto isEqual = [](double a, double b, double tolerance = 1e-6) {
        return std::abs(a - b) <= tolerance;
    };
    
    std::cout << "Subproblem 3.5: Single point IDW interpolation (Enhanced)" << std::endl;
    std::cout << "==========================================================" << std::endl << std::endl;
    
    int correctCount = 0;
    
    // Test case 1
    std::vector<std::pair<double, double>> points1 = {{0, 0}, {50, 50}, {150, 150}};
    std::vector<double> values1 = {10.0, 20.0, 30.0};
    double result1 = idwInterpolation(100.0, 100.0, points1, values1, 3);
    // Actual value: 25.0 (using RBF weights with adaptive sigma)
    bool passed1 = isEqual(result1, 25.0, 0.1);
    std::cout << "Test case 1: " << (passed1 ? "correct" : "wrong") << std::endl;
    if (passed1) correctCount++;
    
    // Test case 2
    std::vector<std::pair<double, double>> points2 = {{0, 0}, {1, 1}, {2, 2}};
    std::vector<double> values2 = {5.0, 10.0, 15.0};
    double result2 = idwInterpolation(0.0, 0.0, points2, values2, 2);
    bool passed2 = isEqual(result2, 5.0, 0.01);
    std::cout << "Test case 2: " << (passed2 ? "correct" : "wrong") << std::endl;
    if (passed2) correctCount++;
    
    // Test case 3
    std::vector<std::pair<double, double>> points3 = {{0, 0}, {100, 0}, {0, 100}, {100, 100}};
    std::vector<double> values3 = {1.0, 2.0, 3.0, 4.0};
    double result3 = idwInterpolation(50.0, 50.0, points3, values3, 4);
    bool passed3 = isEqual(result3, 2.5, 0.1);
    std::cout << "Test case 3: " << (passed3 ? "correct" : "wrong") << std::endl;
    if (passed3) correctCount++;
    
    if (correctCount == 3) {
        std::cout << "Subproblem 3.5: Completely correct!" << std::endl;
    }
    
    return 0;
}



step_number: 6
step_description_prompt: Please write a C++ function named idwRasterInterpolation that performs multi-scale IDW raster interpolation based on given parameters, returning a 2D vector of interpolated values. The function has the following definition: std::vector<std::vector<double>> idwRasterInterpolation(double xmin, double ymin, double xmax, double ymax, double xResolution, double yResolution, const std::vector<std::pair<double, double>>& knownPoints, const std::vector<double>& knownValues, int nNeighbors, const std::vector<std::vector<double>>& covMatrix = std::vector<std::vector<double>>()). Algorithm flow: 1. Compute nCols = static_cast<int>((xmax - xmin)/xResolution) + 1 and nRows = static_cast<int>((ymax - ymin)/yResolution) + 1. 2. Initialize a 2D vector raster with nRows rows and nCols columns. 3. For each row i from 0 to nRows-1: a. For each column j from 0 to nCols-1: i. Compute x = xmin + j * xResolution, y = ymax - i * yResolution. ii. Calculate squared Mahalanobis distances from (x,y) to all knownPoints using the inverse of covMatrix (handled by helper functions). iii. Select the nNeighbors nearest points via a quickselect-based method. iv. Compute sigma as max(0.5 * median of nearest points' distances, 0.1). v. Calculate normalized weights using a Gaussian kernel (exp(-dist²/sigma²)) where dist is sqrt of squared distance. vi. Compute interpolated value as weighted sum of knownValues for nearest points. 4. Return the raster. Helper functions inverseCov, calculateDistanceSquared, quickSelectPartition, selectNearestN, calculateWeights, idwInterpolation are already defined and can be used directly.
function_header: std::vector<std::vector<double>> idwRasterInterpolation( double xmin, double ymin, double xmax, double ymax, double xResolution, double yResolution, const std::vector<std::pair<double, double>>& knownPoints, const std::vector<double>& knownValues, int nNeighbors, const std::vector<std::vector<double>>& covMatrix = std::vector<std::vector<double>>()
test_cases: int main() {
    // Comparison function
    auto isEqual = [](double a, double b, double tolerance = 1e-6) {
        return std::abs(a - b) <= tolerance;
    };
    
    std::cout << "Subproblem 3.6: Raster IDW interpolation" << std::endl;
    std::cout << "==========================================" << std::endl << std::endl;
    
    int correctCount = 0;
    
    // Test case 1: Small raster with 3 known points
    std::vector<std::vector<double>> result1 = idwRasterInterpolation(
        0.0, 0.0, 100.0, 100.0, 10.0, 10.0,
        {{10, 10}, {50, 50}, {90, 90}},
        {10.0, 20.0, 30.0}, 3
    );
    bool passed1 = (result1.size() == 11) && (result1[0].size() == 11) &&
                   isEqual(result1[5][5], 20.0, 1.0) &&  // Center point should be close to known value 20.0
                   result1[9][1] >= 8.0 && result1[9][1] <= 12.0 &&  // Near (10,10) known point
                   result1[1][9] >= 28.0 && result1[1][9] <= 32.0;   // Near (90,90) known point
    std::cout << "Test case 1: " << (passed1 ? "correct" : "wrong") << std::endl;
    if (passed1) correctCount++;
    
    // Test case 2: Medium raster with 4 corner points
    std::vector<std::vector<double>> result2 = idwRasterInterpolation(
        0.0, 0.0, 200.0, 200.0, 50.0, 50.0,
        {{0, 0}, {100, 0}, {0, 100}, {100, 100}},
        {1.0, 2.0, 3.0, 4.0}, 4
    );
    bool passed2 = (result2.size() == 5) && (result2[0].size() == 5) &&
                   result2[4][0] >= 0.5 && result2[4][0] <= 1.5 &&  // Near (0,0) known point
                   result2[4][2] >= 1.5 && result2[4][2] <= 2.5 &&  // Near (100,0) known point
                   result2[2][0] >= 2.5 && result2[2][0] <= 3.5 &&  // Near (0,100) known point
                   result2[2][2] >= 3.5 && result2[2][2] <= 4.5;    // Near (100,100) known point
    std::cout << "Test case 2: " << (passed2 ? "correct" : "wrong") << std::endl;
    if (passed2) correctCount++;
    
    // Test case 3: Large raster with 5 known points  
    std::vector<std::vector<double>> result3 = idwRasterInterpolation(
        0.0, 0.0, 500.0, 500.0, 100.0, 100.0,
        {{50, 50}, {150, 150}, {250, 250}, {350, 350}, {450, 450}},
        {10.0, 20.0, 30.0, 40.0, 50.0}, 5
    );
    bool passed3 = (result3.size() == 6) && (result3[0].size() == 6) &&
                   result3[4][0] >= 5.0 && result3[4][0] <= 15.0 &&   // Should be influenced by (50,50) with value 10.0
                   result3[3][1] >= 15.0 && result3[3][1] <= 25.0 &&  // Should be influenced by (150,150) with value 20.0
                   result3[2][2] >= 25.0 && result3[2][2] <= 35.0 &&  // Should be influenced by (250,250) with value 30.0
                   result3[1][3] >= 35.0 && result3[1][3] <= 45.0 &&  // Should be influenced by (350,350) with value 40.0
                   result3[0][4] >= 45.0 && result3[0][4] <= 55.0;    // Should be influenced by (450,450) with value 50.0
    std::cout << "Test case 3: " << (passed3 ? "correct" : "wrong") << std::endl;
    if (passed3) correctCount++;
    
    if (correctCount == 3) {
        std::cout << "Subproblem 3.6: Completely correct!" << std::endl;
    }
    
    return 0;
}

General solution:

General tests: