exponential scaling problem
i have a value form 0 to 2047 and i want it to be scaled from 0.375 to 0.375 with 5 in the middle. so 0 to 1024 is scaled 0.375 to 5 and 1024 to 2047 is scaled 5 to 0.375.
the patch below shows what i made for this.
the problem is i want it to be exponentially scaled but i can't scale it like i want with scales optional exponential value argument.
i want it exponentially scaled so that the middle of 0 to 1024 (512) is 1 and also the middle of 1024 to 2047 (1536) is 1.
is there a way of smoothly doing this?
Something like this! I found 2.321928 by working backwards (as you can see on the right side of the patch) rather than being clever and doing all the maths. Then it's just a case of scaling the values to fit your input and output. You could probably do it all in one [expr] with clever use of ($f1>1024) but using split is much easier.
lh
Or if you want it all in one go try:
[expr pow(((($f1>1024)*2048)-(($f1>1024)*2-1)*$f1)/1024,2.321928)*5.]
lh
i have abstractions for that, but they are not 100% perfect,
so they might have to be updated one day.
it is a bit complicated:
you first have to split the input range, then do the exponential scaling for both sides.
and for a maximum of security and flexibilty you should only
use > and < and pass/map the center number directly to the
new center value (this is the part which is currently not
done perfectly in my patches, the center comes out double.
this doesn matter when remoted from a GUI object, but it
starts to matter when you input gereric floating point numbers).
[110.makepow.mxb]
[110.makeexp.mxb]
[110.makelog.mxb]
[110.maketanh.mxb]
[110.makeexp-.mxb]
[110.makelog-.mxb]
[110.maketanh-.mxb]
[110.makeexp-bipolar.mxb]
[110.makelog-bipolar.mxb]
[110.maketanh-bipolar.mxb]
[110.makeexp-bipolar-.mxb]
[110.makelog-bipolar-.mxb]
[110.maketanh-bipolar-.mxb]
enjoy,
-110
.....
thanks lh, it works precisely like i want. but i don't understand what's happening in the expr objects, i've never done much with them.
could you please explain slowly what happens in the rightmost expr object of the patch your posted as well as the ones you used for the actual scaling? i would like to learn that so i can try using 8 or another value in the middle.
thanks for your abstractions roman but they look way too complicated for me, i have very little time so i can't take time to figure them out.
i also would like to know what i should do tho get one more close to the middle. for instance instead of 1 @ 512, 1 @ 768.
I hate to bring up Litter Power again, but this is ridiculously easy to do with lp.scampf in any of its symmetry modes.
Create a [lp.scampf map 0 2047 5. 0.375 pow 1.] object, send it the message 'sym 2', and your values will map like the enclosed picture. Send a number to the last inlet (or edit the last argument) for a more or less steep curve. Use exp instead of pow for true exponential shapes (although most people actually want the power curves).
lp.scampf an lp.scampi are two of the most handy little utilities in the (free) Starter Pack, if I do say so myself. Max 5 doesn't like the .help files in the Starter Pack a lot, but the objects themselves work on 5. The Pro Bundle is fully Max 5-compatible.
Hope this helps,
Peter
--
Edit: fixed silly typo, embedded image (didn't know you could do that before!)
Right well if you have a simple [expr pow($f1,$f2)] and the base (first inlet) is limited to being between 0 and 1 then as long as the exponent (second inlet) is >0 the outlet will also always between 0 and 1 also.
In your case you we set the base to 0.5, this is because 512 is half of the range 0 to 1024. We also want the result to be 0.2 becuase 1 is a fifth of the range 0 to 5. I worked it out by setting the base to 0.5 and gradually increasing the exponent until the answer was 0.2.
If I was being clever and awake I would have worked it out using logarithms.
If a^b = c then b = log a of c.
(Either trust me or look it up in a textbook!) However we only have log10 available to use in [expr] so we use another rule of logarithms that states:
If b = log a of c then b = (log10 of c)/(log10 of a)
Put that in an [expr] where a=0.5 and c=0.2 and you get b=2.321928
Now we've calculated the exponent we just need to scale the input and output to get it into your desired range. This is where the /1024 and *5 come in. Put them all together and you get [expr pow($f1/1024,2.321928)*5.]. Simply change the scaling for when the input is >1024 and feed this half of the claculation using [split] and you arrive back at my orignal patch.
And if you're being really clever then use conditional operators in [expr] so that you don't have to use [split] and two seperate scaling equations. I won't explain this bit as I think what I have already is confusing enough.
lh
thank very much you for explaining.
i don;t get everything you say but after looking up some things tomorrow (it's quite late @ night over here) i probably will.
but what does the [expr pow($f1,$f2]actually mean? i figured out pow is something like ^ (don't know how to call that in english) but it's not the same. what does it actualy do?
and what does , mean?
It calculates powers: pow(a,b) The first number in the brackets is the base and the second is the exponent. In shorthand typing its usually shown as a^b which is "a to the power (of) b". For example:
4^2 is four squared which means 4x4 which is 16.
5^3 is five cubed which means 5x5x5 which is 125.
2^8 is two to the power 8 which means 2x2x2x2x2x2x2x2 which is 256.
And an inverse function:
64^(1/2) is the square root of 64 which is 8 because 8x8=64.
27^(1/3) is the cube root of 27 which is 3 because 3x3x3=27.
128^(1/7) is the seventh root of 128 which is 2 because 2x2x2x2x2x2x2=128.
It should be shown as I typed above: pow(a,b) but the comma is a reserved character in max so it has to be escaped with the backslash hence we get [expr pow(a,b)]. I hope that clears things up a bit better.
lh
that clears all up.
thank you very much for explaining everything so extensively!
Not a problem, I always find it a bit easier to learn from exploring examples rather than just reading the theory, especially with maths related stuff.
lh
nit wrote on Wed, 29 July 2009 01:50
but what does the [expr pow($f1,$f2]actually mean? i figured out pow is something like ^ (don't know how to call that in english) but it's not the same. what does it actualy do?
and what does , mean?
the main problem is that if you do not have the time to
find out what "pow" is (for example by entering it as
search term into google.com), you should give up doing
anything with a programming language asap.
this stuff really only works when you are willing to invest
some time.
i dont even have visited a highschool and i found out the
above methods by trial and error, i would exspect that from
anyone who is currently writing a project for his phd, too.
otherwise it is no wonder why there are so many professors
out there who dont know shite about their own topic.
i have a gig this friday and because i'm busy re-programming the core element of my patch (because there are some bugs in the old version caused by new funtions) and i came across more 'trial and error' then expected along the way i have still pretty much to do and therefore not much time.
telling me i should stop using a programming language because you assumed i'm lazy after reading a forum post is a bit lame.
nit wrote on Wed, 29 July 2009 03:44i have a gig this friday and because i'm busy re-programming
the core element of my patch
i just thought that typing "pow" into google could have been
possible. but well.
you know what is good about expr? it has a lenght limit, so
noone must be afraid of too long formulas.
i just adopted tihfu´s idea to have comparison operators
inside the [expr] and implemented those and also the [mean]
of the input range into my formula from the [110.makeexp-bipolar] object.
the object now consists only of one single expression
and 4 default arguments.
this expression now reads like that:
[expr
(((exp((($f1-$f2)/((($f2+$f3)/2.)-$f2))*log($f4))-1)/($f4-1)*
((($f2+$f3)/2.)-$f2))+$f2)*($f1(($f2+$f3)/2.))+($f1+0.)*($f1==(($f2+$f3)/2.))]
and guess what, the shit is too long, so you cannot write it like that in [expr], LOL!
now i have to split it somewhere, maybe it is enough to take
the means "(($f2+$f3)/2.))" out, we´ll see.
-110
.