Project

Module for working with Vectors

Started by brianc on .

Sign in or create an account to join the conversation.

38 posts

Hey brianc, that does look useful - many thanks. :)

Is this part of the "learning curve about to drop" or is it just a coincidence that several instructional-type modules have been uploaded by forum members in the last few days?
Joe Soap wrote:Is this part of the "learning curve about to drop" or is it just a coincidence that several instructional-type modules have been uploaded by forum members in the last few days?
Pure coincidence, at least on my part :) I just thought that it'd be useful to modularize and release functions/objects that can be reused, both for myself and others.

More to come from me...
Nice one man. :)


I'd go further with this idea in fact, as though very useful (and appreciated) . . . it still falls into the category of "the code is the documentation". All well and good for those from (almost any) coding background - but still quite a leap.

For instance it might be a nice idea to explain to people why vectors are useful / necessary. What sorts of things are they used for etc.Oftentimes, the level of abstraction involved makes it difficult to connect the dots between an idea someone has in mind to the underlying techniques required to implement that idea?

IOW . . . we need pics and diagrams, real-world examples, to stand alongside code examples / modules. Nothing about the process should be considered too basic to outline.

This isn't a criticism levelled at you specifically (or at all), Glad people are making the effort.
I definitely agree with you. I chose to be pretty minimal on the documentation just to keep the code small. Most of my projects are pretty big and use quite a few modules like this, and I try to keep the code as small (but still readable) as I can.

Maybe I'll start creating a separate README instead of just the small README() functions included in my modules (those are limited by the cap on script size). I'm also planning to include example templates with modules to show a little bit about how to integrate the modules.
@ Phil999 . . . exactly.

I mean, I have a very rough idea what vectors can be used for (indexing into grids?) . . . but even that (and I may be misunderstanding even still) bit of knowledge was hard-won, from the contexts in which "use vectors" seemed to be the answer (here on the forums).

Oh . . . I've seen various people handwave in the direction of "any basic programming tutorial" etc when asked to explain some stuff further - but this kind of advice rather misses the point. WHICH basic turorial??? Link some FFS!!! :P

It's a wild and wooly internet out there . . . what if some poor n00b* ends up studying Haskell or LISP in their ignorance? :D

* Yeah . . . I'll cop to that.
Hi All

Nice bit of work there though I still have to have a good look through it all . . .
But a few general comments . . .

I must admit I think I prefer 'array' to 'vector' as terminology but much of a muchness in the end - both terms have simultaneous overlapping and exclusive definitions in my mind . .

Think of an 'array/vector' as a 'list' - a bunch of numbers or names that you can access by there position/index in the list . . .

In general I would say check out a 'C-based' tutorial just to get an understanding of assignment, variables, equations, functions etc
There are not really any tutorials that cover both basic program design/structure and Lemur specific approaches . . .

A few specific comments . .

Not sure what the usual result should be for adding unequal arrays - I thought you 0-padded the shorter and return the longer of the two . . .
This is actually the result you get when using standard maths operations on arrays in Lemur ie {1, 2, 3}+{4, 5, 6, 7} = {5,7,9,7}
Perhaps it would be better to call them add_tr, subtract_tr etc to make it clear that they truncate to the shortest as opposed to maintain longest length

