### Extract rows/columns of matrices in C++ vs MATLAV In MATLAB you can extract the first and last rows of a matrix by
 ``12`` `````` A(1,:); A(N,:);``````

Is there a similar way in C++ where we can do this?
For example,
 ``1234567`` `````` for (int i = 0; i < ny+1; i++){ for (int j = 0; j < ny+1; j++){ A[j + ny*i] = cos(acos(ygl[j]) *(i)); cout << A[j + ny*i] << endl ; } }``````

How can I extract the first and last rows here and say replace them with all ones instead? If you are using a 2D C++ container, such as std::vector, first and last row replacement can be done using operator[] indexing or iterators. A quick and dirty slap-dash bit of code to show how it might be done:
 ``1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374`` ``````#include #include template std::ostream& operator<<(std::ostream&, const std::vector>&); template std::ostream& operator<<(std::ostream&, const std::vector&); int main() { // create a 2 dimensional int vector with known dimensions std::vector> vec { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }}; std::cout << "Let's verify the sizes of the 2D vector....\n"; std::cout << "The vector has " << vec.size() << " rows.\n"; std::cout << "The vector has " << vec.size() << " columns.\n\n"; // display the 2D vector std::cout << vec << '\n'; // row element replacement using operator[] indexing for (size_t i { }; i < vec.size(); ++i) { size_t fst_row { }; size_t lst_row { vec.size() - 1 }; vec[fst_row][i] = 0; vec[lst_row][i] = 0; } std::cout << vec << '\n'; // I'm sure there is a less messy way to do this....... // row element replacement using iterators for (auto itr { vec.begin() }; itr != vec.end(); ++itr) { *itr = 20; } for (auto itr { vec[vec.size() - 1].begin() }; itr != vec[vec.size() - 1].end(); ++itr) { *itr = 20; } std::cout << vec; } template std::ostream& operator<<(std::ostream& os, const std::vector>& v) { for (auto const& x : v) { os << x << '\n'; } return os; } template std::ostream& operator<<(std::ostream& os, const std::vector& v) { for (auto const& x : v) { os << x << ' '; } return os; }``````
 ```Let's verify the sizes of the 2D vector.... The vector has 3 rows. The vector has 4 columns. 1 2 3 4 5 6 7 8 9 10 11 12 0 0 0 0 5 6 7 8 0 0 0 0 20 20 20 20 5 6 7 8 20 20 20 20``` depending on what you are doing, though, 2d vectors can cause memory access aggravations and other woes. For very small problems, it does not matter too much.

valarray's slice will get you any row, column, or stuff like the diagonals even if its a 1-d being used for 2d as you are already doing.
a derpy example:

 ``123456789101112`` `````` int main() { valarray a{1,2,3,4,5,6,7,8,9,10,11,12}; valarray col = a[slice(0,4,3)]; for(auto i:col) {cout << i << " ";} valarray lastrow = a[slice(8,4,1)]; cout << endl; for(auto i:lastrow) {cout << i << " ";} }``````

this assumes a 3 rows x 4 cols entity. It takes a little getting used to getting the correct indices for the slices, but once you do, the amount of work you can do with near 0 effort is astonishing.
Last edited on I guess I forgot to mention, I am not using std:vector for this array, so I am initializing A as,
 ``123`` `````` double *A; A= (double*) fftw_malloc((nx*ny)*sizeof(double)); memset(A, 42, (nx*ny)* sizeof(double));``````

Which is different, I see what @George P has done and it makes sense but it feels a bit complex tbh. @jonnin I am using really large arrays that's why I am choosing to allocate memory, but can I initialize valarray to be arbitrary size of nx*ny? yes, valarray should be fine for a large matrix: it does the dynamic memory (new or malloc or whatever it uses) for you, and cleans the memory when it goes out of scope, all for you (vector does this too).

you can make a 2d valarray**, same as vector, but again, there are reasons to keep it 1d.
an arbitrary one?

valarray<double> mat;
mat.resize(nx*ny); //ready to go! or resize(nx*ny,42.0) if you have a default value for all cells.

vector, valarray, and std::array are all objects /classes that replace a basic C array (or pointer equivalent).

you should look at valarray. it can do block work, like adding up a row or column for you, or take the sin() of all the elements, and many things of that nature that require your own loops for other containers. The code is greatly simplified, and they were designed for performance.

**of sorts. you may have to make a vector of valarrays or something goofy if you really want to fool with that approach.
Last edited on I don't routinely deal with large gobs of data, manipulating the data as a whole, so std::valarray is not something that pops up as a "first use" option.

https://en.cppreference.com/w/cpp/numeric/valarray/slice shows a Matrix class using std::valarray and how it can be manipulated. It's probably wrong to use plain valarray<double> or vector<double> here.

JamieAL is using the library FFTW3, whose interface requires memory allocated with fftw_malloc. Whereas std::vector<double> allocates memory with std::allocator. And std::valarray<double> does not allow the user to control its memory allocation at all.

It's critical to call the right function, because fftw_malloc might do more than simply forward on to malloc. For example it could return an over-aligned buffer, or modify some library-internal data structures.

Here is an example of how to use std::vector with a "special" allocation function like fftw_malloc:

 ``1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768`` ``````#include #include #include #include #include // Just for example: void* fftw_malloc(std::size_t n) { static long const page_size = sysconf(_SC_PAGESIZE); if (page_size <= -1) return nullptr; void* result; if (::posix_memalign(&result, page_size, n) != 0) return nullptr; return result; } void fftw_free(void* p) { return ::free(p); } struct bad_fftw_malloc: std::bad_alloc { char const* what() { return "bad fftw_malloc"; } }; struct fftw_resource: std::pmr::memory_resource { void* do_allocate(std::size_t bytes, std::size_t const a) override { void* const ptr_orig = fftw_malloc(bytes); if (ptr_orig == nullptr) throw bad_fftw_malloc{}; // Ensure the alignment requirement is already satisfied by ptr void* ptr_copy = ptr_orig; if (ptr_orig != std::align(a, bytes, ptr_copy, bytes)) throw bad_fftw_malloc{}; return ptr_orig; } void do_deallocate(void* p, std::size_t, std::size_t) override { if (p) fftw_free(p); } bool do_is_equal(std::pmr::memory_resource const&r ) const noexcept override { return this == &r; } }; std::pmr::memory_resource* fftw_malloc_resource() { static fftw_resource res; return &res; } #include #include int main() { // Now `my_vector` is suitable for use with fftw3 std::pmr::vector my_vector(fftw_malloc_resource()); int constexpr n = 10; for (int i = 0; i < n; ++i) my_vector.push_back(i + 0.5); for (int i = 0; i < n; ++i) std::cout << my_vector[i] << '\n'; }``````
Last edited on Okay this sounds way too messy for just a simple one line of code in MATLAB. I am pretty confused and shocked how the alternative in C++ is waaay harder. Mm I tried some of your suggestions and I have something primitive-ish:

 ``1234567891011121314151617181920212223`` `````` valarray VGL1; VGL1.resize((ny+1)*(ny+1),0.0); valarray dVGL1; dVGL1.resize((ny+1)*(ny+1),0.0); valarray firstrow; firstrow.resize((ny+1)*(ny+1),0.0); // for (int i = 0; i < ny+1; i++){ for (int j = 0; j < ny+1; j++){ VGL1[j + ny*i] = cos(acos(ygl[j]) *(i)); dVGL1[j + ny*i] = dummy1[j + ny*i] * sin(acos(ygl[j]) * (i)) * dummy2[j + ny*i]; dVGL1 = pow(-1,(i))*(pow(i,2)); //first row. This is correct dVGL1[ny+1] = 1. * pow(i,2); //last row. This is correct //firstrow[j + ny*i] = dVGL1[slice()]; // this won't work } } ``````

I guess I shouldn't use valarray here for the reasons @mbozzi mentioned, but as a simple test now I will leave it.

So I am able to create each of the first and last row separately but not sure how to put it back in the array. I tried using slice in the loop but it wasn't really working (probably my syntax is off). I know for a standard 2D matrix in C++ I can do something like,
 ``12`` ``````for (int i=0; i<3; i++) Matrix[i] = 4;``````

to replace my first row elements with 4 for example, but I am struggling to do the same with my code. I just feel like there is a straight forward solution that I am not seeing. I am pretty confused and shocked how the alternative in C++ is waaay harder.

It takes a lot of effort to go from bits and bytes to an interface that acts like a matrix. The authors of MATLAB have already done the job. But there's nothing like that in the C++ standard library (valarray is the best it's got).

 I guess I shouldn't use valarray here for the reasons @mbozzi mentioned, but as a simple test now I will leave it.

It's fine, but perhaps only on your computer on Friday. Or, it might be totally okay - who knows?

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445`` ``````#include #include #include #include // Print `a` as a matrix of dimensions `width` by `height` to standard output // Assuming row-major storage order. void print_as_matrix(std::valarray a, int width, int height) { for (int y = 0; y < height; ++y) { std::cout << "["; for (int x = 0; x < width; ++x) { std::cout << std::fixed << a[y * width + x] << (x < width - 1? ", ": ""); } std::cout << "]\n"; } } std::slice column_slice(int i, int width, int height) { return{i, height, width}; } std::slice row_slice(int i, int width, int) { return{width * i, width, 1}; } int main() { int constexpr width = 8; int constexpr height = 4; // allocate a width-by-height matrix in a single valarray // arbitrarily fill it with data std::valarray a(width * height); std::iota(std::begin(a), std::end(a), 1.0); std::sin(a /= (width / std::atan(1) * 4.0)); print_as_matrix(a, width, height); std::cout << '\n'; // Change column 3 to all zeros a[column_slice(3, width, height)] = 0.0; // Change the last row to all ones a[row_slice(height - 1, width, height)] = 1.0; print_as_matrix(a, width, height); std::cout << '\n'; }``````

The a[column_slice(3, width, height)] has type std::slice_array
Assigning to it modifies the subset of a described by the slice.
https://en.cppreference.com/w/cpp/numeric/valarray/slice_array
Last edited on is this a good time to mention that there are many matrix capable libraries, one of the best being eigen? https://eigen.tuxfamily.org/index.php?title=Main_Page

or, to do you one better, it may cost like 1/2 a million bucks by now, but matlab has, had, something a tool to export c++ (that depended upon a matlab library file). It wasn't the fastest, but it works, and it saves translation across 2 very, very different languages.
Last edited on Thanks for the link, jonnin. :)

I notice using the Eigen library is supported on most compilers, and doesn't require another 3rd party library to use.

There's even a header-only version, called Spectra:
https://spectralib.org/
Last edited on Well, spent the past 24 hrs setting up Eigen with my VS code (was not easy) and now I am trying to rewrite some of my my arrays including std::vector to work with eigen and will see if that works better. My only concern if Eigen works with fftw3 library in C++ since I have already written a lot of functions with fftw3. Thanks all.
Last edited on JamieAl wrote:
Well, spent the past 24 hrs setting up Eigen with my VS code (was not easy)

There is a somewhat easy way to manage 3rd party library package integration with Visual Studio, vcpkg.
https://vcpkg.io/en/index.html

It is a command-line tool, but once you get it working installation of a library is a single command away. You can search for packages at either the website or in a command prompt with vcpkg.

Eigen is one of the available packages:
 ```D:\Programming\vcpkg>vcpkg search eigen ceres[eigensparse] Use of Eigen as a sparse linear algebra library in Ceres eigen3 3.4.0 C++ template library for linear algebra: matrices, vectors, numerical solv... highfive[eigen3] Enable Eigen testing libigl 2.3.0#1 libigl is a simple C++ geometry processing library. We have a wide functio... libigl[embree] Build with embree libigl[glfw] Build with glfw libigl[imgui] Build with imgui libigl[opengl] Build with opengl libigl[xml] Build with libxml magnum-integration[eigen] EigenIntegration library opencv[eigen] Eigen support for opencv opencv2[eigen] Eigen support for opencv opencv3[eigen] Eigen support for opencv opencv4[eigen] Eigen support for opencv pangolin[eigen] Build support for Eigen matrix types spectra 1.0.0 A header-only C++ library for large scale eigenvalue problems uvatlas[eigen] Use Eigen & Spectra for eigen-value computations The result may be outdated. Run `git pull` to get the latest results. If your port is not listed, please open an issue at and/or consider making a pull request: https://github.com/Microsoft/vcpkg/issues```

The packages I have installed at the moment (and somewhat use):
 ```D:\Programming\vcpkg>vcpkg list 7zip:x64-windows 21.07#1 Library for archiving file with a high compressi... 7zip:x86-windows 21.07#1 Library for archiving file with a high compressi... bigint:x64-windows 2010.04.30#7 C++ Big Integer Library bigint:x86-windows 2010.04.30#7 C++ Big Integer Library catch2:x64-windows 3.0.1#1 A modern, header-only test framework for unit te... catch2:x86-windows 3.0.1#1 A modern, header-only test framework for unit te... cppunit:x64-windows 1.15.1#3 Unit testing framework module for the C++ progra... cppunit:x86-windows 1.15.1#3 Unit testing framework module for the C++ progra... fmt:x64-windows 8.1.1#1 Formatting library for C++. It can be used as a ... fmt:x86-windows 8.1.1#1 Formatting library for C++. It can be used as a ... gsl-lite:x64-windows 0.40.0 A single-file header-only implementation of ISO ... gsl-lite:x86-windows 0.40.0 A single-file header-only implementation of ISO ... gtest:x64-windows 1.11.0#5 GoogleTest and GoogleMock testing frameworks gtest:x86-windows 1.11.0#5 GoogleTest and GoogleMock testing frameworks ms-gsl:x64-windows 4.0.0 Microsoft implementation of the Guidelines Suppo... ms-gsl:x86-windows 4.0.0 Microsoft implementation of the Guidelines Suppo... pdcurses:x64-windows 3.9#3 Public Domain Curses - a curses library for envi... pdcurses:x86-windows 3.9#3 Public Domain Curses - a curses library for envi... vcpkg-cmake-config:x64-windows 2022-02-06#1 vcpkg-cmake-config:x86-windows 2022-02-06#1 vcpkg-cmake:x64-windows 2022-05-10#1 vcpkg-cmake:x86-windows 2022-05-10#1```

(using the output tags works so much better than the quote tags)
Last edited on Okay this sounds way too messy for just a simple one line of code in MATLAB. I am pretty confused and shocked how the alternative in C++ is waaay harder.

C++ is designed to be a powerful, general-purpose programming language that allows developers to express an enormous variety of concepts while still maintaining backward-compatibility with older versions of the language, and C, as much as possible.

Matlab is designed specifically to enable mathematical experts to express, as easily as possible, complicated mathematical expressions and models.

What would be shocking and confusing would be if it were just as easy to express mathematical expressions in C++ as it were in Matlab, because that would mean one of those things wasn't doing its job properly.
Last edited on There is a 3rd party library available for reading and writing MATLAB binary files.
https://github.com/tbeu/matio

Available via vcpkg. Also available via vcpkg is the FFTW3 library:
https://vcpkg.io/en/packages.html I spent about 3 years making a tool to convert matlab to c++ but that was in the late 90s, the code is horribly out of date now. And it wasn't that much stuff, basic matrix and vector math, eigenvalues, inverse, solver, LU decomp, lyap, kroneker (sp?), a few dozen other common items.

but it started with lyap.
one matlab line, one function call .. probably 20 pages of C++ just for that one, and 3 different ways to do it before I found one that was fast enough. Thanks everyone for the incredible feedback/info! I am working with Eigen now and have managed to get few things working. I think, I will have to make a new post regarding new questions. Thanks again.
Topic archived. No new replies allowed.