What function can I use to change 0<x<1 to 1 and keep 0 at 0?

I’m working on a program that involves (somewhat tangentially) a very simplified version of mutation. A new cell inherits its rules from the cells around it, and is more likely to inherit a rule of more cells have it, but can still mutate against the majority rule. Here is the relevant line of code:

a=cell’s mutation rate
b=number of cells that constitute the majority position
c=number in the minority



if Math.random()<((a*c/(b+c))+(1-a)*b/(b+c))
      the cell has the majority rule


Now, if I want to have no mutation, it isn’t enough just to set the cell’s mutation rate at zero, because that just makes it harder. What formula can I use with the cell’s mutation rate that will make no difference if the rate is not zero, but ensure that inheritance is strictly deterministic if mutation is zero? In other words, I need f(0) to be 0, changing the left side to be less than the right (ensuring the majority rule), but f(x) 0<x<1 to be 1 (or any number, so long as they all produce the same one), so that it doesn’t increase the likelihood of mutation. Something like


Math.random()*mutation/mutation<etc.

, except that will produce a /0 error when mutation is 0.

Yes, I know, I can just write in a variable and explicitly define it with these characteristics, but I don’t want to mess with the code any more than I have to. Any takers?

I do some amateur programming, so this might not apply to whatever fancy program you are
writing, but anyway…

-Int(-X)

should do the trick, if your language has the Int function, which basically rounds DOWN no
matter what the decimal part is. If X = .27 say, flip the sign, apply the Int function, which will
make it -1, then just flip the sign back to positive.

I’m a moron. Upon examination of the Java API (since that’s the language I’m using), I found the signum function, which basically returns the sign of the argument: 0 for 0, 1 for positive. John’s method didn’t work, since Java’s various rounding functions, as far as I can tell, don’t work like that.

I’d still like to know if anyone can come up with a language-independent formula that can do this, because it beats the heck out of me.

And I am again shown to be too quick to post; I tried the ceil() function, which I thought would work and didn’t, but not the floor() function, which does. Thanks, John!

My question is technically answered, but it still seems like a cheap solution to me.

You can define your own function easily enough:


int sign(double x) {
  if (x > 0) return 1;
  if (x < 0) return -1;
  return 0;
}

There isn’t really an algebraic way to define it; you either have to find the value imperatively (by using an if statement or a special FPU operation), or rely on another function that finds it imperatively.

Won’t taking the square root a whole bunch of times work? SQRT(x) is closer to 1 than x for all positive, non-zero x. You could even define mutations to be an exponent of the form

x[sup]1/(2*int(rand *n))[/sup]

which would produce anything from a square root to a 1,024th root, and generate outputs between .9 and .999. If you can int() the output you’ll get what you want for sure.

The square root thing is interesting. Again, not what I was looking for, but it would work, modifying the random number by only a tiny fraction.

Off the top of my head, you could use the ceiling function, the Heaviside unit step function, or the signum function.

In C, you could just use:

x = (x != 0);

A good thought, but True and 1 aren’t quite the same thing in Java.

It might well work, but I have trouble coming up with an example of anything with remotely so high a resource to functionality ratio.

how about:

if (x=0) then {f(x):=0} else {f(x):= (x/x)};

which I still dont really like it because the division is a time sink, but not compared to multiple root extraction.

if (x=0) then {f(x):=0} else {f(x):= 1};

Is much better. compares and assignments take the least time of any operations…comparison to zero is often exceptionally fast.

I’m sure I botched the C syntax, as I can’t be bothered to dig out my K&R book, so think of it as pseudo code…I have only rarely programmed in high level languages.

Java does have a ternary operator, though:

x = (x == 0) ? 0 : 1;

I’m slightly confused. The RHS is clearly the probability of following the majority, but I’m not clear on how that’s supposed to behave in the limits as mutation rate goes to 0 and 1. You imply that it should be 1 when the mutation rate is zero, but instead it is b/(b+c). At the other end (when a=1), it is c/(b+c), which implies that the majority is more likely to be followed if there are more minority cells, which seems counterintuitive (and precisely backwards). It would make more sense to me if either the probability of following the majority was the fraction of majority cells or 0, in the case of a=1.

If you want the a=1 case to follow the majority in proportion to its frequency, then how about:



if (Math.random() < (1 - a*c/(b+c))) {
   // follow the majority
}


This formulation has the following properties:
[ul]
[li] If a = 0, the majority is always followed[/li][li] If a = 1, the majority is followed proportionally to its fraction of the total[/li][li] If 0<a<1, the majority is followed to a lesser and lesser extent, but never less than its fraction[/li][/ul]

Now, if, in the case of a mutation rate of 1, the minority is always followed, then I don’t see why the intermediate cases should (or could) depend on the majority/minority fractions at all. In that case, the simplest model is:



if (Math.random() < (1 - a)) {
   // follow the majority
}


This certainly has the right limiting behavior for the extremes of mutation rate, but doesn’t really feel like what you want.

Now, I could imagine one other case. In this formulation, a mutation rate of 0 implies that inheritence is relative to the fractions of b and c, and in the case of mutation rate of 1, always follow the minority. In that case, the expression becomes



if (Math.random() < ((1-a) * b/(b+c))) {
   // follow the majority
}


Do any of these sound more plausible, or am I missing something simple (which I concede is quite likely)?

-Rick

I think you are running into a common problem with programmers who have not been coding applications for long.

It is called ‘Premature Optimization’
You reckon that using a sneaky built in function will make your code in some way ‘better’.

Actually it will make it obscure, probably unreadable, and except for the most unusual circumstances the difference in speed will be unnoticeable.

As Mr2001 suggested, write a function that does exactly what you want, and is dead simple to read. Give it a meaningful name and use it instead of something that obfuscates your code.

The objective is to write simple code that works, and is easy to see how it works.

I think what you’re looking for is the ceil function. Hopefully, you can figure out how to actually apply it in Java, because I think the one Java class I took was in '99, and my memory is pretty damn foggy.

Aww…

I always liked the C code:

i = -(i < 0) | (i > 0);

Or for Java something arcane like…

i = (i >> 31) | (((i + 0x7fffffff) & 0x8000000) >>> 31); // think this works…

Heh !

This could mutate into a code obfuscation thread.

I realize you could read it that way, but I am just going to use the ceil() function in my actual program. As I said, all I’m interested in now is a way to do it sneakily inside the if statement, because I wanted to do it that way and it’s bugging me that I can’t figure it out.

Not quite. I’m saying that I want to mess with the LHS to make it 0 when mutation is 0, but otherwise not affect it. I know that’s not the way I’ve written it, and that’s why I started the thread. As for a=1, I’m not concerned about that; it’s pretty unlikely that any cell will reach 1 as its mutation rate. All I’m distinguishing between here is 0 and 0<x<1. (Hitting 1 is damn near impossible, since if the rate goes over one it’s trimmed to the decimal part [I think; I haven’t looked at the code for that part in a while])

Yeah, and what I want is that: it is possible for a cell to mutate if the random number cooperates, but if mutation is zero, then the majority should always rule, with no exceptions. As I said, I’m not really concerned with a mutation rate of 1.

Your last formula is almost right, but it only counts the chance that it will go with the majority and not mutate; I also need to keep track of the chance that it will follow the minority and mutate. There are four possibilities: combinations of following the majority/minority and of mutating/not mutating, and all four need to be accounted for in one of the two possible outcomes. The first and third formulas combined are essentially what I have now.