Any particular reason why you went with functions for some and scripts for others - ie push vs pop?? Just wondering . . .
Macciza wrote:I must admit I think I prefer 'array' to 'vector' as terminology but much of a muchness in the end - both terms have simultaneous overlapping and exclusive definitions in my mind . .
I do too. I went with the word "vector" just because that's what the Lemur documentation calls them.
Macciza wrote:Not sure what the usual result should be for adding unequal arrays - I thought you 0-padded the shorter and return the longer of the two . . .
This is actually the result you get when using standard maths operations on arrays in Lemur ie {1, 2, 3}+{4, 5, 6, 7} = {5,7,9,7}
Perhaps it would be better to call them add_tr, subtract_tr etc to make it clear that they truncate to the shortest as opposed to maintain longest length
Yeah, this was a tough design decision. In the mathematical sense, vectors of different dimensions aren't compatible, and just about all implementations of element-by-element arithmetic I've seen (MATLAB/Octave, Mathematica, R, and implementations I've encountered in C/C++/Python) all assert that the lengths are the same. Because of that, I don't like the way it's done in Lemur. I suppose I should make the change, though, to at least make it consistent. Next version...
Macciza wrote:Any particular reason why you went with functions for some and scripts for others - ie push vs pop?? Just wondering . . .
Size. For things I could do as one-liners, I used functions.


Can you think of anything that's missing? The next version will also have filter functions, like ge({9,4,6,1,3,5,8},5) returns all elements greater than or equal to 5, or {9,6,5,8}.
Some good functions there Brianc, thanks! I think some of them mightbe built-in functions.

That is one thing I have requested from legacy times, I would love to save/load functions, instead of copy/pasting or re-writing from scratch, but hey, Liine guys are makig a great job with lemur imo, so simply I can't complaint.

@Macciza about of adding arrays with different sizes, recently I had a project where I used it alot (generative template), so I what did was to wrap arrays, I don't know if this helps in some way, but I have added a file.

Cheers and thanks again brianc.

addArray.jzml
Updated to include some more functions for creating random vectors (floats, integers, and unique floats after inspiration from Antonio), calculating magnitude, calculating angle between vectors, changing the range of all values for all elements, and probably something else. Complete documentation to come soon.

My goal for this module is to create a place to go for working with vectors. I don't personally have uses for all of these (like angle between two vectors), but I wouldn't be surprised if someone comes along who does.

To provide some ideas, vectors can be used to store values of some meter over time. For example, if you're watching the output level in a template for Logic, you might want to know if that level has clipped recently. If you only look at the current value, you can only see clips when they happen. Instead, if you look at the levels for the last 10 seconds, you can know if a clip occurred within that time period.

My personal motivation behind this are for a module I've been developing for syncing to an external MIDI clock. I keep track of when the ticks come in (in a vector) to keep an eye on how tempo changes over time. That lets me monitor the quality of the signal (the reason for my Stats module), detect missed ticks, and so on. It also helps me keep a more consistent tempo instead of only going by instantaneous measures, which can vary quite a bit.

screenshot.png
Cheers AB
That was what I was getting at - that the 'add' function was already there, just implemented differently
Your add_array would drop in replace for SLVector.add - I think I used subarrays() in a similar case . . .
and I do think it is worth adding something that indicates it truncates as opposed to the in built larger length
Same with some of the others - and if using a lot of them then code optimisation could be worth something at point

And at least one is over-riding a built in function - range(a,min,max) is already included and yours seems no different
Which kind of brings up naming conventions, structuring etc Do things still work if setup slightly differently etc


Re; Vector or Array - I think there may be a distinction between vectors in a dimensional (2d,3d etc) sense and arrays in the sense of lists
But I guess it all just linguistics and your particular application . . .
Macciza wrote:Cheers AB
That was what I was getting at - that the 'add' function was already there, just implemented differently
Your add_array would drop in replace for SLVector.add - I think I used subarrays() in a similar case . . .
and I do think it is worth adding something that indicates it truncates as opposed to the in built larger length
Same with some of the others - and if using a lot of them then code optimisation could be worth something at point
I'm sorry, I'm not following. Both mine and Antonio's truncate. Are you just saying that it should be indicated in the function name? That's understandable. My original hesitation was that someone coming in who is familiar with other environments would probably expect to look for add to be called add. I tried to make my function names match what is used in other languages as best as I could. But, common behavior elsewhere is to not work at all when vectors have different lengths, so I'll make the names more specific. truncate_add(), add_truncate(), add_tr()? Dunno yet. Same will apply for all the other arithmetic functions.

Code optimization is something I'm back-and-forth on in this case. While a lot of these could be one-liners, that cuts down on a lot of people's ability to read and understand them. I did some of each here, and I'm not quite sure which fits the task better.
Macciza wrote: And at least one is over-riding a built in function - range(a,min,max) is already included and yours seems no different
Which kind of brings up naming conventions, structuring etc Do things still work if setup slightly differently etc
I had mistakenly assumed the built-in range only worked with numbers, but I see it also works with arrays. I'll be removing it.
Macciza wrote: Re; Vector or Array - I think there may be a distinction between vectors in a dimensional (2d,3d etc) sense and arrays in the sense of lists
But I guess it all just linguistics and your particular application . . .
From what I was taught when I learned programming, "arrays" typically refer to data structures that store a fixed number of objects, while "vectors" can change in size appropriately. I still think of them that way (so I would call these "arrays"), and most programming languages follow that convention (like C++'s STL), but people still use them interchangeably.
hey Brianc, this is a great topic.
This can inspire one to develop stuff.
Thanks Macciza for the headsup on this thread


Hey (Brian/all), I was wondering if you would be interested in taking a look at a little problem I have, precisely with vectors.

Long story short, I wrote a script that populates a vector with about 100 different items or values. Let's call it vectorA

I use that vector for comparison purposes and then to determine the properness of certain scripted routines I have been writing.

Right now I am stuck as I can't figure out how to compare another smaller vector (vectorB) with the contents of vectorA.

ie, say,
vectorA={1,2,3,4,5}
vectorB={2,4}

vectorA==vectorB?=1:0;

What I need is some sort of function to determine whether vectorB's values are CONTAINED in vectorA, and then obtain a true or false result.

Obviously, the length/size of the vectors is oversimplified. As I said, I need to compare vectors with about 100 values vs smaller vectors with about 6 values.

Basically, this question is preventing me from finishing a project that I have been working for a while!!!


help!!!!


Cheeers!
I just took a deeper look at your functions/scripts Brian.
Particularly at "contains"

You can check how if you monitor:
contains({1, 2, 3, 4, 5}, {4, 99})
you always get ret=1 even though the two arrays are not really the same.

For you to get ret=0, you have to have entirely distint arrays like so:
contains({1, 2, 3, 4, 5}, {7, 99})

I wonder if there is a way to write a function to compare vector "content vs content" without having to create loops.
It looks to me like only a loop would do it here (in regards to my scenario)


PS: Btw, what's up with you Brian putting "creative commons licensing" in the file for these somewhat simple functions that are actually public knowledge and common programming techniques especially in other languages and environments?
Just curious. I find it a bit over the top.
m127 wrote:I just took a deeper look at your functions/scripts Brian.
Particularly at "contains"

You can check how if you monitor:
contains({1, 2, 3, 4, 5}, {4, 99})
you always get ret=1 even though the two arrays are not really the same.

For you to get ret=0, you have to have entirely distint arrays like so:
contains({1, 2, 3, 4, 5}, {7, 99})

I wonder if there is a way to write a function to compare vector "content vs content" without having to create loops.
It looks to me like only a loop would do it here (in regards to my scenario)


PS: Btw, what's up with you Brian putting "creative commons licensing" in the file for these somewhat simple functions that are actually public knowledge and common programming techniques especially in other languages and environments?
Just curious. I find it a bit over the top.
...
Hi Brian
I just meant that add function as '+' was already there, which is at he used then 'wrap'ed to the shorter length - I guess I'm used to MutableArrays . . .
I was not sure if you realised the maths operators +-/* already worked on arrays but at longer length making AB code that much simpler as {array}+{array} is already standard within Lemur, rather then iterating though.
I guess ultimately the fact that it is 'add' as opposed to '+' it probably ok - I guess I just wanted the built-in Lemur array maths operators where not thought to be missing or inapplicabble to arrays.
The code optimisation thing was just that there are the inbuilt functions which may be faster, more so than the one-liner thing

m127 - Unfortunately I don't think the code deals with the array input . . .
Also do you want to work if the second array numbers are both in the first, or contiguously in the first - Do the 6 in a 100 need to be in order when they occur?

Cheers all
MM
Hi @Macciza,

I thought you wanted for a solution to get equal arrays size when "adding arrays of non equal size" :D, so I posted "my workaround" I didn't see brian's add script, I have checked it now and it makes basically the same but a bit in a different way, same behaviour truncating the array though.

Array vs vector in lemur I really think on them as you mentioned.

Cheers,
AB
well, yeah, I solved it as I foresaw. It seems that only a loop will do, like so:
decl this, a, i, size, vectorA, vectorB;

vectorA={1,2,3,4,5};
vectorB={2,3,4};
a=0;
size=sizeof(vectorB);

for(i=0;i<size;i++)
{
if(vectorB[i]== vectorA){a[i]=1;}else{a[i]=0;}}

if(sumof(a)!=size){Monitor.value=0;}else{ Monitor.value=1;}
This above is a super-simplified example of what I am trying to accomplish (vector A is really like a 90 values vector).

It is a mere trick, but the fact is that I can't find a more efficient way to do the verification (whether or not vectorB's values are contained within vectorA).

For my project to work the way I want, I need to find a way to run about 70 verifications (ie, vector A is the "master" vector, but I have to verify another 69 vectors besides vectorB).

Could any of you help simplify the code above (make it more efficient/concise)?
Or do you think it's as concise as it will ever get?

As you can see, the verification takes places after "a" is filled with either 1's or 0's, then the sum of all of a's items is calculated and so if a's sum is equal to the size of vectorB, then we get a "true" or 1, else a "false" or 0.

The verification is rock solid now.

But I still wonder if there is a way to make a more efficient verification (less code).

Macciza wrote: m127 - Unfortunately I don't think the code deals with the array input . . .
Also do you want to work if the second array numbers are both in the first, or contiguously in the first - Do the 6 in a 100 need to be in order when they occur?

Cheers all
MM
No, order is irrelevant in my case scenario.

Macciza, what is the actual limitation in terms of characters or similar per script?

Just 6 verifications like the coded above started to turn some of the script text BLACK!!


This is how it looks without the breaks, but still, I have no idea where am I going to put the code to verify 70 vectors:
decl this, a, i, size, vectorA, vectorB;
vectorA={1,2,3,4,5};vectorB={2,3,4};a=0;size=sizeof(vectorB);
for(i=0;i<size;i++){if(vectorB[i]== vectorA){a[i]=1;}else{a[i]=0;}}
if(sumof(a)!=size){Monitor.value=0;}else{ Monitor.value=1;}
vectorVerificationByM127.jzml
m127 wrote: What I need is some sort of function to determine whether vectorB's values are CONTAINED in vectorA, and then obtain a true or false result.
Obviously, the length/size of the vectors is oversimplified. As I said, I need to compare vectors with about 100 values vs smaller vectors with about 6 values.
Basically, this question is preventing me from finishing a project that I have been working for a while!!!
help!!!!
Whoa, sorry for the delay! The forum didn't tell me there were new posts in this thread for some reason. I'll try to combine a few posts:

I had originally intended contains() to look for a single value, so tthat's why it's not working for you as expected. I've updated the behavior of contains() in version 1.2 of SLVector (online now, including some basic documentation), so hopefully that's another way to get what you were looking at. You can now just do:
SLVector.contains(a,b)
Which will return 1 if vector a contains all of the values in vector b, and 0 otherwise. So SLVector.contains({1,2,3,4,5,6,7},{1,3,4}) would return 1, while SLVector.contains({1,2,3,4,5,6,7},{1,3,9}) would return 0.

It looks like you came up with a good solution!
m127 wrote:PS: Btw, what's up with you Brian putting "creative commons licensing" in the file for these somewhat simple functions that are actually public knowledge and common programming techniques especially in other languages and environments?
Just curious. I find it a bit over the top.
Yeah, I definitely don't mean to be pretentious or to claim that I invented these basic algorithms. I just want to be explicit that people can use the module as a whole however they wish. For example, one of my templates was inspired a bit from another template, and since it wasn't clear what that template's author's terms were, I had to email him just to make sure it was ok. The CC license saves that step. It was also just me trying some ideas of how a community-based module ecosystem might work well.