Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i.smap: fix possible pole error with log in extract function #4499

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ymdatta
Copy link
Contributor

@ymdatta ymdatta commented Oct 11, 2024

Using logarithm function call with zero argument will lead to a pole error, which occurs if the mathematical function has an exact infinite result.

Refactor the conditional to only execute the code when number of subclasses are more than 1, which would preemptively stop us from getting into situation where log would have a zero argument. In cases where number of subclasses are <= 0, set the default value to 0. This is necessary as ll points to malloc'd memory and can contain renadom value.

References:

[1] https://en.cppreference.com/w/c/numeric/math/log
[2] SEI CERT C Coding Standard

@github-actions github-actions bot added C Related code is in C module imagery labels Oct 11, 2024
@nilason nilason added this to the 8.5.0 milestone Oct 12, 2024
imagery/i.smap/model.c Outdated Show resolved Hide resolved
@nilason
Copy link
Contributor

nilason commented Oct 16, 2024

I gather this issue originates from cppcheck, this is the relevant part for this:

cppcheck imagery/i.smap/model.c
...
imagery/i.smap/model.c:158:43: warning: Invalid log() argument nr 1. The value is 0 but the valid values are '4.94066e-324:'. [invalidFunctionArg]
                        ll[i][j][m] = log(subsum) + maxlike;
                                          ^
imagery/i.smap/model.c:154:34: note: Assignment 'subsum=0', assigned value is 0
                        subsum = 0;
                                 ^
imagery/i.smap/model.c:155:39: note: Assuming condition is false
                        for (k = 0; k < C->nsubclasses; k++)
                                      ^
imagery/i.smap/model.c:158:43: note: Invalid argument
                        ll[i][j][m] = log(subsum) + maxlike;

The static analysis, takes the path where C->nsubclasses are 0, which leaves subsum with the initialised value of 0.0. log(0) return "-infinity and raise the "divide-by-zero" floating-point exception"1, which is the real issue here.

Now, in this branch of the if-else statement:

else {
/* find the most likely subclass */
for (k = 0; k < C->nsubclasses; k++) {
if (k == 0)
maxlike = subll[k];
if (subll[k] > maxlike)
maxlike = subll[k];
}
/* Sum weighted subclass likelihoods */
subsum = 0;
for (k = 0; k < C->nsubclasses; k++)
subsum += exp(subll[k] - maxlike) * C->SubSig[k].pi;
ll[i][j][m] = log(subsum) + maxlike;
}
}

there are two loops over C->nsubclasses which only does anything if C->nsubclasses > 1.

Wouldn't it better to change the else to a else if (C->nsubclasses > 1) on line 144, which guarantees that the for-loops are entered and the initialised value of subsum is altered?

Footnotes

  1. man 3 log

@ymdatta
Copy link
Contributor Author

ymdatta commented Oct 17, 2024

@nilason : I agree with your suggestion, it's a much cleaner way. Thanks!

I have modified the code to reflect that and I also added an else condition, which should cover the cases where nsubclasses <= 0 to set the value for ll to 0.0.

Using logarithm function call with zero argument will lead to
a pole error, which occurs if the mathematical function has
an exact infinite result.

Refactor the conditional to only execute the code when number
of subclasses are more than 1, which would preemptively stop
us from getting into situation where log would have a zero
argument. In cases where number of subclasses are <= 0, set
the default value to 0. This is necessary as `ll` points to
malloc'd memory and can contain renadom value.

Signed-off-by: Mohan Yelugoti <ymdatta.work@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C Related code is in C imagery module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants