C++ generic numeric algorithms in header <numeric>

The C++ Standard Library header <numeric> contains several generic numeric algorithms. In this post we take a look at how they can be used for solving real world examples.

Accumulating values

Problem: Given the monthly sales values compute the total sales during a year.

Solution: This is a simple sum that can be computed by iterating over the sales and summing them.

There is an algorithm for that called accumulate. It computes the sum in a given range and the provided initial value. So for our problem this can be put as:

Problem: Given the monthly inflation rates compute the total inflation during a year.

Solution: If the inflation was 10% in January and 20% in February, the inflation at the end of February is not 30% but 32%. The monthly inflation rates must be multiplied. An overloaded accumulate allows to specify a binary operation to be used for accumulating values, instead of operator+. So the solution to our problem could look like this:

Partial accumulations

Problem: Given the monthly sales values compute the accumulated total sales per whole year at the end of each month. In other words show the sales for January, January to February, January to March, … January to December.

Solution: This is again a simple summing operation where in each loop you have a partial sum. s[0] = v[0], s[1] = v[0] + v[1], s[2] = v[0] + v[1] + v[2], etc.

There is an algorithm called partial_sum that does exactly that: it computes the partial sums of the elements in the given range and writes them in a destination range. There are two overloads of it, one using operator+ and one that allows to specify a binary operation.

The content of acc_sales will be {1000, 2500, 4500, 6000, 8000, 9000, 12000, 13500, 14700, 16500, 18700, 20700}.

Sum of products

Problem: Given the values of daily sales in USD compute the total sales in EUR.

Solution: Computing the total sales in USD and then multiplying with the USD/EUR exchange rate is not a correct solution because the exchange rate varies every day. We must compute the daily sales in EUR and then sum those values. That means we need a sum of products.

Another algorithm in the <numeric> header called inner_product does exactly that. It takes two ranges and an initial value and uses operator* to compute the product and operator+ to sum the products.

Problem: Given the monthly budgets and the actual sales over an year count how many times the budget was met or exceeded.

Solution: To count how many times the sales where equal or greater than the budget we have to compare the values in each month and increment a value each time the condition was true.

Instead of coding this explicitly we could use an overload of the inner_product algorithm that takes two additional parameters, both binary operations, for the sum operation and the product operation. For the sum we can use std::plus() and for comparison std::greater_equal() (need to include header <functional>).

The result of the count for the input data is 6.

Adjacent differences

Problem: Given the monthly sales for an year compute the variations (in percentage) between the current and previous monthly sales. If sales in January were 1000 and in February were 1500, then the sales variation for February is 50%.

Solution: We have to iterate through the monthly value and compute (current - prev) / prev for each month. This is an operation applied to adjacent values.

An algorithm called adjacent_difference computes difference between adjacent values in a given ranges and writes them in a destination range. The first element of the input range is copied unmodified to the beginning of the destination range. An overload allows to specify a binary operation to be used instead of operator-.

To solve the proposed problem we call this algorithm on the sales and then remove the first element from the destination range (since it’s just a copy of the sales for the first month). We use a lambda for the binary operation and it simply returns (current - prev) / prev.

The result for the given range (shown with 4 decimals) is {0.5000, 0.3333, -0.2500, 0.3333, -0.5000, 2.0000, -0.5000, -0.2000, 0.5000, 0.2222, -0.0909}.

The standard way of converting between numbers and strings in C++11

In C++03 there was no standard way of converting numbers to strings. The best way to do that was using a std::stringstream:

One could put that into a more generic function that looks like this:

The opposite of converting a text to a number could look like this:

Of course, there was also the option of using C functions such as itoa, sprintf or atoi (or their Microsoft secure version _itoa_s, sprintf_s).

C++11 provides several standard functions for converting numbers to strings and strings to numbers, all of them available in the <string> header.

For converting numbers to strings there are two new overloaded functions: to_string() and to_wstring(). They take one argument of various numeric types (int, long, long long, double, long double, etc.) and return either a std::string or a std::wstring with the number converted to text.

These functions are actually just wrappers over sprintf and swprintf. According to the standard (section 21.5):

Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of “%d”, “%u”, “%ld”, “%lu”, “%lld”, “%llu”, “%f”, “%f”, or “%Lf”, respectively, where buf designates an internal character buffer of sufficient size.

For the other way around of converting strings to numbers there are several overloaded methods (taking either a std::string or a std::wstring):

  • stoi: converts a string to a signed integer
  • stol: converts a string to a signed long
  • stoll: converts a string to a signed long long
  • stoul: converts a string to an unsigned long
  • stoull: converts a string to an unsigned long long
  • stof: converts a string to a float
  • stod: converts a string to a double
  • stold: converts a string to a long double

Functions stof, stod and stold are also just wrappers over strtod and strtold:

the first two functions call strtod(str.c_str(), ptr) and the third function calls strtold(str.c_str(), ptr). Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

atoi() and atol() that convert a null-terminated byte-string (i.e. char*) to an integer or long were already available in header <cstdlib>. There is a new function available in this header called atoll() that converts a null-terminated byte string to a long long value.

Assigning algorithms in the C++ Standard Library

The C++ Standard Library provides several algorithms for assigning values to a range (such as a container or a C-array).

fill and fill_n

std::fill assigns a given value to all the elements in a range. It is available in the header <algorithm>. In the following example all elements of a vector of integers are assigned the value 1.

std::fill_n is similar, but instead taking the bounds of a range it takes the beginning and a count and initializes N elements starting from the specified first element. You must make sure that first + count does not exceed the bounds of the range. The following example is an equivalent of the first:

generate and generate_n

These algorithms are similar to the first, but instead of taking a value to assign they take a function and assign the value returned by the function. They are also available in the header <algorithm>.

std::generate assigns the elements in a range the values returned by a function.

In the following example we initialize a vector of 10 elements with random numbers (using a Marsenne twister engine).

The result may look like this:

You can use lambdas as the function whose return value is stored into the range. The following example generates random numbers ranging from 1 to 100 with a uniform distribution.

Result may look like this:

std::generate_n is similar, but instead of taking the limits of the range it takes the beginning and a count and assigns the first N values returned by the function to the range. You must makes sure that first + count does not exceeds the bounds of the range.

In the following example we initialize the elements of a vector with values from 1 to N, where N is the size of the range.

The result is:

iota

std::iota is a new algorithm to C++11. It assigns the elements of a range with sequentially increasing values starting from a given value. The algorithm is available in header <numeric>.

The following example initializes the elements of a vector with values from 1 to N, where N is the size of the range (basically the same thing we did in the last example).

The result is:

Notice that the term iota is taken from the APL programming language and denotes the Greek letter used in various mathematical notations.

WIC File Open Dialog Using IFileOpenDialog Interface

A previoius article extends CFileDialog MFC class, in order to make a File Open or a File Save dialog that automatically filters files, according to available WIC (Windows Imaging Component) codecs. This article presents how to show a similar File Open dialog using IFileOpenDialog interface. This way, it can be used not only in an aplication that uses MFC, but also in an ATL one, even in a raw Win32 or console application that uses basic ATL stuff.
Let’s see an example.

Using IFileOpenDialog to show a WIC File Open Dialog

Enumerating the WIC decoders

Demo project

The demo project is a simple Win32 console application that uses the above functions.

Download: WIC_File_Open_Dialog_Win32_Demo.zip (34)

WIC File Open Dialog - Demo

WIC File Open Dialog – Demo

 

Notes

  • In a similar way, we can make a File Save dialog using IFileSaveDialog interface.
  • This article presents just proof of concepts. IFileOpenDialog offers much more methods to customize the dialog according to specific needs. And of course, a more elegant job can be done by writing some C++ wrapper class(es).
  • For the future, I intend to integrate WIC File Dialogs in WIC Wrapper Library also presented in this blog.
  • The built-in WIC decoders deal with the following image file formats: BMP, GIF, ICO, JPEG, PNG, TIFF and WMPhoto. However there are many other decoders that can befound over the internet. Just to mention two free ones: Microsoft Camera Codec Pack and Adobe DNG Codec for Windows.

Resources

Free WIC codecs download

See also

WIC Wrapper Library – Version 1.1

WIC Wrapper Library v1.1 has the following:

  • new and completed methods for existing wrapper classes in the previous version;
  • new classes: wic::Bitmap and wic::Palette;
  • a new header containg enums, WicWrapEnums.h.

Download: WIC Wrapper Library [1.1].zip (41)

Example 2: Using wic::ImagingFactory::CreateBitmapFromHICON and wic::Bitmap

The following example is close to the previous one, except that it uses wic::ImagingFactory::CreateBitmapFromHICON to display an icon resource.

Demo Application

The demo application displays an icon resource when no image file is loaded.

Download: WIC Wrapper Library Sample [1.1].zip (34)

WIC Wrapper Library – Sample Application #2

WIC Wrapper Library – Sample Application #2

 

See also

WIC Wrapper Library – Version 1.0

I’ve begun writing a series of wrapper classes over WIC (Windows Imaging Component) interfaces, that can easily be used in MFC, ATL, or Win32 applications without worry about directly dealing with COM interfaces.
This first version contains basic operation for loading, scaling and converting source image formats that are supported by WIC.
Download: WIC Wrapper Library.zip (47)
WIC Wrapper Library.zip archive contains the following:

    • Header files, located in \WicWrap\Include folder;
    • WicWrapDLL.dll, both Debug and Release builds, located in \WicWrap\Bin folder;
    • WicWrapDLL.lib, both Debug and Release builds, located in \WicWrap\Lib folder.

