(More) Math help needed!


#1

Hey!

Have been looking a bit into building a number sequencer, where I can enter a sned a variable in, like 1,2,3,4,5,6 and the result should be something like this:

1 1,2 1,2,3 1,2,3,4 1,2,3,4,5, 1,2,3,4,5,6, 1,2,3,4,5,6,7 1,2,3,4,5,6,7,8

And so on..... Every sequence is as long as the the amount of numbers in the sequence.
I tried all kinds of trick using modulo but I am out of ideas.

Everytime it has run through the sum of the numbers in the sequence, it adds another number to the sequence. I have googled it a bit but have not found anything that would work where I put in a variable in one end and i get the selected number of the above list out. I did try something using an array, but well, it very quickly sums up to a very large array, so it would be nice to be able to do it with a formula instead.

Does any one have suggestions to do the above?

Thanks!


#2

i don't get it, so you enter 1,2,3,4,5,6 (six numbers) but there are 8 sequences in your example afterwards...

or do you mean the steps you enter?

so for example

input:

3,2,1,7,6,5,4

output:
3
3,2
3,2,1
3,2,1,7
3,2,1,7,6
3,2,1,7,6,5
3,2,1,7,6,5,4


#3

Ahh sorry maybe i didnt explain it carefully, I m not even sure what, what I am trying to is called. So its hard looking it up, hehe :slight_smile:

Ill try again:
I input one variable at a time, fro example use an ctrl/i as an input. So if I input value , like 1,2,3,4,5,6,7 etc. The numbers should be converted into the list below.

If I input these value, with the ctrl/i, like we do with any other parameter in Axo:
1 2,3 4,5,6 7,8,9,10 10,11,12,13,14 15,16,17,18,19,20,
These values should come out.
1 1,2 1,2,3 1,2,3,4 1,2,3,4,5, 1,2,3,4,5,6,

My first try was using an array, but again it works but the array very quickly get very big. I also tried something using modulo and some dvisions, but that didnt work either.


#4

so you want to count how many numbers were inputted?

so you would have to set yourself an upper limit, and setup a buffer. then you will need a way to determine when new numbers come in, and when you want to count them.

i would initialise the whole array to a value that it cannot hold later (for example -1) and count all occurrences of non -1 values when you want to determine how many steps you need.


#5

Here is an example made with tables:

array numbers.axp (2.3 KB)

I tried yesterday with some patching using modulo and latch and some other tricks but it was a mess and didnt really work out well. The ones I saw on the web were all based on for-loops, so yeah I am thinking I might have to look into that. But I am starting to hink I am just going to use the table for now and think A bit more about it.

I am just think it must be possible to do this with a formula.


#6

local: int s,l,pSel;

k-rate:
if (param_Sel!=pSel){
pSel=param_Sel;
s=0;
l=1;
for (int i=1; i<=param_Sel;i++){
if (s<l){
s++;
}
else{
l++;
s=1;
}
}
}
outlet_l = l;
outlet_s = s;


#7

Thank you very much @Captain_Burek that worked out nicely :slight_smile:

I did a cycle counter test, it's alot more efficient than the table version, so this is great.

Can I ask where you got it from? Or if you just made it now, what is it called? So I can look it up? Thanks again!


#8

no name, just typed it up; i had important things to do and needed to procrastinate...(-;


#9

So I got another one for you guys, but I'll keep it in the same thread:

I am trying to make a POW function that works for int32_t values. This semi works, by that i mean it rounds the numbers to whole number, I cant use decimals, like 3.44 or similar. I know there will always be some rounding, but I could really use a couple of decimals, at least:

POW COM.axp (2.5 KB)

I tried without the bit shifting first, but without the bitshifting, the floats seems to be out of range. So I first bit shift >>21 to make the value smaller, and then at the end scale it back with <<21. But the problem is I get a rounded result:

Is there something in my algorithm that might cause that? I have used int32_t and float, which both allows use og decimals.

Any suggestions?


#10

don't shift, divide...by shifting right, you always loose resolution.


#11

Ahh yes, but which number should I divide with to get in the right range? I use shifting for other stuff and it keeps the decimals, even after shifting. But yeah, this is all still a bit new to me, so I might ne missing something obvious.

I tried yesterday dividing with 4194304, cause thats the same as shifting the value of one, 21 times. That didnt work.


#12

There's a lookup table based implementation in objects/math/exp.axo.
You should be using that - or something similar to it.

Other points:

1) If you want to convert fixed point to floating point you should use the proper conversion routines- these routines will retain as much of the fraction as practical given the formats.
q27_to_float and float_to_q27 are available - if you want to convert from/to some other fixed point format you'll need to write your own- take a look at the code - it's simple.

2) powf() - you probably shouldn't use it. The standard c math library favors accuracy over speed- you want speed, hence the author of the firmware provided a lookup table implementation which is fast- but not so accurate.

In summary - try to leverage the lookup table approach indicated in exp.axo.


#13
float inf1 = arm::q_to_float(inlet_i1, 21);
float inf2 = arm::q_to_float(inlet_i2, 21);
float test = powf(inf1, inf2);

outlet_k = (int32_t)(test * (1<<21));

would work as intended:

  • test is a float
  • (1<<21) is an int but, as it is involved in a multiplication with a float, it is automatically up casted to float.
  • the product test * (1<<21) is a float
  • it is casted back to int.

or you can use the intrinsic arm function:

outlet_k = arm::float_to_q(test, 21);

#14

Thanks guys, there are some things to try out here :slight_smile:

Its for a sampler algorithm, so Ill just see what I can get working and then see how important accuracy is.


#15

as @deadsy pointed out using floats and float functions (like powf) are expensive in terms of cpu cycles, so its going to affect your patch a lot if you use frequently... and in your current 'configuration' its going to hit on every k-rate cycle.
(you could test this yourself using the cpu cycle counter, so you get a feel for the extra load this causes)

also once it becomes an object, as its so easy to use, its becomes easy to forget its 'cost', and wonder why your 'simple' patch is quite costly.

perhaps, if you know the bounds of your inputs, you could perhaps pre-calculate the results at startup, and store in a table - meaning during 'audio time' your only doing a table look up.
(in a similar way to the way exp/pitch is done in the firmware)

of course this is not as flexible, and uses sdram but with a platform that has limited CPU like axoloti, there will always be a trade off, thats the nature of the beast.


#16

3 posts were merged into an existing topic: Using floats vs fixed point maths

mod note: I've moved this post, not because they were off-topic, but because i think there are some interesting observations, that are of more general interest than this topic (which is has a very broad title) ... and i dont think it 'disturbs' this thread too much


#17

The reasom I used powf, was because Johannes suggested it in another post over using just pow for Axoloti:

It is something that is going to be used only once pr patch, so I hope its going to be okay. I haven't had time to try it out yet.


#20

Yeah writing some modules for VCV rack was definately a lot easier , math vice, than doing it for Axoloti, cause you can keep it in "real world units", like samples, milliseconds, etc. Understanding bitshifting is kind of important for Axoloti. If you dont know how things should be build with "real world math" its even harder to make it in Axo world, because of all the bit shifting.


#21

Yay, I had time to try it out, it works. so now I just gotta build the rest of the structure to see if it works as supposed :slight_smile: