iOS alpha value of imageView failing comparison - iphone

Here's my code:
#define kDeselected .3
#define kSelected 1
- (void) selectButton:(UIImageView*)iconView{
[iconView setAlpha:kDeselected];
if(iconView.alpha == kDeselected){
[iconView setAlpha:kSelected];
}
else if(iconView.alpha == kSelected){
[iconView setAlpha:kDeselected];
}
}
I'm a pretty advanced programmer but it's beyond me as to why right before the if statement, when I manually went in and ensured that the if statement would result to true, it still doesn't hit it.
It should be noted that when kDeselected = .5, then it works perfectly. When it's .3 however...it doesn't like me.

Try casting your const to a float value as #define kDeselected 0.3f

It might be due to a compiler problem when casting your constant into a type
Try doing
CGFloat deselectedValue = kDeselected;
and see what it's value actually is, and try working with that:
- (void) selectButton:(UIImageView*)iconView{
CGFloat deselectedValue = kDeselected;
[iconView setAlpha:deselectedValue];
if(iconView.alpha == deselectedValue){
[iconView setAlpha:deselectedValue];
}
else if(iconView.alpha == kSelected){
[iconView setAlpha:kDeselected];
}
}
Your other option is to try and define your .3 as #define kDeselected 0.3f, however I doubt it'll make a difference if .5 works

I guess there is some limited precision in the storage of alpha in the iconView. It's probably returning 0.3334. Or thereabouts.
In image editing, it's rare to see an alpha value outside an 8-bit integer range. In fact, I don't think I've ever seen one.
I tried
for (int i = 0; i <100; i++) {
double myAlpha = 0.3 + i * 0.01;
self.view.alpha = myAlpha;
NSLog(#"myAlpha=%30.20f viewAlpha=%30.20f", myAlpha, self.view.alpha);
}
and saw
myAlpha= 0.29999999999999998890 viewAlpha= 0.30000001192092895508
myAlpha= 0.30999999999999999778 viewAlpha= 0.31000000238418579102
myAlpha= 0.32000000000000000666 viewAlpha= 0.31999999284744262695
myAlpha= 0.32999999999999996003 viewAlpha= 0.33000001311302185059
myAlpha= 0.33999999999999996891 viewAlpha= 0.34000000357627868652
so expecting the returned value of alpha to be anything other than an approximation looks like wishful thinking!

Related

How/When to update bias in RPROP neural network?

I am implementing this neural network for some classification problem. I initially tried back propagation but it takes longer to converge. So I though of using RPROP. In my test setup RPROP works fine for AND gate simulation but never converges for OR and XOR gate simulation.
How and when should I update bias for RPROP?
Here my weight update logic:
for(int l_index = 1; l_index < _total_layers; l_index++){
Layer* curr_layer = get_layer_at(l_index);
//iterate through each neuron
for (unsigned int n_index = 0; n_index < curr_layer->get_number_of_neurons(); n_index++) {
Neuron* jth_neuron = curr_layer->get_neuron_at(n_index);
double change = jth_neuron->get_change();
double curr_gradient = jth_neuron->get_gradient();
double last_gradient = jth_neuron->get_last_gradient();
int grad_sign = sign(curr_gradient * last_gradient);
//iterate through each weight of the neuron
for(int w_index = 0; w_index < jth_neuron->get_number_of_weights(); w_index++){
double current_weight = jth_neuron->give_weight_at(w_index);
double last_update_value = jth_neuron->give_update_value_at(w_index);
double new_update_value = last_update_value;
if(grad_sign > 0){
new_update_value = min(last_update_value*1.2, 50.0);
change = sign(curr_gradient) * new_update_value;
}else if(grad_sign < 0){
new_update_value = max(last_update_value*0.5, 1e-6);
change = -change;
curr_gradient = 0.0;
}else if(grad_sign == 0){
change = sign(curr_gradient) * new_update_value;
}
//Update neuron values
jth_neuron->set_change(change);
jth_neuron->update_weight_at((current_weight + change), w_index);
jth_neuron->set_last_gradient(curr_gradient);
jth_neuron->update_update_value_at(new_update_value, w_index);
double current_bias = jth_neuron->get_bias();
jth_neuron->set_bias(current_bias + _learning_rate * jth_neuron->get_delta());
}
}
}
In principal you don't treat the bias differently than before when you did backpropagation. It's learning_rate * delta which you seem to be doing.
One source of error may be that the sign of the weight change depends on how you calculate your error. There's different conventions and (t_i-y_i) instead of (y_i - t_i) should result in returning (new_update_value * sgn(grad)) instead of -(new_update_value * sign(grad)) so try switching the sign. I'm also unsure about how you specifically implemented everything since a lot is not shown here. But here's a snippet of mine in a Java implementation that might be of help:
// gradient didn't change sign:
if(weight.previousErrorGradient * errorGradient > 0)
weight.lastUpdateValue = Math.min(weight.lastUpdateValue * step_pos, update_max);
// changed sign:
else if(weight.previousErrorGradient * errorGradient < 0)
{
weight.lastUpdateValue = Math.max(weight.lastUpdateValue * step_neg, update_min);
}
else
weight.lastUpdateValue = weight.lastUpdateValue; // no change
// Depending on language, you should check for NaN here.
// multiply this with -1 depending on your error signal's sign:
return ( weight.lastUpdateValue * Math.signum(errorGradient) );
Also, keep in mind that 50.0, 1e-6 and especially 0.5, 1.2 are empirically gathered values so they might need to be adjusted. You should definitely print out the gradients and weight changes to see if there's something weird going on (e.g. exploding gradients->NaN although you're only testing AND/XOR). Your last_gradient value should also be initialized to 0 at the first timestep.

Cant rewrite variable after assigned as infinity Ansi C

I have double field ypos[] and in some cases instead of double is written into field -1.#INF00. I need to rewrite this values with 0.0, but i cant simply assign zero value, application falls everytime. Is there a way, how to solve this problem?
Please see http://codepad.org/KKYLhbkh for a simple example of how things "should work". Since you have not provided the code that doesn't work, we're guessing here.
#include <stdio.h>
#define INFINITY (1.0 / 0.0)
int main(void) {
double a[5] = {INFINITY, 1, 2, INFINITY, 4};
int ii;
for(ii = 0; ii < 5; ii++) {
printf("before: a[%d] is %lf\n", ii, a[ii]);
if(isinf(a[ii])) a[ii] = 0.0;
printf("after: a[%d] is %lf\n", ii, a[ii]);
}
return 0;
}
As was pointed out in #doynax 's comment, you might want to disable floating point exceptions to stop them from causing your program to keel over.
edit if your problem is caused by having taken a logarithm from a number outside of log's domain (i.e. log(x) with x<=0 ), the following code might help:
#include <stdio.h>
#include <signal.h>
#include <math.h>
#define INFINITY (1.0 / 0.0)
int main(void) {
double a[5] = {INFINITY, 1, 2, INFINITY, 4};
int ii;
signal(SIGFPE, SIG_IGN);
a[2] = log(-1.0);
for(ii = 0; ii < 5; ii++) {
printf("before: a[%d] is %lf\n", ii, a[ii]);
if(isinf(a[ii]) || isnan(a[ii])) a[ii] = 0.0;
printf("after: a[%d] is %lf\n", ii, a[ii]);
}
return 0;
}
You get a different value for log(0.0) (namely -Inf) and for log(-1.0) (namely nan). The above code shows how to deal with either of these.
A geuess that your problem is somewhere else. Can you write 0.0 before INF is written?
Sorry guys, I've solving this problem about 2 hours and tried to ask here but I've made a solution by comparing value of variable with -DBL_MAX. But thank you all for try.

how to add echo effect on audio file using objective-c

I am developing an application in which I want to add echo effect in recorded audio files using objective-c.
I am using DIRAC to add other effect e.g. man to women, slow, fast.
now I have to make Robot voice of recorded voice. for robot voice I need to add echo effect
Please help me to do this
Echo is pretty simple. You need a delay line, and little multiplication. Assuming one channel and audio already represented in floating point, a delay line would look something like this (in C-like pseudo-code):
int LENGTH = samplerate * seconds; //seconds is the desired length of the delay in seconds
float buffer[ LENGTH ];
int readIndex = 0, writeIndex = LENGTH - 1;
float delayLine.readNext( float x ) {
float ret = buffer[readIndex];
++readIndex;
if( readIndex >= LENGTH )
readIndex = 0;
return ret;
}
void delayLine.writeNext( float x ) {
buffer[ writeIndex ] = x;
++writeIndex;
if( writeIndex >= LENGTH )
writeIndex = 0;
}
Don't forget to initialize the buffer to all zeros.
So that's your delay line. Basic usage would be this:
float singleDelay( float x ) {
delayLine.writeNext(x);
return delayLine.readNext( x );
}
But you won't hear much difference: it'll just come out later. If you want to hear a single echo, you'll need something like this:
float singleEcho( float x, float g ) {
delayLine.writeNext(x);
return x + g * delayLine.readNext( x );
}
where g is some constant, usually between zero and one.
Now say you want a stream of echos: "HELLO... Hello... hello... h..." like that. You just need to do a bit more work:
float echo( float x, float g ) {
float ret = x + g * delayLine.readNext( x );
delayLine.writeNext( ret );
return ret;
}
Notice how the output of the whole thing is getting fed back into the delay line this time, rather than the input. In this case, it's very important that |g| < 1.
You may run into issues of denormals here. I can't recall if that's an issue on iOS, but I don't think so.

