This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
Bug 749 - Enable resize() on Maps when rows*cols doesn't change
Summary: Enable resize() on Maps when rows*cols doesn't change
Status: NEW
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - general (show other bugs)
Version: 3.2
Hardware: x86 - general All
: Normal enhancement
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-24 11:42 UTC by Xavier Robin
Modified: 2019-12-04 13:02 UTC (History)
4 users (show)



Attachments

Description Xavier Robin 2014-02-24 11:42:12 UTC
Hope to phrase this correctly.

A typical use-case where one would like to allow resizing of a map is when calling transposeInPlace() on a rectangular Map<...>. Currently this fails because the resulting map has different dimensions than itself:

/path-to-eigen/Eigen/src/Core/Assign.h:498: Derived& Eigen::DenseBase<Derived>::lazyAssign(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<int, -0x00000000000000001, -0x00000000000000001, 1, -0x00000000000000001, -0x00000000000000001>, Derived = Eigen::Map<Eigen::Matrix<int, -0x00000000000000001, -0x00000000000000001> >]: Assertion `rows() == other.rows() && cols() == other.cols()' failed.

The following example (that currently produce the above error) ought to work though, as the dimensions of the data doesn't change it should be pretty safe to write:

#include <Eigen/Dense>
using Eigen::Map;
using Eigen::MatrixXi;

int main() {
	// Create an array of integers 0 to 9
	int* dat = new int[10];
	for (int i = 0; i < 10; i++) {
		dat[i] = i;
	}

	// Map it in a 2x5 matrix
	Map<MatrixXi> m(dat, 2, 5);
	
	// Transpose in place
	m.transposeInPlace();
	
	delete[] dat;
	return 0;
}


This feature request was discussed here: http://forum.kde.org/viewtopic.php?f=74&t=119828
Comment 1 Christoph Hertzberg 2014-02-24 12:32:09 UTC
Another restriction would be that there can't be a non-default outer stride. I think an inner-stride actually is no problem.

A workaround for your case would be:
  Map<MatrixXi> m2(dat, 5,2) = m.transpose().eval();
Or even using placement-new (this is untested, maybe you need an explicit temporary to do this):
  new(&m) Map<MatrixXi>(dat, 5,2) = m.transpose().eval();

Note that the eval() is necessary in both cases and essentially what transposeInPlace() does for non-square matrices at the moment (cf. Bug 226).
Comment 2 Christoph Hertzberg 2014-02-24 13:01:17 UTC
Addendum:
Thinking about it again, I'm kind-of against allowing resize on Maps. Otherwise, assigning non-fitting expressions to a Map would be allowed as well, which I think will be a likely source of errors. Also, allowing resize for transposeInPlace() but not for assignments seems inconsistent to me.

I think usually just creating another Map sharing the same memory is a 'good enough' workaround (I just noticed that you already found it yourself).

I'll specify what resizable means in the documentation of transposeInPlace, but keep this bug open.
Comment 3 Gael Guennebaud 2014-02-24 13:40:44 UTC
Indeed, non-default outer stride would be an additional restriction.

The .eval() workaround introduces a temporary while in theory this could be done without any temp. So it seems there is no ideal solution.
Comment 4 Angelos 2015-07-05 09:34:20 UTC
Hi,

Remapping maps can be very useful. Maybe if not resize, there can be a function remap(.,.) which would only work if size() stays the same.
Also, transposeInPlace is a useful operation on a map.
Comment 5 Nobody 2019-12-04 13:02:01 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/749.

Note You need to log in before you can comment on or make changes to this bug.