Problem: Binary Image Band Gaussian-Weighted Statistics

The problem involves locating a binary file, reading a specified 600x600 band (with vertical flipping), applying Gaussian spatial weighting to compute statistical metrics (mean, variance, entropy, skewness, kurtosis), and deriving a normalized score to evaluate the band's properties.


Input/Output: The problem takes an integer input band_num specifying the target band index and requires locating a binary file named "AA" in three relative paths: "test_data/AA", "../test_data/AA", and "../../test_data/AA". For each subproblem (11.1–11.6), it reads the specified 600x600 band (reversing row order vertically), computes Gaussian-weighted metrics (with center at the image midpoint and sigma = max(rows, cols)/4), and returns a double. Specifically, 11.1 returns the weighted mean, 11.2 returns the weighted variance, 11.3 returns the weighted entropy, 11.4 returns the weighted skewness, 11.5 returns the weighted kurtosis minus 3, and 11.6 returns a normalized score combining these metrics with predefined weights. If the file is not found, all subproblems return -1.0.

Required dependencies:
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
using namespace std;

Sub-steps:
step_number: 1
step_description_prompt: Please write a C++ function named problem_11_1 that takes an int parameter band_num and returns a double. This function computes the Gaussian-weighted mean of a specified band from a binary file named "AA". The function definition is double problem_11_1(int band_num);.Algorithm steps:1. Check the paths {"test_data/AA", "../test_data/AA", "../../test_data/AA"} to find the binary file "AA". If no path is valid, output "Error: Cannot find data file AA" to cerr and return -1.0.2. Read the band_num-th band from the file. The band is 600 rows by 600 columns of unsigned char. Skip (band_num - 1) * 600 * 600 bytes using seekg in binary mode. Read each row into a dynamically allocated unsigned char buffer of size 600, then store the row in the 2D vector band at index (rows - 1 - i) where i is the current row index.3. Calculate the Gaussian-weighted mean: the center is at (rows / 2.0, cols / 2.0) (rows = 600, cols = 600), sigma is max(rows, cols) / 4.0. For each pixel (i, j) in band, compute weight as exp(-((i - center_i) * (i - center_i) + (j - center_j) * (j - center_j)) / (2.0 * sigma * sigma)). Accumulate the sum of band[i][j] * weight and the total weight. Return sum / weight_sum if weight_sum > 1e-10, otherwise return 0.0.Include the headers <bits/stdc++.h>, <cmath>, <iomanip>, <numeric>, <random>, <fstream>, <complex>, <algorithm> and use namespace std;. Assume all called functions are pre-defined. Handle file operations in binary mode, use seekg to skip bytes, read rows into a dynamically allocated buffer, and reverse the row order when storing data into the band vector.
function_header: double problem_11_1(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 11.1" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;

    double result1 = problem_11_1(band1);
    if (result1 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct1 = 81.600296;  // Expected value (updated from actual result)
        if (abs(result1 - correct1) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 2
    int band2 = 3;

    double result2 = problem_11_1(band2);
    if (result2 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct2 = 42.733612;  // Expected value (updated from actual result)
        if (abs(result2 - correct2) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 3
    int band3 = 5;

    double result3 = problem_11_1(band3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 56.514335;  // Expected value (updated from actual result)
        if (abs(result3 - correct3) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }

    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 2
step_description_prompt: Please write a C++ function named problem_11_2 that takes an int parameter band_num and returns a double. The function calculates the Gaussian-weighted variance of a specified band from a binary file named AA.

Function definition: double problem_11_2(int band_num);

Algorithm flow:
1. Check three paths ("test_data/AA", "../test_data/AA", "../../test_data/AA") to find the valid file path for AA. If no file is found, output "Error: Cannot find data file AA" to cerr and return -1.0.
2. Read a 600x600 band from the binary file: skip (band_num - 1) * 600 * 600 bytes, read each row into a buffer, then store data in a 2D vector<vector<unsigned char>> band with rows reversed (rows-1 - i).
3. Compute Gaussian weights for each pixel using center (rows/2.0, cols/2.0) and sigma = max(rows, cols)/4.0. Weight is exp(-( (i - center_i)*(i - center_i) + (j - center_j)*(j - center_j) ) / (2.0 * sigma * sigma)).
4. Calculate weighted mean as weighted_sum / weight_sum (0 if weight_sum < 1e-10), then calculate weighted variance as sum of weight * (band[i][j] - mean)^2 divided by (weight_sum if weight_sum > 1e-10 else 1.0).
5. Return the variance.

Use ios::binary and ios::beg for file operations. Assume necessary headers (vector, fstream, cmath, iostream) and functions (exp, max) are available.
function_header: double problem_11_2(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 11.2" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;

    double result1 = problem_11_2(band1);
    if (result1 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct1 = 44.370669;  // Expected value (updated from actual result)
        if (abs(result1 - correct1) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 2
    int band2 = 3;

    double result2 = problem_11_2(band2);
    if (result2 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct2 = 94.112739;  // Expected value (updated from actual result)
        if (abs(result2 - correct2) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 3
    int band3 = 5;

    double result3 = problem_11_2(band3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 467.307074;  // Expected value (updated from actual result)
        if (abs(result3 - correct3) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }

    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 3
step_description_prompt: Please write a C++ function named problem_11_3 that takes an int band_num and returns a double. This function computes the spatially weighted entropy of a specified band from the binary file "AA".

Function definition: double problem_11_3(int band_num);

Algorithm flow:
1. Search for the binary file "AA" in paths "test_data/AA", "../test_data/AA", "../../test_data/AA" using ifstream. If not found, output "Error: Cannot find data file AA" to cerr and return -1.0.
2. Define rows = 600, cols = 600. Create a 2D vector<vector<unsigned char>> band(rows, vector<unsigned char>(cols, 0)).
3. Open the found file in binary mode, skip (band_num - 1) * rows * cols bytes from the start. For each row i (0 to rows-1), read cols bytes into an unsigned char buffer, then assign buffer[j] to band[rows - 1 - i][j].
4. Calculate spatially weighted histogram: center at (rows/2.0, cols/2.0), sigma = max(rows, cols)/4.0. For each (i,j):
   a. Get v = band[i][j].
   b. Compute dist_sq = (i - center_i)*(i - center_i) + (j - center_j)*(j - center_j).
   c. Compute weight = exp(-dist_sq / (2.0 * sigma * sigma)).
   d. Add (int)(weight * 100 + 0.5) to histogram[v], accumulate weight * 100 into total_weight.
5. Compute entropy: for each non-zero count in histogram, calculate prob = (double)count / total_weight, then entropy -= prob * log2(prob + 1e-10) (use 1e-10 for stability).
6. Return entropy.

Use vector, ifstream (with ios::binary, ios::beg), cerr. Allocate buffer with new unsigned char[cols] and delete after use. Use exp and log2 from <cmath>.
function_header: double problem_11_3(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 11.3" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;

    double result1 = problem_11_3(band1);
    if (result1 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct1 = 4.731815;  // Expected value (updated from actual result)
        if (abs(result1 - correct1) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 2
    int band2 = 3;

    double result2 = problem_11_3(band2);
    if (result2 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct2 = 5.208719;  // Expected value (updated from actual result)
        if (abs(result2 - correct2) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 3
    int band3 = 5;

    double result3 = problem_11_3(band3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 6.148536;  // Expected value (updated from actual result)
        if (abs(result3 - correct3) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }

    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 4
step_description_prompt: Write a C++ function named problem_11_4 that takes an int parameter band_num and returns a double. This function calculates the skewness of a specified band from a binary file using Gaussian spatial weighting.

Function definition: double problem_11_4(int band_num);

Algorithm flow: 1. Check three paths ("test_data/AA", "../test_data/AA", "../../test_data/AA") to find the existing binary file. If no file exists, output "Error: Cannot find data file AA" to cerr and return -1.0. 2. Initialize a 600x600 vector of unsigned char for the band. 3. Open the file in binary mode, skip (band_num - 1) * 600 * 600 bytes from the start, read each row (600 bytes) into an unsigned char buffer, and store with rows flipped (band[600 - 1 - i][j] = buf[j]). 4. Calculate Gaussian weights for each pixel: center at (300.0, 300.0), sigma = 150.0, weight = exp(-((i - 300.0)*(i - 300.0) + (j - 300.0)*(j - 300.0)) / (2.0 * 150.0 * 150.0)). 5. Compute weighted mean as sum(v * weight) / sum(weight). 6. Compute weighted variance as sum(weight * (v - mean) * (v - mean)) / sum(weight). 7. Compute standard deviation as sqrt(variance). If std_dev < 1e-10, return 0.0. 8. Compute skewness as sum(weight * ((v - mean)/std_dev) * ((v - mean)/std_dev) * ((v - mean)/std_dev)) / sum(weight) and return it.
function_header: double problem_11_4(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 11.4" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;

    double result1 = problem_11_4(band1);
    if (result1 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct1 = 0.550993;  // Expected value (updated from actual result)
        if (abs(result1 - correct1) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 2
    int band2 = 3;

    double result2 = problem_11_4(band2);
    if (result2 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct2 = 0.570284;  // Expected value (updated from actual result)
        if (abs(result2 - correct2) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 3
    int band3 = 5;

    double result3 = problem_11_4(band3);
    if (result3 < -1) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = -0.362871;  // Expected value (updated from actual result)
        if (abs(result3 - correct3) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }

    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 5
step_description_prompt: Please write a C++ function named problem_11_5 that takes an integer band_num as input and returns a double. This function calculates the excess kurtosis of a specified band from a binary data file using Gaussian spatial weighting.
The function signature is double problem_11_5(int band_num);
Algorithm flow: 1. Check three paths ("test_data/AA", "../test_data/AA", "../../test_data/AA") to find the existing binary file. If no file exists, output "Error: Cannot find data file AA" to stderr and return -1.0. 2. Initialize a 600x600 vector<vector<unsigned char>> band filled with 0. 3. Open the found file in binary mode. Skip (band_num - 1) * 600 * 600 bytes from the start. Read each row (600 bytes) into a buffer, then store the data in reverse row order (rows-1-i) into the band vector. 4. Compute Gaussian weights for each pixel: center at (rows/2.0, cols/2.0), sigma = max(rows, cols)/4.0. Calculate weighted_sum (sum of v*weight) and weight_sum (sum of weight) to get the weighted mean (weighted_sum/weight_sum if weight_sum > 1e-10, else 0). 5. Compute weighted variance by summing weight*(v-mean)^2, divide by weight_sum. Compute std_dev as sqrt(variance). If std_dev < 1e-10, return 0.0. 6. Compute excess kurtosis by summing weight*((v-mean)/std_dev)^4 / weight_sum - 3.0, then return it.
Note: Use ifstream with ios::binary to read the file. The band vector has 600 rows and 600 columns. Reverse row order when storing data into band. Existing functions (exp, sqrt, max) are assumed to be defined. If the file is not found, output the error message to stderr.
function_header: double problem_11_5(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 11.5" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;

    double result1 = problem_11_5(band1);
    if (result1 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct1 = 4.279798;  // Expected value (updated from actual result)
        if (abs(result1 - correct1) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 2
    int band2 = 3;

    double result2 = problem_11_5(band2);
    if (result2 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct2 = 0.488110;  // Expected value (updated from actual result)
        if (abs(result2 - correct2) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 3
    int band3 = 5;

    double result3 = problem_11_5(band3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 0.687347;  // Expected value (updated from actual result)
        if (abs(result3 - correct3) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }

    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 6
step_description_prompt: Please write a C++ function named problem_11_6 that takes an int parameter band_num and returns a double. This function calculates a weighted score based on statistical features of a specific band from a binary file.

Function definition: double problem_11_6(int band_num);

Algorithm flow:
1. Search for the binary file "AA" in paths {"test_data/AA", "../test_data/AA", "../../test_data/AA"}. If not found, output "Error: Cannot find data file AA" to cerr and return -1.0.
2. Read the specified band (band_num) from the file: The data has 600 rows and 600 cols. Skip (band_num - 1) * 600 * 600 bytes from the start. Read each row, then store it in reverse row order (using rows - 1 - i as the row index).
3. Calculate Gaussian weights for each pixel: Center at (rows/2.0, cols/2.0), sigma = max(rows, cols) / 4.0, weight = exp(-dist_sq/(2*sigma*sigma)) where dist_sq is (i - center_i)^2 + (j - center_j)^2.
4. Compute weighted mean: Sum (band[i][j] * weight) divided by sum(weight) (avoid division by zero).
5. Compute weighted variance: Sum (weight * (band[i][j] - mean)^2) divided by sum(weight) (avoid division by zero).
6. Compute weighted entropy: Build a 256-bin histogram by adding (int)(weight * 100 + 0.5) to the corresponding bin. Calculate total_weight as sum(weight * 100). For bins with count > 0, compute prob = count / total_weight, then entropy -= prob * log2(prob + 1e-10).
7. Compute weighted skewness: If std_dev (sqrt(variance)) >= 1e-10, sum (weight * ((band[i][j] - mean)/std_dev)^3) divided by sum(weight) (avoid division by zero).
8. Compute weighted kurtosis: If std_dev >= 1e-10, sum (weight * ((band[i][j] - mean)/std_dev)^4) divided by sum(weight) minus 3.0 (avoid division by zero).
9. Normalize features: mean/255.0, std_dev/73.0, entropy/8.0, abs(skewness)/2.0, abs(kurtosis)/5.0. Calculate score using weights 0.2, 0.2, 0.3, 0.15, 0.15 respectively.
10. Return the score.

Note: Use ios::binary mode for file operations. Use vector<vector<unsigned char>> for band storage. Handle file open checks.
function_header: double problem_11_6(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 11.6" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;

    double result1 = problem_11_6(band1);
    if (result1 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct1 = 0.429411;  // Expected value (updated from actual result)
        if (abs(result1 - correct1) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 2
    int band2 = 3;

    double result2 = problem_11_6(band2);
    if (result2 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct2 = 0.312837;  // Expected value (updated from actual result)
        if (abs(result2 - correct2) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 3
    int band3 = 5;

    double result3 = problem_11_6(band3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 0.381956;  // Expected value (updated from actual result)
        if (abs(result3 - correct3) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }

    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

General solution:

General tests: