Menu

Overwriting mat file variable values

Help
Saif
2018-03-07
2018-03-09
  • Saif

    Saif - 2018-03-07

    Dear all,

    i've just started using this library. I'm working on a problem, where i need to update values of a variable in an existing mat file. I tried the following approach to mke it work, may be anyone knows a better way to do it:

    The approach i took involves the following step:

    1. Open input.mat file
      matoutput = Mat_Open(" input.mat", MAT_ACC_RDWR);

    2. Read input.mat file
      matoutvar1 = Mat_VarReadNextInfo(matoutput);
      matoutvar_val = Mat_VarRead(matoutput, matoutvar1->name);

    3. Store the variables and other attributes of the input.mat file in a temporary variable, e.g., matvar_t * variable_temp

    variable_temp.name = matoutvar_val->name;
    variable_temp.class_type = matoutvar_val->class_type;
    variable_temp.data_type = matoutvar_val->data_type;
    variable_temp.rank = matoutvar_val->rank;
    variable_temp.dims = matoutvar_val->dims;

    1. Close input.mat file
      Mat_Close(matoutput);

    2. Open input.mat file
      matoutput = Mat_Open("input.mat", MAT_ACC_RDWR);

    3. Delete the enteries of input.mat file one by one by using the variable names from the variable_temp
      matoutvar1 = Mat_VarReadNextInfo(matoutput);
      Mat_VarDelete(matoutput, matoutvar1->name)

    4. Close input.mat file, at this point, input.mat contains nothing.
      Mat_Close(matoutput);

    5. Get the new variable values that needed to be assigned to the variable names in variable_temp, e..g,
      double out2[1];
      out2[0] = 5.0;

    6. Open input.mat
      matoutput = Mat_Open("input.mat", MAT_ACC_RDWR);

    7. Using Mat_VarCreate and Mat_VarWrite save new values corresponding to the variable_temp.name
      matvar1 = Mat_VarCreate(variable_temp.name, variable_temp.class_type, variable_temp.data_type, variable_temp.rank, variable_temp.dims, &out2[0], 0);
      Mat_VarWrite(matoutput, matvar1, MAT_COMPRESSION_NONE);
      Mat_VarFree(matvar1);

    8. Close input.mat file
      Mat_Close(matoutput);

    Though, the above method works and gives the expected results, however, is there any other method or function in the matio library where i can directly change the variable values for an existing mat file

    Any help would be highly appreciated.

    PS: I'm not appending new variable or chaning the structure of elements or data types. To be specific, I need to only update the numerical value of a variable
    a = 5 in input.mat file to be given a new value, e.g.,
    a = 10

     
  • tbeu

    tbeu - 2018-03-08

    Indeed, this is far too complicated: This is what I propose:

    1. mat = Mat_Open(fileName, MAT_ACC_RDWR);
    2. matvar = Mat_VarRead(mat, varName);
    3. check matvar->data_type and matvar->class_type if it meets your expectations
    4. cast matvar->data to the type you expect, e.g., double pointer
    5. manipulate matvar->data as you like, but make sure to respect dimensions matvar->dims and to not leak memory
    6. Mat_VarDelete(mat, varName); // delete the old variable from file
    7. Mat_VarWrite(mat, matvar, MAT_COMPRESSION_NONE); // write the manipulated var to file
    8. Mat_VarFree(matvar);
    9. Mat_Close(mat);
     
  • Saif

    Saif - 2018-03-09

    Thank you for your answer, but it's not working for me and can't figure it out where is the problem :(

    int main(int argc, char* argv[]) {
    
        double out2[3];
        out2[0] = 500.0;
        out2[1] = 100.0;
        out2[2] = 100.0;
        mat_t *mat;
        matvar_t *matoutvar1;
        matvar_t *matvar_val;
    
        mat = Mat_Open("output.mat", MAT_ACC_RDWR);
    
        size_t dims[1];
        Mat_GetDir(mat, dims);
        cout << dims[0] << endl;    
        string *variable_temp = new string[dims[0]];
        const char* p_c_str;
        int j = 0;
        // Here I'm reading the variable names in the matoutput file
        // and assinging them to a string array
        while ((matoutvar1 = Mat_VarReadNextInfo(mat)) != NULL) {   
            variable_temp[j] = matoutvar1->name;
            cout << "variable_temp[j]: " << variable_temp[j] << " count j: " << j << endl;      
            j = j + 1;      
        }
        Mat_Close(mat);
    
            // Here I'm overwriting the values of the variable name
    
        for (int i = 0; i < dims[0]; i++) {
            mat = Mat_Open(outputFile.c_str(), MAT_ACC_RDWR);
            p_c_str = variable_temp[i].c_str();
            cout << "p_c_str " << p_c_str << endl;
            // Reads the variable with the given name from a MAT file
            matvar_val = Mat_VarRead(mat, p_c_str);
            cout << "matvar_val->data" << matvar_val->data << endl;
            double *newData = static_cast<double*>(matvar_val->data);
            cout << "matvar_val->data" << newData << endl;
            newData = &out2[i];
    
            Mat_VarDelete(mat, matvar_val->name);
            Mat_VarWrite(mat, matvar_val, MAT_COMPRESSION_NONE);
            Mat_VarFree(matvar_val);
            Mat_Close(mat);
        }
    
        getchar();
    
        return 0;
    }
    
     
  • tbeu

    tbeu - 2018-03-09

    It works if you get the assignment right:

    newData[0] = out2[i];
    

    If you want to assign the data at once, provided dimensions do not change, you need to free the old data and set the mem_conserve flag for the new data:

    free(matvar_val->data);
    matvar_val->data = &out2[i];
    matvar_val->mem_conserve = 1;
    
     

    Last edit: tbeu 2018-03-09
  • tbeu

    tbeu - 2018-03-09

    And, there is no reason to open and close the MAT file repeatedly in the loop. It is enough to open once and close once.

     
  • Saif

    Saif - 2018-03-09

    Thanks for your quick reply. I tried both approaches and i can get the results which i need :)

     

Log in to post a comment.