Skip to content
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

Missing diff #1634

Closed
melroy89 opened this issue Sep 25, 2019 · 11 comments
Closed

Missing diff #1634

melroy89 opened this issue Sep 25, 2019 · 11 comments

Comments

@melroy89
Copy link

melroy89 commented Sep 25, 2019

Hi,

I have an array of numbers, I would like to calculate the diffs between them.

Calculate the n-th discrete difference along the given axis.

Just like the numpy diff.

Is that possible?

Ps. this is definitely not the same as your math.setDifference!

Regards,
Melroy

@LloydLS
Copy link

LloydLS commented Sep 26, 2019

You can use .map(), e.g.

arr = [1,6,3,8,7,10];
diff = [];
arr.map( f(x,i,a) =  (i[1] + 2 > size(a)[1]) ? "" : diff = concat(diff, [a[i[1] + 2] - x] ))
// diff == [5, -3, 5, -1, 3]

The function f(x,i,a) used in .map() gives you access to the element of the array (x), the index of the array (i, note that this is zero based and returned as an array containing 1 element), and the array itself (a)

@melroy89
Copy link
Author

More over your code gives ReferenceError: f is not defined

@melroy89
Copy link
Author

melroy89 commented Sep 26, 2019

The answer would be, but nevertheless maybe somebody just want to add it to mathjs?

x = [..., .. ,..]
y = [..., ..,..]
// Assuming both x & y are the same length
var diff = x.map((value, index) => value - y[index])

@LloydLS
Copy link

LloydLS commented Sep 27, 2019

The answer would be, but nevertheless maybe somebody just want to add it to mathjs?

x = [..., .. ,..]
y = [..., ..,..]
// Assuming both x & y are the same length
var diff = x.map((value, index) => value - y[index])

Hi,
If you want to subtract one array from another in MathJS you don't need .map(), you can just subtract one from the other.

@LloydLS
Copy link

LloydLS commented Sep 27, 2019

More over your code gives ReferenceError: f is not defined

That's odd, it works for me on the MathJS site. Maybe someone else can chime in on this.

@josdejong
Copy link
Owner

Thanks for your suggestion Melroy, would be nice to add a function diff.

@LloydLS the function diff would not calculate the difference between two matrices, but calculates the difference between the elements in a matrix: [1, 2, 4, 7, 0] should return [ 1, 2, 3, -7] for example.

Before implementing diff we should discuss the details of how it should behave, we can take the Python implementation as example and source of inspiration.

Anyone interested in implementing diff? Help would be welcome.

@Veeloxfire
Copy link
Contributor

Veeloxfire commented Apr 5, 2020

I wrote a function called crush (named after garlic crusher to give you an idea of what it should kinda do and I couldnt think of what it should actually be called)
Currently what it does is take a function and an array. It then takes the array and runs the function on slices of the length equal to the number of parameters of that function. So for this example it would be diff = (x ,y) => y - x and arr = [1, 2, 4, 7, 0] then math.crush(arr, dif) goes over the array like this: [diff(arr[1] - arr[0]), diff(arr[2] - arr[1]), diff(arr[3] - arr[2]), diff(arr[4] - arr[3])]
It uses diff.apply(null, arr.slice(i, i+1)) so it can take functions of any number of parameters (but throws RangeError if function takes more parameters than the array contains)

e.g.

largeAdd = (a, b, c, d, e, f, g, h) => a + b + c + d + e + f + g + h  //<- 8 elements
arr = [1, 2, 3, 4, 5, 6, 7, 8]  or matrix([1, 2, 3, 4, 5, 6, 7, 8]) //<- 8 elements
math.crush(arr, largeAdd) returns [36] or  matrix([36]) //<- 1 element

I wrote it this way becuase it allows it to be slightly more general kinda like the map function than just implementing a diff function, which didnt take very long when I tried it originally.

@josdejong What are your thoughts? Is this the sort of thing you were thinking of?

EDIT: In the c++ standard library they have a diff function similar to the numpy one called adjacent_diff. Maybe a better name for this function if it were implemented would be adjacent

@josdejong
Copy link
Owner

That is an interesting approach. So this way you can pass any function which will be applied to every pair of two elements, but also can loop over every set of 3 or 8 elements as in your example. I guess you can use that for calculating sliding windows and things like that? Can you give some usecases for this function crush? It looks interesting, but it also feels quite specific to me. I have the feeling that in many cases writing a little for-loop or map or reduce offers you more freedom so I'm not sure how much value it adds.

I think the function diff is so common that it is good to implement this. Under the hood it could utilize a more generic function like crush, but I think diff is so simple that this would only complicate things and is probably not worth it.

I'm not sure about the naming, I see Matlab and Python both use diff as name, wouldn't it make sense to simply follow them?

@Veeloxfire
Copy link
Contributor

Veeloxfire commented Apr 8, 2020

Yeah that does make sense. I was just trying to generalise but I guess its not common enough to need that as the diff function would be the only example that would need it.

@josdejong
Copy link
Owner

👍 let's start simple then and see how it evolves :)

@josdejong
Copy link
Owner

Closing this issue, diff has been implemented in the meantime.

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

No branches or pull requests

4 participants