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
>>>
>>

Reply via email to