kedarps
kedarps

Reputation: 861

Clear MATLAB command window from mex function

I have a for loop in a mexFunction, which displays some information at every iteration. Consider this simple code, which will print 100 lines in the MATLAB command window and update at every iteration:

#include "mex.h"
#include <iostream>
#include <sstream>
#include <stdio.h>      
#include <stdlib.h>     
#include <time.h>       

using namespace std;

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
    int nrhs, const mxArray *prhs[])
{
    int numiters = 100;
    /* initialize random seed: */
    srand(time(NULL));

    for (int iter = 1; iter <= numiters; ++iter)
    {
        int rand_num = rand() % 100 + 1;

        /* Print info in matlab */
        std::ostringstream buffer;
        buffer << "iter = " << iter << " of " << numiters << 
            ". random number = " << rand_num << endl;

        /* need something similar to clc here */
        mexPrintf("%s", buffer.str().c_str());
    }
    return;
}

At every iteration I wish to clear MATLAB's command window before calling mexPrintf().

I am aware that I can use mexCallMATLAB, to invoke MATLAB's clc, but I am not sure if invoking MATLAB at every iteration is very efficient, hence I need a solution native to C++.

Upvotes: 2

Views: 286

Answers (1)

kedarps
kedarps

Reputation: 861

My assumption about mexCallMATLAB being inefficient was wrong, thanks to @Ander Biguri for the heads up. I used the following test code to compare times with and without mexCallMATLAB.


TL;DR - TIMING RESULTS

  • With mexCallMATLAB(0, NULL, 0, NULL, "clc");: mean time per iteration = 0.1016885 sec
  • Without mexCallMATLAB(0, NULL, 0, NULL, "clc");: mean time per iteration = 0.0978730 sec

DETAILS

Test Bench Summary

  • Create a vector with 1 million random integers and take the mean.
  • Repeat for 500 iterations.
  • Compute time required for each iteration and save in vector.
  • Average iteration times to get mean time per iteration.

Code

#include "mex.h"
#include <iostream>
#include <sstream>
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include <ctime>
#include <vector>

using namespace std;
extern bool ioFlush(void);

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
    int nrhs, const mxArray *prhs[])
{
    int numiters = 500;
    /* initialize random seed: */
    srand(time(NULL));

    std::vector<double> all_times(numiters);

    for (int iter = 1; iter <= numiters; ++iter)
    {
        /* tic */
        clock_t begin = clock();

        std::vector<int> rand_vec;

        for(std::size_t i = 0; i < 1000000; ++i)
            rand_vec.push_back( rand() % 100 + 1 );

        double vec_mean = 0.0;
        for(std::size_t i = 0; i < rand_vec.size(); ++i)
            vec_mean += rand_vec[i];

        vec_mean /= rand_vec.size();

        /* clear screen */
        mexCallMATLAB(0, NULL, 0, NULL, "clc");

        /* toc */
        double time_elapsed = double(clock() - begin) / CLOCKS_PER_SEC;

        /* Print data in matlab */
        std::ostringstream buffer;
        buffer << "iter " << iter << " of " << numiters << 
                ". random vector mean = " << vec_mean << 
                ". in " << time_elapsed << "s" << endl;

        mexPrintf("%s", buffer.str().c_str());
        ioFlush();

        all_times[iter] = time_elapsed;
    }

    double avg_time = 0.0;
    for(std::size_t i = 0; i < all_times.size(); ++i)
        avg_time += all_times[i];

    avg_time /= all_times.size();
    mexPrintf("\navg time per iter = %3.7f\n", avg_time);

    return;
}

Note the use of ioFlush() which is an undocumented function needed to update command window at every iteration. See more details about it here.

To Compile

  • On Windows using Visual Studio: Add #pragma comment(lib, "libmwservices.lib") in source file.
  • On Ubuntu using gcc: Compile using mex yourFile.cpp -lmwservices

Upvotes: 1

Related Questions