What are the likely causes of random crashes with cocos2d and how do I track them down?

I have an arcade style iPhone game that is built with Cocos2d-iPhone and works fine except that it randomly crashes for no apparent reason after an unpredictable amount of playing. Sometimes you can play several levels without a problem and others it crashes after a few seconds. There are a few common lines reported in XCode as usually EXC_BAD_ACCESS which would suggest a memory thing but the objects are all autorelease with extra retains and the crashes are very inconsistent. One thing that seems to fit is that as more is going on at once the likelihood of a crash increases which again suggests some memory issue but then there is no app memory warning fired.
Some example crash lines are:
if(gameGlobals.gameState == GAME_STATE_PAUSED) {...}
if(![hearts isKindOfClass:[CCSprite class]]) {...}
but both these lines have global objects that are fune for ages until the crash.
So, my question is really how do I go about tracking down the problem and are there any likely culprits?
Thanks.
UPDATE
I have been doing a bit of detective work and I at least have some consistency. I think that there are two things going on:
1) is that the maths used to detect a pixel perfect collision with an object with deletion of pixel data is cooking the CPU.
2) I have some zombie sprites and otherwise that are being released with out my realising.
When I add a bullet sprite I use:
CCSprite *bullet = [CCSprite spriteWithFile:#"bullet.png"];
bullet.tag = BULLET_TAG_GOODY;
bullet.position = ccp(player.position.x,50);
[self addChild:bullet];
[bullet runAction:[CCSequence actions:
[CCMoveTo actionWithDuration:2 position:ccp(player.position.x,320)],
[CCCallFuncN actionWithTarget:self selector:#selector(bulletMoveFinished:)],
nil]];
[bullets addObject:bullet];
And then I loop through the bullets array. At the moment it crashes saying that I am trying to access a deallocated instance.
So, 1) how do I set this up so my sprites don't get released? Is it a good idea to remove the autorelease from CCSprite?
2) What is the best way to detect bullets colliding with a space invaders style base attriting the sprite as it gets shot?
Currently:
if([self overlapBases: bullet.position.x :bullet.position.y :true]) {...}
-(bool)overlapBases :(GLfloat)x :(GLfloat)y :(bool)up {
// NSLog(#"overlapping - %f,%f",x,y);
if(y > 20 && y < 100) {
int bn = -1;
if(x > 28 && x < 118) {
bn = 0;
}
if(x>140 && x<230 ) {
bn = 1;
}
if(x>254 && x<343 ) {
bn = 2;
}
if(x>365 && x<453 ) {
bn = 3;
}
if(bn> -1) {
NSLog(#"overlapping - %f,%f",x,y);
// for (int ix = 0; ix < NUM_BASES; ix++) {
if (overLap(x, 2, aspeaker[bn].position.x, BASE_WIDTH * aspeaker[bn].scale)) {
if (overLap(y, 4, aspeaker[bn].position.y, BASE_HEIGHT * aspeaker[bn].scale)) {
NSLog(#"ix: %i, x: %f, y: %f",bn,x,y);
return [self fineCollision:bn :x :y :up];
}
}
}
}
return false;
}
-(bool)fineCollision :(GLuint)baseNum :(GLfloat)x :(GLfloat)y :(bool)up {
//convert bullet x and y passed in to this base coords
//check if solid
//if so, remove bits in gfx and array, return true
//else return false;
GLfloat bullx = (x - aspeaker[baseNum].position.x + BASE_WIDTH) / 2.0;
GLfloat bully = (y - aspeaker[baseNum].position.y + BASE_HEIGHT) / 2.0;
GLint testx = (GLint)bullx;
if ((testx < 0) | (testx >= BASE_WIDTH)) {
return false;
}
GLuint testy;
bool hit = false;
for (int iy = -2; iy < 2; iy++) {
testy = (GLint)(bully - iy);
if ((testy >= 0) & (testy < BASE_HEIGHT)) {
if (baseShape[baseNum][15 - testy][testx] > 0) {
if(showrm == YES) {
CCSprite *maskSprite = [CCSprite spriteWithFile:#"bullet-mask.png"];
[maskSprite setBlendFunc: (ccBlendFunc) {GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}];
maskSprite.position = ccp( x , y-(40+22-5) );
NSLog(#"sprite: %f",maskSprite.position.x);
NSLog(#"render mask: %f",rm.frameInterval);
[rm addSpriteMask:maskSprite];
[rm drawCurrent];
}
[self remove:testx :testy :baseNum :up];
GLuint seed = rand()%64;
if (seed & 1) {
[self remove:testx - 1:testy - 1 :baseNum :up];
}
if (seed & 2) {
[self remove:testx - 1:testy :baseNum :up];
}
if (seed & 4) {
[self remove:testx - 1:testy + 1:baseNum :up];
}
if (seed & 8) {
[self remove:testx + 1:testy - 1:baseNum :up];
}
if (seed & 16) {
[self remove:testx + 1:testy :baseNum :up];
}
if (seed & 32) {
[self remove:testx + 1:testy + 1:baseNum :up];
}
hit = true;
}
}
}
return hit;
}
- (void)remove:(GLint)offX :(GLint)offY :(GLuint)baseNum :(bool)up {
if ((offX < 0) | (offX >= BASE_WIDTH)) {
return;
}
if ((offY < 0) | (offY >= BASE_HEIGHT)) {
return;
}
baseShape[baseNum][15 - offY][offX] = 0;
}
bool overLap(GLfloat x1, GLfloat w1, GLfloat x2, GLfloat w2) {
GLfloat left1, left2;
GLfloat right1, right2;
GLfloat halfWidth1 = w1 * 0.5f;
GLfloat halfWidth2 = w2 * 0.5f;
left1 = x1 - halfWidth1;
left2 = x2 - halfWidth2;
right1 = x1 + halfWidth1;
right2 = x2 + halfWidth2;
if (left1 > right2) {
return false;
}
if (right1 < left2) {
return false;
}
return true;
}
For detection and a rendermask think using lots of sprites and their blend mode for the attrition.
Thanks.
UPDATE AGAIN :)
Ok, I found some Zombies!
Address Category Event Type RefCt Timestamp Size Responsible Library Responsible Caller
0 0x13a00e90 CCSprite Malloc 1 00:32.974.212 432 SpacedInvaders +[CCSprite spriteWithFile:]
1 0x13a00e90 CCSprite Autorelease <null> 00:32.974.235 0 SpacedInvaders +[CCSprite spriteWithFile:]
2 0x13a00e90 CCSprite Retain 2 00:32.974.546 0 SpacedInvaders -[CCArray insertObject:atIndex:]
3 0x13a00e90 CCSprite Retain 3 00:32.974.629 0 SpacedInvaders -[CCActionManager addAction:target:paused:]
4 0x13a00e90 CCSprite Retain 4 00:32.974.634 0 SpacedInvaders -[CCArray addObject:]
5 0x13a00e90 CCSprite Release 3 00:32.986.279 0 QuartzCore CA::Display::DisplayLink::dispatch(unsigned long long, unsigned long long)
6 0x13a00e90 CCSprite Release 2 00:33.074.889 0 SpacedInvaders -[CCArray removeObject:]
7 0x13a00e90 CCSprite Release 1 00:33.074.915 0 SpacedInvaders -[CCActionManager deleteHashElement:]
8 0x13a00e90 CCSprite Release 0 00:33.074.918 0 SpacedInvaders -[CCArray removeObject:]
9 0x13a00e90 CCSprite Zombie -1 00:33.074.939 0 SpacedInvaders -[GameLayer update:]
So what's going on here? I see that the retain count has gone too low but how do I avoid this. I assume I am doing something dumb btw.
Thanks.
The only way this line can crash
if(gameGlobals.gameState == GAME_STATE_PAUSED) {...}
is if gameGlobals is an Objective-C object that has already been deallocated.
If gameGlobals is a C struct, you would not see EXC_BAD_ACCESS because it is not a pointer.
If gameGlobals is a nil object, you would not see EXC_BAD_ACCESS because sending messages to nil is OK.
Your statement "the objects are all autorelease with extra retains" rings alarm bells to me because it suggests you don't really understand the memory management rules. Global objects that should live for the entire lifetime of the app, do not need to be autoreleased. You should just alloc it at the beginning and that's it. Alternatively, consider making your global objects properties of you app delegate.
If you still can't figure it out, the first part of ade's answer is the way to go (NSZombie), although the second part probably won't help. I doubt if your objects ever get to be nil.
It definitely sounds like memory problems to me. If it's a huge memory leak you also won't necessarily get a memory warning before.
Did you try profiling your game for leaks with XCode? If it is a memory problem you will see it when it crashes during profiling.
"objects are all autorelease" sounds like the likely cause. Autorelease takes effect when the UI "comes up for air" (control returns from the current UI event handling logic), and if you have an autoreleased variable you're expecting to continue to use after this, it's likely to have gone "poof" (though often you can use it for a time after, until the storage is reused).
Did you run the analyzer or any other tools?
If I've understood you correctly then "autorelease with extra retains" sounds like a problem (unless you also have extra releases), that could cause a leak leading to increased memory usage causing other objects to be released which you then subsequently try to access.
try enabling nszombies: How to enable NSZombie in Xcode?
also use nslog statements to trace when objects are null when you expect them to not be.
if you know of some if cases where you get crashes then maybe you can put a breakpoint in the else of a NULL check prior to that:
if(gameGlobals.gameState != NULL) {
if(gameGlobals.gameState == GAME_STATE_PAUSED) {...}
} else {
//break or nslog here
}
The first thing to realise is that there may be nothing wrong with the code where the EXC_BAD_ACCESSoccurs. However, it is worth investigating that particular object just in case. The first avenue to pursue is that one of those objects has been deallocated because it has not been retained sufficiently. So, yes, definitely enable Zombies as per other people's advice here.
Objects that are released may not be deallocated immediately. That's why theEXC_BAD_ACCESScan occur at weird times. The objects are only deallocated when the chunk of memory that they were using is no longer needed. Other objects would of course use the same chunk. So when that chunk becomes eligible for deallocation is out of your control as the developer. That's handled by the runtime.
Best thing is to first run the Analyzer, then run Instruments, profiling with the Leaks instrument.
There's a great explanation of all this, and point by point advice on tracking downEXC_BAD_ACCESSerrors on Lou Franco's site:
Understanding EXC_BAD_ACCESS

float + float = NAN

float jk = 7700; float ck = 8000; - if i do int jk; I get rim=0;
printf (asin(jk/10500)) = 1.57897 - for example
printf (asin(ck/9500)) = 0.87868 - for example
float rim;
rim= asin(jk/10500)+ asin(ck/9500);
printf("\n%f", rim) = nan
Why i get nan?
I don't believe your "for example". Because I don't believe in magic. If you have two valid floats both pretty small, then their sum is not a nan. So, my guess is this:
either |jk| > 10500 or |ck| > 9500. So you make asin with an invalid ( > 1.0 or < -1.0) argument and thus get a nan.
Or you have made another error. Please post a compilable runnable example which will print NAN
There's either something wrong with your code or something seriously wrong with the iphone. The following code:
#include<stdio.h>
#include<math.h>
int main (void) {
printf ("%f\n", asin(1));
printf ("%f\n", asin(0.5));
float rim;
rim = asin(1) + asin (0.5);
printf ("%f\n", rim);
return 0;
}
produces a more sensible:
1.570796
0.523599
2.094395
In other words, both your asin(0.5) and your sum are incorrect.
Are you sure that you didn't actually do something like:
rim = asin(1 + asin (0.5));
That will indeed give you NaN.
Update based on your added info:
Your code still works fine in my environment:
#include<stdio.h>
#include<math.h>
int main (void) {
float jk = 7700;
//jk = 7700/10500;
jk = jk/10500;
printf ("%f\n", asin(jk));
float hg = 8000;
hg = hg / 9500;
printf ("%f\n", asin(hg));
float rim;
rim = asin(jk) + asin (hg);
printf ("%f\n", rim);
return 0;
}
outputting:
0.823212
1.001175
1.824387
You'll notice I changed jk = 7700/10500 to jk = jk/10500 since the latter gave you 0 due to the integer division, but I don't get NaN in either case. You really need to post a complete program which shows the errant behaviour.
#include <stdio.h>
#include <math.h>
main()
{
float jk=7700, ck=8000;
printf ("\n%f",asin(jk/10500));
printf ("\n%f",asin(ck/9500));
float rim;
rim= asin(jk/10500)+ asin(ck/9500);
printf("\n%f", rim);// = nan
}
Output
0.823212
1.001175
1.824387
I think your code is right. The problem is the value of jk and ck.
You kown if |jk/temp|>1 or |ck/temp|>1, the return of asin(jk/temp) will be nan.
so try to make |jk/temp|<=1 and |ck/temp| <=1, I believe that the return will be ok.