New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pointwise operations between scalar and vector #707

Closed
SimoneTosato opened this Issue Sep 2, 2016 · 10 comments

Comments

Projects
None yet
3 participants
@SimoneTosato

SimoneTosato commented Sep 2, 2016

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(..)?

@ThomasBrierley

This comment has been minimized.

Contributor

ThomasBrierley commented Sep 2, 2016

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.

@SimoneTosato

This comment has been minimized.

SimoneTosato commented Sep 7, 2016

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?

@josdejong josdejong added the bug label Sep 7, 2016

@josdejong

This comment has been minimized.

Owner

josdejong commented Sep 7, 2016

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.

@SimoneTosato

This comment has been minimized.

SimoneTosato commented Sep 7, 2016

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

@ThomasBrierley

This comment has been minimized.

Contributor

ThomasBrierley commented Sep 7, 2016

nya! when operands become operators 😝

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.

@SimoneTosato

This comment has been minimized.

SimoneTosato commented Sep 7, 2016

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

@ThomasBrierley

This comment has been minimized.

Contributor

ThomasBrierley commented Sep 7, 2016

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.

@josdejong josdejong closed this in 92918ed Sep 7, 2016

@josdejong

This comment has been minimized.

Owner

josdejong commented Sep 7, 2016

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

@SimoneTosato

This comment has been minimized.

SimoneTosato commented Sep 7, 2016

Thank you guys you're awesome ❤️

@josdejong

This comment has been minimized.

Owner

josdejong commented Sep 7, 2016

You're welcome :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment