Storing functions in an array and applying them to an array of numbers - ios

I've prototyped an algorithm for my iOS game in Python, and I need to rewrite in in ObjC. Basically, I have a board of 16 numbers, and I want to loop through every number three times and the four functions I'm using (add, subtract, multiply, exponentiate). 1+2+3, 2*3-4, 3^4-5, 9-4^3, etc., but without order of operations (first operation is always done first).
What I would like is an overview of how this might be implemented in Objective-C. Specifically, what is the equivalent of an array of functions in Objective-C? Is there an easy way to implement it with selectors? What's the best structure to use for loops with numbers? Array of NSIntegers, array of ints, NSArray/NSMutableArray of NSNumbers?
import random as rand
min = 0
max = 9
max_target = 20
maximum_to_calculate = 100
def multiply(x, y):
return x * y
def exponate(x, y):
return x ** y
def add(x, y):
return x + y
def subtract(x, y):
return x - y
function_array = [multiply, exponate, add, subtract]
board = [rand.randint(min, max) for i in xrange(0, 16)]
dict_of_frequencies = {}
for a in board:
for b in board:
for first_fun in function_array:
first_result = first_fun(a, b)
for c in board:
for second_fun in function_array:
final_result = second_fun(first_result, c)
if final_result not in dict_of_frequencies:
dict_of_frequencies[final_result] = 0
dict_of_frequencies[final_result] += 1

The most convenient way in Objective-C to construct an array of functions would be to use Blocks:
typedef NSInteger (^ArithmeticBlock)(NSInteger, NSInteger);
ArithmeticBlock add = ^NSInteger (NSInteger x, NSInteger y){
return x + y;
};
ArithmeticBlock sub = ^NSInteger (NSInteger x, NSInteger y){
return x - y;
};
NSArray * operations = #[add, sub];
Since there's no great way to perform arithmetic on NSNumbers, it would probably be best to create and store the board's values as primitives, such as NSIntegers, in a plain C array. You can box them up later easily enough, if necessary -- #(boardValue) gives you an NSNumber.

If you want to do it with straight C function pointers, something like this will do it:
#include <stdio.h>
#include <math.h>
long add(int a, int b) {
return a + b;
}
long subtract(int a, int b) {
return a - b;
}
long multiply(int a, int b) {
return a * b;
}
long exponate(int a, int b) {
return pow(a, b);
}
int main(void) {
long (*mfunc[4])(int, int) = {add, subtract, multiply, exponate};
char ops[4] = {'+', '-', '*', '^'};
for ( int i = 0; i < 4; ++i ) {
printf("5 %c 9 = %ld\n", ops[i], mfunc[i](5, 9));
}
return 0;
}
and gives the output:
paul#MacBook:~/Documents/src$ ./rndfnc
5 + 9 = 14
5 - 9 = -4
5 * 9 = 45
5 ^ 9 = 1953125
paul#MacBook:~/Documents/src$
Function pointer syntax can be slightly convoluted. long (*mfunc[4])(int, int) basically translates to defining a four-element array, called mfunc, of pointers to functions returning long and taking two arguments of type int.

Maddy is right. Anyway, I'll give it a try just for the fun of it.
This has never seen a compiler. So please forgive me all the typos and minor syntax errors in advance.
#include <stdlib.h>
...
const int MIN = 0;
const int MAX = 9;
const int MAX_TARGET = 20;
const int MAX_TO_CALCULATE = 100;
...
- (int) multiply:(int)x with:(int)y { return x * y; }
- (int) exponate:(int)x with:(int)y { return x ^ y; }
- (int) add:(int)x to:(int)y { return x + y; }
- (int) substract:(int)x by:(int)y { return x - y; }
// some method should start here, probably with
-(void) someMethod {
NSArray *functionArray = [NSArray arrayWithObjects: #selector(multiply::), #selector(exponate::), #selector(add::), #substract(multiply::), nil]; // there are other ways of generating an array of objects
NSMutableArray *board = [NSMutableArray arrayWithCapacity:16]; //Again, there are other ways available.
for (int i = 0; i < 16; i++) {
[board addObject:#(arc4random() % (MAX-MIN) + MIN)];
}
NSMutableDictionary dictOfFrequencies = [[NSMutableDictionary alloc] init];
for (NSNumber a in board)
for (NSNumber b in board)
for (SEL firstFun in functionArray) {
NSNumber firstResult = #([self performSelector:firstFun withObject:a withObject:b]);
NSNumber countedResults = [dictOfFrequencies objectForKey:firstResult];
if (countedResults) {
[dictOfFrequencies removeObjectForKey:firstResult];
countedResults = #(1 + [countedResults intValue]);
} else {
countedResults = #1; // BTW, using the # followed by a numeric expression creates an NSNumber object with the value 1.
}
[dictOfFrequencies setObject:countedResults forKey:firstResult];
}
}
Well, let me add some comments before others do. :-)
There is no need for objective c. You python code is iterative therefore you can implement it in plain C. Plain C is available where ever Objective C is.
If you really want to go for Objective-C here then you should forget your python code and implement the same logic (aiming for the same result) in Objective-C in an OOP style. My code really tries to translate your code as close as possible. Therefore my code is far far away from neither beeing good style nor maintainable nor proper OOP. Just keep that in mind before you think, ObjC was complicated compared to python :-)

Related

vala: quotient of two integers is always an integer. Why?

Newbie question:
void main () {
int A = 1;
int B = 2;
double C = A / B;
stdout.printf("C value is: %g\n", C);
}
This prints: "C value is: 0"
void main () {
int A = 1;
double B = 2;
double C = A / B;
stdout.printf("C value is: %g\n", C);
}
This prints: "C value is: 0.5"
I don't understand the reason why the result is not 0.5 in both cases.
The division operation is performed on two integers, so the result is an integer. The fact that you assign it to a double afterwards doesn't change that.
What you're doing in your question, with the implicit conversions made explicit, is
int A = 1;
int B = 2;
double C = (double) (A / B);
However, if you want to perform the division operation using doubles you have to explicitly cast at least one of the operands to double:
int A = 1;
int B = 2;
double C = ((double) A) / B;
For the rules concerning arithmetic operations, see the arithmetic expressions section of the Vala Manaual. The relevant bit:
If both operands are of integer types, then the result will be the quotient only of the calculation (equivalent to the precise answer rounded down to an integer value.) If either operand is of a floating point type, then the result will be as precise as possible within the boundaries of the result type (which is worked out from the basic arithmetic type rules.)

Objective C multiply 2 int*

This code show this error Invalid operands to binary expression ('int*' and 'int*')
int *a = 5;
int *b = 3;
int *c = a*b;
How I can multiply them, and Why is this a error?
you are initializing int* with an int value. To multiply values and write them to another pointer, you should call the value of a stored in an address with (*a)
here is the example code for what you want to do:
int *a = malloc(sizeof(int));
int *b = malloc(sizeof(int));
int *c = malloc(sizeof(int));
*a = 2;
*b = 3;
*c = (*a)*(*b);
printf("%d %d %d", *a,*b,*c);
free(a);
free(b);
free(c);
it prints 2 3 6 as expected.
this is the C (primitive type) Integer type so you cannot declare with pointer.
Please find the below code :
int a = 5;
int b = 3;
int c = (a*b);
Thanks
Please remove asterisk symbol because int is a primitive data type not an object. You can put asterisk symbol with objects not primitive data types.
Asterisk symbol is pointer symbol from the C language.
int a = 5;
int b = 3;
int c = a*b;

conversion of decimal to binary output

I am facing problem with the objective c code to convert decimal to binary. When I enter small values it shows me the output.
For e.g. 12 -> 1010
But when I enters large numbers, it shows me the output as "10..." (includes dots in the output)
Please help me.
My program is as follows:
NSUInteger x = [newDec integerValue];
//int y[30];
int i=0;
int m =1;
while (x != 0) {
int mod = x % 2;
x /= 2;
i = i + mod * m;
m = m * 10;
string = [NSString stringWithFormat:#"%d", i];
}
There are two problems with your code.
1) Your label size is perhaps not able to accommodate your string. So check the length of it.
2) Your code will not support the conversion if value of x is large. The reason is that int has limited capacity. Check this question regarding memory size of in-built variable. So, consider making your string mutable and add 0s or 1s in it. I am attaching my snippet of code.
NSMutableString *string = [[NSMutableString alloc] init];
while (x != 0) {
int mod = x % 2;
x /= 2;
[string insertString:[NSString stringWithFormat:#"%d", mod] atIndex:0];
}
NSLog(#"String = %#", string);

How to create a random selector by custom number?

Traditionally if I wish to choose a case occurred 25%, I use "arc4random()%" function by integer to trigger the case of 1/4 chance.
Now I have 4 cases with float rate. Let's say,
A 0.3055
B 0.391
C 0.165
D 0.1485
A+B+C+D=1
How can I develop a random selector to trigger a case of 4 by properly selecting? Of course, case B gets the most chance to be selected.
Many thanks
I don't think this is perfect, but it'll get you close
int probability = arc4random_uniform(10000);
NSLog(#"Probability: %i", probability);
if (probability < 3055) {
// A
}
else if (probability <= (3055 + 3910)) {
// B
}
else if (probability <= (3055 + 3910 + 1650)) {
// C
}
else {
// D
}
By selecting with the appropriate probability from a uniform distribution.
int myOwnFunkyDistribution(void)
{
uint32_t A = 0.3055 * UINT32_MAX;
uint32_t B = A + 0.3910 * UINT32_MAX;
uint32_t C = B + 0.1650 * UINT32_MAX;
uint32_t r = arc4random();
if (r < A)
return 0;
if (r < B)
return 1;
if (r < C)
return 2;
return 3;
}
With more cases, this is definitely to be refactored using an array and a for loop.
You want to do a multinomial sample. You could do this in iOS with GSL or other C- or C++-based statistics libraries.

How to do classification manually parsing the support vectors from LibSVM model?

As much as I understand, I could parse the support vectors from the model produced by training with a set of data with LibSVM.
What would be the formula, to produce the classifier?
Do I need the data in the headers of the file, like the following (kernel etc...before the listed support vectors):
svm_type c_svc
kernel_type rbf
gamma 0.125
nr_class 4
total_sv 1038
rho -0.859244 -0.876628 -0.958343 0.543365 -1.10722 -1.79433
label 2 1 3 0
nr_sv 364 276 242 156
SV
My case is
I want to do classification from Node.JS. But there isn't any bindings for LibSVM for it, yet.
Since my models are not going to change, I would like to do the classification in Node.JS, holding the model in-memory.
If this proves to be slow, I rather write the same classification from scratch in C++ and create a wrapper module if it's only a matter of a simple computation (as I suspect it is).
Thanks.
You should be able to translate the C function to Javascript.
Here is the relevant code:
double svm_predict_values(const svm_model *model, const svm_node *x, double* dec_values)
{
int i;
int nr_class = model->nr_class;
int l = model->l;
double *kvalue = Malloc(double,l);
for(i=0;i<l;i++)
kvalue[i] = Kernel::k_function(x,model->SV[i],model->param);
int *start = Malloc(int,nr_class);
start[0] = 0;
for(i=1;i<nr_class;i++)
start[i] = start[i-1]+model->nSV[i-1];
int *vote = Malloc(int,nr_class);
for(i=0;i<nr_class;i++)
vote[i] = 0;
int p=0;
for(i=0;i<nr_class;i++)
for(int j=i+1;j<nr_class;j++)
{
double sum = 0;
int si = start[i];
int sj = start[j];
int ci = model->nSV[i];
int cj = model->nSV[j];
int k;
double *coef1 = model->sv_coef[j-1];
double *coef2 = model->sv_coef[i];
for(k=0;k<ci;k++)
sum += coef1[si+k] * kvalue[si+k];
for(k=0;k<cj;k++)
sum += coef2[sj+k] * kvalue[sj+k];
sum -= model->rho[p];
dec_values[p] = sum;
if(dec_values[p] > 0)
++vote[i];
else
++vote[j];
p++;
}
int vote_max_idx = 0;
for(i=1;i<nr_class;i++)
if(vote[i] > vote[vote_max_idx])
vote_max_idx = i;
free(kvalue);
free(start);
free(vote);
return model->label[vote_max_idx];
}
Notice that you have to recreate this equation:
The only difference is since your model has 4 classes, you need to implement the vote system which is basically the code above.
Hope it helps.

Resources