Problem: Image Band Filtering and Weighted Metrics

The problem focuses on processing specific bands of binary file AA by locating the file, reading the 600x600 band with vertical row flip, applying various filters (mean, median, Gaussian), computing weighted statistical metrics (mean, variance, MSE, edge sum), and returning results while handling file not found errors.


Input/Output: The problem accepts integer inputs band_num (specifying the band index in binary file AA) and, for subproblems 15.1, 15.2, 15.4, 15.5, integer kernel_size (filter kernel dimension); for subproblem 15.3, double sigma (Gaussian filter parameter); for subproblem 15.6, only band_num. It locates file AA by checking relative paths: "test_data/AA", "../test_data/AA", "../../test_data/AA". For each subproblem, it reads the specified 600x600 band (with vertical row flipping), applies the required filter (mean for 15.1/15.4/15.5/15.6, median for 15.2, Gaussian for 15.3), computes the corresponding metric (Gaussian-weighted average for 15.1/15.2, variance for 15.3, weighted edge sum multiplied by an enhancement factor for 15.4, weighted mean squared error (MSE) for 15.5, sum of absolute differences between adjacent weighted MSEs for 15.6), and returns a double result. If file AA is not found, it returns -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_15_1 that takes two integers (band_num, kernel_size) as parameters and returns a double. This function loads a specific band from a binary image file, applies a mean filter, then computes a Gaussian-weighted average of the filtered image.  
The function signature is double problem_15_1(int band_num, int kernel_size).  
Algorithm steps: 1. Check three paths ("test_data/AA", "../test_data/AA", "../../test_data/AA") to find the existing binary file. If no file exists, output an error message and return -1.0. 2. Load the specified band: skip (band_num-1)*600*600 bytes from the file, read 600x600 data, and store rows in reverse order (band[rows-1-i][j] = buf[j]). 3. Apply a mean filter of size kernel_size (process pixels within half-kernel distance from edges). 4. Compute Gaussian-weighted average of the filtered image: center at (300.0, 300.0), sigma = max(600,600)/4.0, weight = exp(-dist_sq/(2*sigma*sigma)) where dist_sq is the squared distance from the pixel to the center. Return weighted_sum/weight_sum (return 0.0 if weight_sum is too small to avoid division by zero).  
When loading the file, ensure to skip the bytes of previous bands and reverse the row order. Use the given paths to find the data file.
function_header: double problem_15_1(int band_num, int kernel_size)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.1" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;
    int kernel1 = 3;

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

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

    double result3 = problem_15_1(band3, kernel3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 42.039605;  // 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_15_2 that takes two int parameters (band_num, kernel_size) and returns a double. This function loads a specific band from a binary file, applies median filtering, then computes a Gaussian-weighted mean of the filtered image.
The function signature is double problem_15_2(int band_num, int kernel_size).
Algorithm steps:
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" and return -1.0.
2. Load the specified band (band_num) from the binary file: image size is 600x600; skip (band_num-1)*600*600 bytes from the start; read each row, store rows in reverse order (rows-1-i) into a 2D vector band of unsigned char.
3. Apply median filtering: create a filtered 2D vector; for pixels not in the border (offset by kernel_size/2), collect kernel window pixels, sort them, take the median as filtered pixel.
4. Compute Gaussian-weighted mean: center at (300.0, 300.0), sigma = max(600,600)/4.0; calculate weight for each pixel as exp(-(distance squared from center)/(2*sigma²)); sum weighted pixel values and total weights; return weighted sum divided by total weight if total weight >1e-10, else 0.0.
Functions like sort, exp are already defined. Handle file reading with ifstream, binary mode, seekg, read.
function_header: double problem_15_2(int band_num, int kernel_size)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.2" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;
    int kernel1 = 3;

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

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

    double result3 = problem_15_2(band3, kernel3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 42.040405;  // 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_15_3 that takes an integer band_num and a double sigma as inputs, then returns a double representing the weighted variance of the specified band image after Gaussian filtering.
The function signature is double problem_15_3(int band_num, double sigma);
Algorithm steps: 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 (skip (band_num-1)*600*600 bytes from the file start) into a 600x600 unsigned char 2D vector, flipping it vertically (store row rows-1-i as the i-th row). 3. Convert the unsigned char vector to int type. 4. Generate a Gaussian kernel of size (int)(6*sigma)+1 (make it odd if even), calculate kernel values using exp(-(x²+y²)/(2σ²))/(2πσ²), then normalize by sum. 5. Apply the kernel to the int matrix to get a filtered double matrix (compute only for pixels where i and j are between half and rows-half). 6. Calculate weighted sum and sum of squares using Gaussian weight (sigma_weight = max(600,600)/4.0) based on distance to center (300, 300). 7. Compute mean (weighted_sum/weight_sum) and variance (weighted_sum_sq/weight_sum - mean²), return variance.
Note: Read the file in binary mode; skip the correct bytes for the specified band and flip the rows vertically. Use standard libraries like vector, ifstream, cerr. The kernel application uses the int matrix, and the weight calculation uses the filtered double matrix. Ensure all variables (rows=600, cols=600, pi=3.14159265358979323846) are set as in the流程.</think>Please write a C++ function named problem_15_3 that takes an integer band_num and a double sigma as inputs, then returns a double representing the weighted variance of the specified band image after Gaussian filtering.
The function signature is double problem_15_3(int band_num, double sigma);
Algorithm steps: 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 (skip (band_num-1)*600*600 bytes from the file start) into a 600x600 unsigned char 2D vector, flipping it vertically (store row rows-1-i as the i-th row). 3. Convert the unsigned char vector to int type. 4. Generate a Gaussian kernel of size (int)(6*sigma)+1 (ensured odd), calculate kernel values using exp(-(x²+y²)/(2σ²))/(2πσ²), normalize by sum. 5. Apply the kernel to the int matrix to get a filtered double matrix (process pixels within [half, rows-half] range). 6. Calculate weighted sum and sum of squares using Gaussian weight (sigma_weight = max(600,600)/4.0) based on distance to center (600/2, 600/2). 7. Compute mean and variance from weighted sums, return variance.
Note: Read the file in binary mode; skip correct bytes for the band and flip rows vertically. Use vectors, ifstream, cerr. Variables rows=600, cols=600, pi=3.14159265358979323846 are fixed.
function_header: double problem_15_3(int band_num, double sigma)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.3" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;
    double sigma1 = 1.0;

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

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

    double result3 = problem_15_3(band3, sigma3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 88.779472;  // 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: Please write a C++ function named problem_15_4 that takes two integers (band_num, kernel_size) and returns a double. This function loads a specific band from a binary data file, applies a mean filter, calculates a weighted sum of edge values, and returns an enhanced result.
double problem_15_4(int band_num, int kernel_size);
1. File Path Search: Check paths in {"test_data/AA", "substep/test_data/AA", "../test_data/AA", "../../test_data/AA", "AA"} to find the existing binary file. If no file is found, output "Error: Cannot find data file AA" to cerr and return -1.0.
2. Data Loading: Read the band specified by band_num from the binary file into a 600x600 2D vector of unsigned char (band). Skip (band_num - 1) * 600 * 600 bytes from the start. Flip rows by storing data in band[rows - 1 - i][j] (rows=600, cols=600). Use ifstream with ios::binary, allocate a buf (unsigned char*) of size cols to read each row, then delete buf.
3. Mean Filtering: Compute a kernel_size x kernel_size mean filter on the band. Create a 600x600 filtered vector. For i from half (kernel_size/2) to 599 - half and j from half to 599 - half, calculate the sum of the kernel area (band[i+ki][j+kj] for ki from -half to half, kj from -half to half), set filtered[i][j] to (unsigned char)(sum / (kernel_size * kernel_size)).
4. Weighted Sum Calculation:
   a. Initialize weighted_sum=0.0, weight_sum=0.0, center_i=300.0, center_j=300.0, sigma=max(600,600)/3.5.
   b. Process Top (i=0) and Bottom (i=599) Edges: For each j in 0-599: val1=(filtered[half][j]>0)?filtered[half][j]:band[0][j]; dist_sq1=(0-center_i)^2+(j-center_j)^2; weight1=1.0+0.6*exp(-dist_sq1/(2.0*sigma*sigma)); add val1*weight1 to weighted_sum and weight1 to weight_sum. val2=(filtered[599-half][j]>0)?filtered[599-half][j]:band[599][j]; dist_sq2=(599-center_i)^2+(j-center_j)^2; weight2=1.0+0.6*exp(-dist_sq2/(2.0*sigma*sigma)); add val2*weight2 to weighted_sum and weight2 to weight_sum.
   c. Process Left (j=0) and Right (j=599) Edges: For each i in 1-598: val1=(filtered[i][half]>0)?filtered[i][half]:band[i][0]; dist_sq1=(i-center_i)^2+(0-center_j)^2; weight1=1.0+0.6*exp(-dist_sq1/(2.0*sigma*sigma)); add val1*weight1 to weighted_sum and weight1 to weight_sum. val2=(filtered[i][599-half]>0)?filtered[i][599-half]:band[i][599]; dist_sq2=(i-center_i)^2+(599-center_j)^2; weight2=1.0+0.6*exp(-dist_sq2/(2.0*sigma*sigma)); add val2*weight2 to weighted_sum and weight2 to weight_sum.
5. Result Calculation: Compute base_result=(weight_sum>1e-10)?(weighted_sum/weight_sum):0.0; enhancement=1.0+0.15*(kernel_size/10.0)+0.05*(band_num/10.0); return base_result*enhancement.
Ensure headers like <vector>, <fstream>, <cmath>, <iostream> are included. Assume exp, max are available (from cmath). Use unsigned char for data storage. Handle file operations with ifstream (open, seekg, read, close) and check if files are open.
function_header: double problem_15_4(int band_num, int kernel_size)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.4" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    double correct1 = 87.058005;
    int band1 = 1;
    int kernel1 = 3;
    double result1 = problem_15_4(band1, kernel1);
    if (abs(result1 - correct1) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }

    // Test 2
    double correct2 = 41.517808;
    int band2 = 2;
    int kernel2 = 5;
    double result2 = problem_15_4(band2, kernel2);
    if (abs(result2 - correct2) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
        cout << "Expected: " << correct2 << ", Got: " << result2 << endl;
    }

    // Test 3
    double correct3 = 49.628851;
    int band3 = 3;
    int kernel3 = 7;
    double result3 = problem_15_4(band3, kernel3);
    if (abs(result3 - correct3) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
        cout << "Expected: " << correct3 << ", Got: " << result3 << endl;
    }
    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 5
step_description_prompt: Please write a C++ function named problem_15_5 that calculates the weighted mean squared error (MSE) between an original image band and its mean-filtered version, using Gaussian spatial weighting. The function takes two integers (band_num for the target band index, kernel_size for the mean filter size) as inputs and returns a double.

Function definition: double problem_15_5(int band_num, int kernel_size);

Algorithm flow:
1. Attempt to locate the binary data file "AA" in three paths: "test_data/AA", "../test_data/AA", and "../../test_data/AA". If no file is 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 image has fixed dimensions (600 rows, 600 columns). Skip (band_num - 1) * 600 * 600 bytes from the file start using seekg. Read each row into a buffer, then store rows in reverse order (rows - 1 - i) in a 2D vector of unsigned char (band).
3. Apply an inline mean filter: compute half as kernel_size / 2. For pixels (i,j) where i ranges from half to (600 - half - 1) and j ranges from half to (600 - half - 1), calculate the average of the kernel_size x kernel_size neighborhood in band. Store results in a filtered 2D vector.
4. Calculate weighted MSE with Gaussian spatial weighting: set the center at (600/2.0, 600/2.0) and sigma as max(600, 600)/4.0. For each pixel (i,j), compute weight as exp(-((i - center_i)^2 + (j - center_j)^2) / (2.0 * sigma * sigma)). Sum weighted squared differences between band[i][j] and filtered[i][j], then normalize by total weight (use 1.0 if total weight is too small). Return the final MSE.

Note: Use binary mode to read the file. Assume vector, ifstream, ios, cerr, exp, max are already available.
function_header: double problem_15_5(int band_num, int kernel_size)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.5" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;
    int kernel1 = 3;

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

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

    double result3 = problem_15_5(band3, kernel3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 28.791081;  // 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_15_6 that takes an integer band_num as input and returns a double. The function reads a specific band of 600x600 unsigned char image data from a binary file, applies mean filters of sizes 3x3, 5x5, 7x7, computes weighted Mean Squared Error (MSE) with Gaussian spatial weighting for each filtered result, and returns the sum of absolute differences between consecutive MSE values.

Function definition: double problem_15_6(int band_num);

Algorithm steps:
1. File path search: Check three paths in order ("test_data/AA", "../test_data/AA", "../../test_data/AA") using ifstream in binary mode. Use the first existing path as filepath. If no path exists, output "Error: Cannot find data file AA" to cerr and return -1.0.
2. Image data reading: The image has 600 rows and 600 columns. Calculate skip offset as (band_num - 1) * 600 * 600 bytes. Seek to the skip offset from the start of the file. Read each row (600 bytes) into a buffer, then assign to a 2D vector<unsigned char> band (size 600x600) with row reversal: band[600 - 1 - i][j] = buf[j] for row i (0 ≤ i < 600, 0 ≤ j < 600).
3. Mean filtering:
   - For kernel size 3 (half3 = 1): Initialize filtered3 (600x600, 0s). For pixels from half3 to 600 - half3 - 1 (both rows and columns), compute sum of 3x3 neighborhood, divide by 9.0, cast to unsigned char, assign to filtered3[i][j].
   - Repeat for kernel size 5 (half5 = 2, divide by 25.0) to get filtered5.
   - Repeat for kernel size 7 (half7 = 3, divide by 49.0) to get filtered7.
4. Weighted MSE calculation:
   - Gaussian parameters: center_i = 600 / 2.0, center_j = 600 / 2.0, sigma = max(600, 600) / 4.0.
   - For each filtered matrix (filtered3, filtered5, filtered7):
     - Initialize mse and weight_sum to 0.0.
     - For each pixel (i,j):
       - diff = band[i][j] - filtered[i][j].
       - dist_sq = (i - center_i) * (i - center_i) + (j - center_j) * (j - center_j).
       - weight = exp(-dist_sq / (2.0 * sigma * sigma)).
       - mse += weight * diff * diff.
       - weight_sum += weight.
     - mse /= (weight_sum > 1e-10 ? weight_sum : 1.0) (avoid division by zero).
5. Result: Compute mse_3 (from filtered3), mse_5 (filtered5), mse_7 (filtered7). Return abs(mse_3 - mse_5) + abs(mse_5 - mse_7).

Dependencies: Use C++ standard libraries including vector, fstream, cmath, iostream, and cstddef.
function_header: double problem_15_6(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.6" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;

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

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

    double result3 = problem_15_6(band3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 17.447346;  // 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: 7
step_description_prompt: Please write a C++ function double problem_15_7(int band_num) that calculates the absolute difference between weighted Mean Squared Error (MSE) of mean-filtered and median-filtered results from a specific band of a binary image file. The function takes an integer band_num as input and returns a double value. 

Algorithm steps: 1. Check three paths ("test_data/AA", "../test_data/AA", "../../test_data/AA") to find the binary file "AA". If not found, output "Error: Cannot find data file AA" to stderr and return -1.0. 2. Read the specified band (band_num) from the file: the image has 600 rows and 600 columns. Skip (band_num - 1) * 600 * 600 bytes to locate the target band. For each row read, store it in reverse order (rows-1-i) in the band matrix. 3. Apply a 3x3 mean filter (half = 1) to the band matrix. 4. Calculate weighted MSE for mean-filtered result: use Gaussian weighting with center at (300.0, 300.0), sigma = max(600,600)/4.0. Weight is exp(-dist_sq/(2*sigma²)) where dist_sq is squared distance from pixel to center. Normalize MSE by total weight. 5. Apply a 3x3 median filter (half = 1) to the band matrix. 6. Calculate weighted MSE for median-filtered result using the same Gaussian weighting as step 4. 7. Return the absolute difference between the two weighted MSE values. 

Note: When reading the band data, skip the previous bands and reverse the row order. Ensure the file reading uses binary mode. The sort function for median filter is available.</think>Please write a C++ function double problem_15_7(int band_num) that computes the absolute difference between the weighted Mean Squared Error (MSE) of mean-filtered and median-filtered results from a specific band of a binary image file.

The function takes an integer band_num as input and returns a double.

Algorithm steps:
1. Check three paths ("test_data/AA", "../test_data/AA", "../../test_data/AA") to find the binary file "AA". If not found, output "Error: Cannot find data file AA" to stderr and return -1.0.
2. Read the specified band (band_num) from the file: the image has 600 rows and 600 columns. Skip (band_num - 1) * 600 * 600 bytes to locate the target band. For each row read, store it in reverse order (rows-1-i) in the band matrix.
3. Apply a 3x3 mean filter (half = 1) to the band matrix.
4. Calculate weighted MSE for the mean-filtered result: use Gaussian weighting with center at (300.0, 300.0), sigma = max(600,600)/4.0. Weight is exp(-dist_sq/(2*sigma*sigma)) where dist_sq is the squared distance from the pixel to the center. Normalize MSE by total weight.
5. Apply a 3x3 median filter (half = 1) to the band matrix (sort the window and take the median).
6. Calculate weighted MSE for the median-filtered result using the same Gaussian weighting as step 4.
7. Return the absolute difference between the two weighted MSE values.

Note: When reading the band data, skip previous bands and reverse the row order. Use binary mode for file operations. The sort function is available for median filter.
function_header: double problem_15_7(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.7" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1 = 1;

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

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

    double result3 = problem_15_7(band3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 0.423633;  // 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: 8
step_description_prompt: Please write a C++ code, create a function named problem_15_8 that implements calculating the absolute difference between weighted mean squared errors (MSE) of two specified bands from a data file after applying a mean filter with the given kernel size.

Function definition: double problem_15_8(int band1, int band2, int kernel_size);

Algorithm flow: 1. Check file paths {"test_data/AA", "../test_data/AA", "../../test_data/AA"} to find the first existing binary file AA; if none exist, output error "Error: Cannot find data file AA" and return -1.0. 2. Read 600x600 unsigned char data for band1 and band2 by skipping (band-1)*600*600 bytes from the file start, then store each row in reverse order (rows-1-i). 3. Apply mean filter with kernel_size: compute half = kernel_size/2, for each pixel (i,j) in [half, rows-half) x [half, cols-half), sum kernel neighborhood values and divide by kernel_size² to get filtered value. 4. Calculate weighted MSE for each filtered band using Gaussian weights: center at (rows/2.0, cols/2.0), sigma = max(rows, cols)/4.0, weight = exp(-((i-center_i)² + (j-center_j)²)/(2*sigma²)); sum weight*(original - filtered)² and divide by total weight (avoid zero division). 5. Return absolute difference between the two weighted MSE values.

Note: The file is read in binary mode; rows and cols are fixed to 600.
function_header: double problem_15_8(int band1, int band2, int kernel_size)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.8" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int band1_1 = 1, band2_1 = 2;
    int kernel1 = 3;

    double result1 = problem_15_8(band1_1, band2_1, kernel1);
    if (result1 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct1 = 10.935597;  // Expected value (updated from actual result)
        if (abs(result1 - correct1) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 2
    int band1_2 = 2, band2_2 = 3;
    int kernel2 = 5;

    double result2 = problem_15_8(band1_2, band2_2, kernel2);
    if (result2 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct2 = 11.749558;  // Expected value (updated from actual result)
        if (abs(result2 - correct2) < tolerance) {
            cout << "Correct" << endl;
            correct_count++;
        } else {
            cout << "Wrong" << endl;
        }
    }
// Test 3
    int band1_3 = 3, band2_3 = 4;
    int kernel3 = 7;

    double result3 = problem_15_8(band1_3, band2_3, kernel3);
    if (result3 < 0) {
        cout << "Wrong (File not found)" << endl;
    } else {
        double correct3 = 17.047137;  // 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: 9
step_description_prompt: Please use C++ code to generate a function named problem_15_9 that takes an integer band_num as input and returns a double (representing the optimal odd kernel size between 3-7 for mean filtering, selected by minimized Gaussian-weighted MSE).
The function is defined as double problem_15_9(int band_num).
Algorithm flow:
1. Check paths {"test_data/AA", "../test_data/AA", "../../test_data/AA"} in order to find the valid binary file "AA"; if no valid path is found, output "Error: Cannot find data file AA" to cerr and return -1.0.
2. Read the 600x600 band (specified by band_num) from the binary file: seek to position (band_num-1)*600*600, read each row into a buffer, then store in a 2D vector band with rows flipped (band[rows-1-i][j] = buf[j], rows=600, cols=600).
3. For kernel sizes k=3,5,7 (step 2):
   a. Apply inline mean filtering: compute the average of kxk neighborhood for inner pixels (from half to rows-half, half=k/2) and store in filtered.
   b. Calculate Gaussian-weighted MSE: use center (300,300) and sigma=150, weight=exp(-dist_sq/(2*sigma²)), sum weight*diff², normalize by total weight (avoid division by zero).
4. Track the k with the smallest weighted MSE and return it.
Ensure file reading uses ifstream with ios::binary, handle buffer allocation/deallocation for reading rows, and all used functions (ifstream, exp) are pre-defined.
function_header: double problem_15_9(int band_num)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 15.9" << endl;
    
    int correct_count = 0;
    
    // Test 1
    int correct1 = 3;  // Expected value
    int band1 = 1;
    int result1 = problem_15_9(band1);
    if (result1 == correct1) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }

    // Test 2
    int correct2 = 3;  // Expected value
    int band2 = 2;
    int result2 = problem_15_9(band2);
    if (result2 == correct2) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }

    // Test 3
    int correct3 = 3;  // Expected value
    int band3 = 3;
    int result3 = problem_15_9(band3);
    if (result3 == correct3) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

General solution:

General tests: