Hi, what about writing a small helper function "as_scalar_or_array(x)" that would return a scalar if x is already a scalar or a 1x1 Eigen expression at compile-time, and just x otherwise. This should solve most of your problems. Another direction would be to use "auto val = ArrayXd::Constant(n,x)" instead of "double val = x;" but this needs to know and store the size n.
Gaël. On Thu, Jul 30, 2020 at 9:53 AM Mario Azcueta <[email protected]> wrote: > Thank you very much for your answers and suggestions. > > Adrien's suggestion on overloading functions to accept both Arrays and > scalars solved some of the problems (e.g. retrieving the size of an > array/scalar) > > However, I reached a wall when reductions were involved, i.e., there is a > sub-function call that given a scalar returns an Array3d, and given a > VectorXd returns an ArrayX3d. On these return values, I calculate the sum > of each row, so that ArrayX3d reduces to an ArrayXd and the Vector3d > reduces to a scalar. I'm still finding a way to deal with these 2 > situations properly without replicating code. I may need to revise my > approach since I brought it from Matlab, where it was very convenient, but > I see it a bit forced given that Eigen does not allow summing > single-element arrays with multiple-elements. > > Thank you all again, > Mario > > El mié., 29 jul. 2020 a las 9:15, Joseph Mirabel (<[email protected]>) > escribió: > >> Hi, >> >> >> I have one comment on that. When I need this, I write code like >> >> a[0] * b >> >> where `a` is a vector of 1 element. This works fine but makes the code >> unclear as it is not evident that `a` has only one element. Of course, I >> can add an assert or a comment myself but that relies on me doing it... >> >> I don't like the automatic casting but I would find an explicit method >> clearer. I am not able to find a good name for it. Maybe an explicit cast >> operation ? >> >> a.asScalar() * b >> >> a.singleElement() * b >> >> static_cast<Scalar>(a) * b >> >> >> Joseph >> >> >> On 29/07/2020 03:56, Rasmus Munk Larsen wrote: >> >> Generally speaking, silently treating vectors as scalars and vice versa >> with implied broadcasting is a common source of subtle bugs, so this >> behavior is unlikely to change. Eigen does support scalar*vector, if you >> extract the single element as such. >> >> On Tue, Jul 28, 2020 at 6:06 AM Mario Azcueta <[email protected]> wrote: >> >>> Is there a way of adding/subtracting/multiplying two Eigen::ArrayXd >>> arrays both when (a) they have dimension N, and (b) when one of them has >>> dimension N and the other dimension 1? >>> >>> I'd ideally like that the array with size=1 is treated like a scalar for >>> these operations. I'm somewhat trying to replicate the way Matlab behaves. >>> >>> As an example, I'd the code below to work both when a1 and a2 have the >>> same size, as well as when one of them has size=1 and the other size=N: >>> >>> ArrayXd add_arrays(const ArrayXd& a1, const ArrayXd& a2) >>> { >>> return a1 + a2; >>> } >>> >>> Of course, this could be solved with an if statement, but I want to >>> avoid that since my actual code would require to write a long function >>> verifying all combinations of sizes (they're many args). Also, writing a >>> template function gets me problems when trying to use some ArrayXd methods >>> and I pass a double. >>> >>> I've looked into the EIGEN_ARRAYBASE_PLUGIN preprocessor which may seem >>> like the way to extend this behavior, but I'm not sure this is the right >>> way.. any advice will be welcome. >>> >>> Note: I've also post this question here >>> >>> https://stackoverflow.com/questions/63074198/c-eigen-treat-single-element-array-as-scalar-for-arithmetc-operations >>> >>