Adding WIC Wrapper Library to a project

As said before, WIC Wrapper Library can be used in MFC, ATL or Win32 projects. Here is an example shownig the steps for adding this library to an existing project:

        1. copy WicWrap folder, in the solution directory;
        2. in Solution Explorer window right-click on project name and choose the Properties menu item;
        3. choose All Configurations, go to Configuration Properties\C/C++ and add $(SolutionDir)WicWrap\Include in the Additional Include Directories field;
        4. go to Configuration Properties\Linker\Input and add WicWrapDLL.lib (also for all configurations);
        5. choose Debug configuration, go to Configuration Properties\Linker and add $(SolutionDir)WicWrap\Lib\Debug in the Additional Library Directories field;
        6. choose Release configuration, go to Configuration Properties\Linker and add $(SolutionDir)WicWrap\Lib\Release in the Additional Library Directories field
        7. copy the debug and release versions of WicWrapDLL.dll in solution Debug and Release output directories;
        8. in Solution Explorer window, right-click on project name, choose Add\Existing Item and add the WicWrap header files from \WicWrap\Include folder;
        9. include WicWrap.h in the project source code, e.g in stdafx.h .

Using WIC Wrapper Library

Next is a simple example, in an MFC program:

More details can be found in the demo application, attached below.

Demo Application

The demo application is a simple image viewer made in a simple SDI MFC project.
Download: WIC Wrapper Library Sample [1].zip (39)

WIC Wrapper Library - Sample Application

WIC Wrapper Library – Sample Application

Note: the image shown in the sample application is taken from SoftIcons.com site.

WIC-related articles and resources

Multiple-View File Explorer

File Explorer (aka Windows Explorer) is a well known and commonly used file manager application, shipped since early Windows 95 operating system. There are also other replacements that can be found over the Internet, however, let’s see how can we make our own file manager, having multiple (tabbed) views.

A brief tour of possible ways

Ones can say that’s a piece of cake: just use raw-WinAPI to populate a tree with folders then a list with folder contents. Another ones can choose to use IShellFolder and browse the shell namespace for the same purpose. Booth methods require a lot of work to do and may be a real overkill. Even more advanced methods like using IShellView and IFolderView are not so easy.
Fortunately, for Windows Vista, Windows Server 2008 and newer Windows versions, we can use IExplorerBrowser interface to get a “full featured” File Explorer.
We have it so let’s use it!

Create the multiple tabbed views application

If have Visual Studio 2008 SP1 or newer, creating such type of project is no sweat.

  • Create a new MFC Application project (Ctrl+Shift+N).
  • In MFC Application Wizard check theese options:
    • Application type: Multiple documents & Tabbed documents
    • Project style: MFC Standard
    • User interface Features: Split window
    • Change generated view class name to CFileExplorerView.
  • Click the “Finish” button.

Of course, you can choose other options, but for our purpose the most important are multiple tabbed documents and split window.

Use IExplorerBrowser interface

We can directly use IExplorerBrowser interface in the view class but to make things easier, I wrote an MFC-extension class named CFileExplorer that takes care of instantiating, releasing and using IExplorerBrowser methods. Here is its definition:

The implementation of CFileExplorer class can be found in the demo project attached to this article. Now, let’s use CFileExplorer in our application view class.

          1. Add a CFileExplorer member to CFileExplorerView class
          2. Handle WM_CREATE message. In the OnCreate handler function, perform browser intialization like creating IExplorerBrowser instance, set initial options, set the parent window and folder options.
          3. Handle WM_SIZE and resize the browser to fit the parent client area.
          4. Handle WM_ERASEBKGND to avoid flickering when the parent view is resized.
          5. Finally, let’s override CView::OnUpdate and browse for a folder.

Demo Project

The demo project uses CFileExplorer to make a simple file manager with multiple views.
Download demo project: Multiple-View File Explorer.zip (121)

Multiple-View File Explorer

Multiple-View File Explorer

          • to open new views choose File/New menu item, press Ctrl+N or push the “New” button;
          • to split a view choose Window/Split menu;
          • to arrange views side by side drag from view tab caption;
          • to change a view layout push “Organize” then check “Layout” subitems;
          • to change the view style (details, small icons, tiles, etc) push “More options” button.

Notes

          • This article as well as the demo project presents just proof of concepts. It can be improved by adding many other features:
            • navigate back and forward;
            • add more functions to menu / toolbar or use a ribbon;
            • filter the columns to be shown in details view;
            • search;
            • automatically show views side by side;
            • make the layout and other settings persistent between application instances;
            • and so on, and so on.

Resources