Mathjs: Pointwise operations between scalar and vector

Created on 2 Sep 2016  Â·  10Comments  Â·  Source: josdejong/mathjs

Is there a smart way to do this? Because I can't find any in the documentation.

Let's say I have something like
a = 1:10
b = 4
Multiplication works great, either
a*b
or
b*a
returns
[4, 8, 12, 16, 20, 24, 28, 32, 36, 40]

but with divison and power I have some issues, what is in my mind is something like

b/a (or b./a)
to act something like this
(b*ones(size(a)))./a

is there a smarter way to do this than replacing every number in the string with number*ones(..)?

bug

All 10 comments

I tried the element-wise scalar vector divide b./a and it seems to work fine, with the same result as your array building example. Is it that element-wise divide is not working for you or that vector multiply is not coercing the scalar operand into a vector?

a = 1:10
b = 4

b./a
// = [4, 2, 1.333, 1, 0.8, 0.667, 0.571, 0.5, 0.444, 0.4]

(b*ones(size(a)))./a
// = [4, 2, 1.333, 1, 0.8, 0.667, 0.571, 0.5, 0.444, 0.4]

I'm not sure why b/a isn't supported, perhaps because divide is non-commutative so order is important meaning divide must operate on the first operand which is a scalar. Where as with b*a we can just cheat and operate on the second operand... I'm not sure if that coercion was avoided intentionally or accidentally.

... I wonder if this is the same code that deals with string coercion because that was identified as being a little bit inconsistent recently.

I've found the issue I was facing. With variables it works fine

a=1:10
b=4  
b./a
// = [4, 2, 1.333, 1, 0.8, 0.667, 0.571, 0.5, 0.444, 0.4]

But when i try to do something like

a=1:10
4./a
//RangeError: Matrix must be square (size: [10])

I've found a solution doing

(4)./a

but i would like to know if there is a better way. Since my work has to operate with arrays I currently parse the equation string to change every operation to pointwise, I could change every number to (number) too,but is there a smarter way to deal with this issue?

Ah, I get it. The parser parses 4./a as (4.)/a. To work around it you can indeed surround the the number by parenthesis, or add a space in between, like 4 ./ a.

I will fix this by making the parser more strict such that it doesn't consider 4. a valid number, the dot should be followed by a digit.

Love ya. ♥

Also regex solved this replacing every number in string with (number) as said before, maybe it's a bit odd but works so for now i'm fine with this

nya! when operands become operators :stuck_out_tongue_closed_eyes:

Are there any operators ending in .? because .0 is considered a valid number format by some (at least from an end user perspective)... maybe for simplicity mathjs should not consider either case to be part of a number.

Well, if there are no operands ending with . (and i hope there are not) this is handling it well for me

string.split('*').join('.*').split('/').join('./').split('^').join('.^');
string.split('..*').join('.*').split('../').join('./').split('..^').join('.^');
string.replace(/(\.?\d+)/g,'($1)');

"3/this"

becomes

(3)./this

and

".3/this"
(.3)./this

so it's working fine for now

Be aware that your expression manipulation would also change some valid vector-vector operations into alternatives vector-vector operations e.g dot product [1, 2, 3] * [1, 2, 3] // 14 into element-wise multiply [1, 2, 3] .* [1, 2, 3] // [1, 4, 9].

I think your dot might need escaping if I understand correctly?

/(\.?\d+)/g

Alternatively if you want a more thorough number regex:

/([\-+]?\d*)(\.\d+)?(e[\-+]?\d+)?/ig

Handles signs, decimals and exponents, excludes trailing but not leading decimal.

@SimoneTosato this should be fixed now in v3.5.0 (available on npm, website will be updated soon)

Thank you guys you're awesome :heart:

You're welcome :)

Was this page helpful?
0 / 5 - 0 ratings