BLE (iBeacons) Trilateration - objective-c

I'm a student at the University of Furtwangen in Germany.
I am in my final term and I am writing my thesis now. I'm very interested in iBeacons and the technology behind them. My current project is to compare the beacon technology with other technologies like GPS, Wireless-location, GSM, and NFC. For my thesis, I will create different use-cases and compare the results.
Over the last few days I've tried to determine my position in a room. I use the relative distance (accuracy) from three beacons and gave every beacon a fixed position in my room.
I get three circles and calculate 6 intersections.
When a radian (accuracy) is too low I increase this value artificially. Then I look which of the 6 points (intersections) are the nearest. (The three nearest points)
With those points I get an triangle, and with this I calculate the middle point.
My problem is that the result is not really the best.
I found a better solution here:
https://gis.stackexchange.com/questions/40660/trilateration-algorithm-for-n-amount-of-points
but I have am having trouble implementing this in Objective C.
But I understand the solution. How can I import or get this in Objective C.
I found some libs (C, C++) but I'm not really sure which of these libs is the best.
The best solution for me will be a Objectice C math library which can calculate with these points (x1,x2,x3, -- ,y1,y2,y3, --- ,r1,r2,r3).
Graphic of my calculation now

I was struggling with the same problem, then I found this solution, written in python. I tried porting the code into objective-c and using the same case for testing and the result is accurate. I modified the code so it can accept 2-dimension vector as well.
The test case was :
P1 = (3,0) r1 = 6.4031
P2 = (9,0) r2 = 4.1231
P3 = (4,8) r3 = 5.6568
I ran this data through the code :
//P1,P2,P3 is the point and 2-dimension vector
NSMutableArray *P1 = [[NSMutableArray alloc] initWithCapacity:0];
[P1 addObject:[NSNumber numberWithDouble:3]];
[P1 addObject:[NSNumber numberWithDouble:0]];
NSMutableArray *P2 = [[NSMutableArray alloc] initWithCapacity:0];
[P2 addObject:[NSNumber numberWithDouble:9]];
[P2 addObject:[NSNumber numberWithDouble:0]];
NSMutableArray *P3 = [[NSMutableArray alloc] initWithCapacity:0];
[P3 addObject:[NSNumber numberWithDouble:4]];
[P3 addObject:[NSNumber numberWithDouble:8]];
//this is the distance between all the points and the unknown point
double DistA = 6.4031;
double DistB = 4.1231;
double DistC = 5.6568;
// ex = (P2 - P1)/(numpy.linalg.norm(P2 - P1))
NSMutableArray *ex = [[NSMutableArray alloc] initWithCapacity:0];
double temp = 0;
for (int i = 0; i < [P1 count]; i++) {
double t1 = [[P2 objectAtIndex:i] doubleValue];
double t2 = [[P1 objectAtIndex:i] doubleValue];
double t = t1 - t2;
temp += (t*t);
}
for (int i = 0; i < [P1 count]; i++) {
double t1 = [[P2 objectAtIndex:i] doubleValue];
double t2 = [[P1 objectAtIndex:i] doubleValue];
double exx = (t1 - t2)/sqrt(temp);
[ex addObject:[NSNumber numberWithDouble:exx]];
}
// i = dot(ex, P3 - P1)
NSMutableArray *p3p1 = [[NSMutableArray alloc] initWithCapacity:0];
for (int i = 0; i < [P3 count]; i++) {
double t1 = [[P3 objectAtIndex:i] doubleValue];
double t2 = [[P1 objectAtIndex:i] doubleValue];
double t3 = t1 - t2;
[p3p1 addObject:[NSNumber numberWithDouble:t3]];
}
double ival = 0;
for (int i = 0; i < [ex count]; i++) {
double t1 = [[ex objectAtIndex:i] doubleValue];
double t2 = [[p3p1 objectAtIndex:i] doubleValue];
ival += (t1*t2);
}
// ey = (P3 - P1 - i*ex)/(numpy.linalg.norm(P3 - P1 - i*ex))
NSMutableArray *ey = [[NSMutableArray alloc] initWithCapacity:0];
double p3p1i = 0;
for (int i = 0; i < [P3 count]; i++) {
double t1 = [[P3 objectAtIndex:i] doubleValue];
double t2 = [[P1 objectAtIndex:i] doubleValue];
double t3 = [[ex objectAtIndex:i] doubleValue] * ival;
double t = t1 - t2 -t3;
p3p1i += (t*t);
}
for (int i = 0; i < [P3 count]; i++) {
double t1 = [[P3 objectAtIndex:i] doubleValue];
double t2 = [[P1 objectAtIndex:i] doubleValue];
double t3 = [[ex objectAtIndex:i] doubleValue] * ival;
double eyy = (t1 - t2 - t3)/sqrt(p3p1i);
[ey addObject:[NSNumber numberWithDouble:eyy]];
}
// ez = numpy.cross(ex,ey)
// if 2-dimensional vector then ez = 0
NSMutableArray *ez = [[NSMutableArray alloc] initWithCapacity:0];
double ezx;
double ezy;
double ezz;
if ([P1 count] !=3){
ezx = 0;
ezy = 0;
ezz = 0;
}else{
ezx = ([[ex objectAtIndex:1] doubleValue]*[[ey objectAtIndex:2]doubleValue]) - ([[ex objectAtIndex:2]doubleValue]*[[ey objectAtIndex:1]doubleValue]);
ezy = ([[ex objectAtIndex:2] doubleValue]*[[ey objectAtIndex:0]doubleValue]) - ([[ex objectAtIndex:0]doubleValue]*[[ey objectAtIndex:2]doubleValue]);
ezz = ([[ex objectAtIndex:0] doubleValue]*[[ey objectAtIndex:1]doubleValue]) - ([[ex objectAtIndex:1]doubleValue]*[[ey objectAtIndex:0]doubleValue]);
}
[ez addObject:[NSNumber numberWithDouble:ezx]];
[ez addObject:[NSNumber numberWithDouble:ezy]];
[ez addObject:[NSNumber numberWithDouble:ezz]];
// d = numpy.linalg.norm(P2 - P1)
double d = sqrt(temp);
// j = dot(ey, P3 - P1)
double jval = 0;
for (int i = 0; i < [ey count]; i++) {
double t1 = [[ey objectAtIndex:i] doubleValue];
double t2 = [[p3p1 objectAtIndex:i] doubleValue];
jval += (t1*t2);
}
// x = (pow(DistA,2) - pow(DistB,2) + pow(d,2))/(2*d)
double xval = (pow(DistA,2) - pow(DistB,2) + pow(d,2))/(2*d);
// y = ((pow(DistA,2) - pow(DistC,2) + pow(i,2) + pow(j,2))/(2*j)) - ((i/j)*x)
double yval = ((pow(DistA,2) - pow(DistC,2) + pow(ival,2) + pow(jval,2))/(2*jval)) - ((ival/jval)*xval);
// z = sqrt(pow(DistA,2) - pow(x,2) - pow(y,2))
// if 2-dimensional vector then z = 0
double zval;
if ([P1 count] !=3){
zval = 0;
}else{
zval = sqrt(pow(DistA,2) - pow(xval,2) - pow(yval,2));
}
// triPt = P1 + x*ex + y*ey + z*ez
NSMutableArray *triPt = [[NSMutableArray alloc] initWithCapacity:0];
for (int i = 0; i < [P1 count]; i++) {
double t1 = [[P1 objectAtIndex:i] doubleValue];
double t2 = [[ex objectAtIndex:i] doubleValue] * xval;
double t3 = [[ey objectAtIndex:i] doubleValue] * yval;
double t4 = [[ez objectAtIndex:i] doubleValue] * zval;
double triptx = t1+t2+t3+t4;
[triPt addObject:[NSNumber numberWithDouble:triptx]];
}
NSLog(#"ex %#",ex);
NSLog(#"i %f",ival);
NSLog(#"ey %#",ey);
NSLog(#"d %f",d);
NSLog(#"j %f",jval);
NSLog(#"x %f",xval);
NSLog(#"y %f",yval);
NSLog(#"y %f",yval);
NSLog(#"final result %#",triPt);
I've tested by drawing on cartesian diagram using the test case data above, and got the result that the unknown point is located at (8,4), then testing using the code above and got the result (7.999978,4.000021710625001).
Then I did a second test using data :
P1 = (2,0) r1 = 5.831
P2 = (8,0) r2 = 5.831
P3 = (8,10) r3 = 5.831
The manual result is (5,5), and the result using the code is (5,5).
So, I believe the code is correct.

Related

myArray count isn't functioning as expected

The arrayTwelveLEngth variable isn't working as expected. When I placed a breakpoint on the amount = 1; line above, I hovered over arrayTwelve, and found that it was empty with 0 elements. Immediately after, I then hovered about arrayTwelveLength, expecting to see 0, but instead it seems that the arrayTwelveLength had a value of 1876662112. I don't know how it got that value, and I need to solve that problem. What am I doing wrong?
NSMutableArray *redValues = [NSMutableArray array];
NSMutableArray *arrayTwelve = [NSMutableArray array];
__block int counter = 0;
__block NSInteger u;
NSUInteger redValuesLength = [redValues count];
__block int arrayTwelveLength = 0;
__block float diffForAverage, fps, averageTime, bloodSpeed;
float average;
__block int amount = 1;
__block float totalTwelve, totalThirteen;
__block NSUInteger totalNumberOfFramesInSmallArrays = 0;
__block NSUInteger totalNumberOfFramesNotInSmallArrays;
for (u = (counter + 24); u < (redValuesLength - 24); u++)
{
diffForAverage = average - [redValues[u + 1] floatValue];
float test = [redValues[u] floatValue];
arrayTwelveLength = [arrayTwelve count];
if (diffForAverage > -1 && diffForAverage < 1)
{
totalTwelve += [redValues[u + 1] floatValue];
amount++;
[arrayTwelve addObject:#(test)];
counter++;
}
else
{
if (arrayTwelveLength >= 8)
{
counter++;
break;
}
else
{
[arrayTwelve removeAllObjects];
totalTwelve = [redValues[u + 1] floatValue];
counter++;
amount = 1;
}
}
}
amount = 1; // I added a breakpoint here
totalThirteen = [redValues[u + 1] floatValue];
average = totalThirteen / amount;
if (counter == redValuesLength)
{
totalNumberOfFramesNotInSmallArrays = redValuesLength - totalNumberOfFramesInSmallArrays - 25 - (redValuesLength - counter);
fps = redValuesLength / 30;
averageTime = totalNumberOfFramesNotInSmallArrays / fps;
bloodSpeed = 3 / averageTime;
[_BloodSpeedValue setText:[NSString stringWithFormat:#"%f", bloodSpeed]];
}
if (arrayTwelveLength == NULL)
{
arrayTwelveLength = 0;
}
totalNumberOfFramesInSmallArrays += arrayTwelveLength;
You have problems with unsigned/signed types and with your data set the first for loop should not even enter, because your for loop index variable u (== 24) < (redValuesLength (== 0) - 24) but, because redValuesLength being Unsigned type it wraps around and you get:
(unsigned long)0 - (unsigned long)24 = -24 modulo ULONG_MAX + 1= 18446744073709551592
Also, you are not initialising average before usage.

Reg locationmanager: didUpdateLocation

Hi !!
I am new to Objective-C.
I am developing a tracker application, in which I have to store all the gps coordinates and then analyse them to track the path in which the vehicle was. I am using two arrays for storing the latitude and longitude points. When trying to use the Latitude points for calculations later, its giving me an error saying "Out of bound exception at index 1", but the size of the array is being shown to me as 4. Here is the code snippet of my ViewController.h, please take a look and let me know how I do this.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[trackingMapView addPoint:newLocation];
float time = -[startDate timeIntervalSinceNow];
displayLabel.text = [NSString stringWithFormat:#"Speed: %.02f mph", distance * 2.2369 / time];
// if there was a previous location
if (oldLocation != nil)
{
// add distance from the old location tp the total distance
distance += [newLocation getDistanceFrom:oldLocation];
}
// create a region centered around the new point
MKCoordinateSpan span = MKCoordinateSpanMake(0.005, 0.005);
// create a new MKCoordinateRegion centered around the new location
MKCoordinateRegion region = MKCoordinateRegionMake(newLocation.coordinate, span);
//New Added Code
CLLocationSpeed speed = newLocation.speed ;
speed = speed * 2.2369 ;
/* if (speed > 10.000)
{
NSString *message = #"Slow Down !!" ;
UIAlertView *alertforspeed = [[UIAlertView alloc] initWithTitle:#"Speed Monitor" message: message delegate:self cancelButtonTitle:#"Return" otherButtonTitles:nil];
[alertforspeed show];
[alertforspeed release];
}*/
//NEW CODE 2
//----------------------------------------------
arraywithlat= [[NSMutableArray alloc]init];
arraywithlong= [[NSMutableArray alloc]init];
NSNumber *lati = [NSNumber numberWithFloat:newLocation.coordinate.latitude];
NSNumber *longi = [NSNumber numberWithFloat:newLocation.coordinate.longitude];
[arraywithlat addObject:lati];
[arraywithlong addObject:longi];
//[locations addObject:newLocation];
NSLog(#"Array with lat : %#" , arraywithlat);
NSLog(#"Array with long: %#", arraywithlong);
//-----------------------------------------------
int i;
float r1 = 0.0, r2, result ;
NSLog(#"IN LANE TRACKING, BEFORE IFF");
int exsize = sizeof(arraywithlat);
NSLog(#"SIze of array before the loop: %d", exsize);
if (sizeof(arraywithlat) >= 4) {
NSLog(#"CROSSED THE IFFFFF");
NSLog(#"SIXE OF ARRAYWITHLAT: %lu" , sizeof(arraywithlat));
for (i = 0; i <= sizeof(arraywithlat); i++) {
NSNumber *tla1 = [arraywithlat objectAtIndex:i];
float temp1 = [tla1 floatValue];
NSLog(#"temp111111111: %f",temp1);
NSNumber *tla2 = [arraywithlat objectAtIndex:i+1] ;
float temp2 = [tla2 floatValue];
float r1 = temp1 - temp2 ;
// float r1 = [NSNumber numberWithFloat:tla2] - [NSNumber numberWithFloat:tla1];
//float r1 = [tla2 floatValue] - [tla1 floatValue];
r1 = r1 * r1 ;
//float tla = arraywithlat objectAtIndex: i+1) - (arraywithlat objectAtIndex: i);
//float tlo = [arraywithlong obj]
// float tr1 = powf(((arraywithlat objectAtIndex:(i+1))-([arraywithlat objectatIndex:(i)])), <#float#>)
}
}
NSLog(#"r1 after cal: %f",r1);
// reposition the map t show the new point
[mapView setRegion:region animated:YES];
}
I think your problem is here:
for (i = 0; i <= sizeof(arraywithlat); i++) {
NSNumber *tla1 = [arraywithlat objectAtIndex:i];
float temp1 = [tla1 floatValue];
NSLog(#"temp111111111: %f",temp1);
NSNumber *tla2 = [arraywithlat objectAtIndex:i+1] ;
float temp2 = [tla2 floatValue];
float r1 = temp1 - temp2 ;
// float r1 = [NSNumber numberWithFloat:tla2] - [NSNumber numberWithFloat:tla1];
//float r1 = [tla2 floatValue] - [tla1 floatValue];
r1 = r1 * r1 ;
//float tla = arraywithlat objectAtIndex: i+1) - (arraywithlat objectAtIndex: i);
//float tlo = [arraywithlong obj]
// float tr1 = powf(((arraywithlat objectAtIndex:(i+1))-([arraywithlat objectatIndex:(i)])), <#float#>)
}
first indexes in array starts from 0 to n-1, so i <= sizeof(arraywithlat) here wrong, i < sizeof(arraywithlat) should be.
And NSNumber *tla2 = [arraywithlat objectAtIndex:i+1] is wrong. change it, coz when i will be equal to n-1 then you get exception out of bound. And can you explain what does this loop, may be we help you to rewrite it
Also note that - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation method of delegate is deprecated. Use locationManager:didUpdateLocations: instead.

Doesn't draw my grid properly in objective C

I have a problem with counting my module. I am doing the following.
- (void)makeGrid:withData:(NSDictionary * )data
{
NSLog(#"aantal is: %d",[data count]);
int xStart = 0;
int yStart = 0;
int xCurrent = xStart;
int yCurrent = yStart;
int xStepSize = 165;
int yStepSize = 251;
int xCnt = 3 ;
int yCnt = [data count] % 3;
int cellCounter = 0;
UIView * gridContainerView = [[UIView alloc] init];
[keeperView addSubview:gridContainerView];
for (int y = 0; y < yCnt; y++) {
for (int x = 0; x < xCnt; x++) {
printf("xCurrent %d yCurrent %d \n", xCurrent, yCurrent);
NSString *url1 = #"player_imgUrl";
NSString *url2 = [NSString stringWithFormat:#"%i", x];
NSString *url3 = [url1 stringByAppendingString:url2];
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[data objectForKey:url3]]];
UIImage* myImage = [[UIImage alloc] initWithData:imageData];
UIImageView * myView = [[UIImageView alloc] initWithImage:myImage];
CGRect rect = myView.frame;
rect.origin.x = xCurrent;
rect.origin.y = yCurrent;
myView.frame = rect;
myView.tag = cellCounter;
[gridContainerView addSubview:myView];
//just label stuff
UILabel * myLabel = [[UILabel alloc] init];
[gridContainerView addSubview:myLabel];
//--------------------------------
xCurrent += xStepSize;
cellCounter++;
}
xCurrent = xStart;
yCurrent += yStepSize;
}
CGRect repositionRect = gridContainerView.frame;
repositionRect.origin.y = 100;
gridContainerView.frame = repositionRect;
}
My NSLog says that in my data object are 16 values. And when I run it, it only shows 3 imageviews. Does anybody know what I am doing wrong?
Please help,
Kind regads.
After reading your code, the number of imageviews should be (xCnt * yCnt).
Your problem is here:
int yCnt = [data count] % 3;
the yCnt is 1 when your data is 16, that's why your result is 3 imageviews only.
to overcome this issue, you should do the following:
yCnt = (data.count / xCnt) + 1;
for (int y = 0 ; y < yCnt; y++)
{
for (int x = 0; x < xCnt; x++)
{
if ((y == (yCnt - 1)) && (x > (data.count % xCnt)))
{
break;
}
else {
// Your Grid code here
}
}
}
Hope This helps.
int yCnt = [data count] % 3;
gives 1 when [data count] == 16;

Matrix multiplication in Objective-C

These are some code that I carried in my project to do matrix computing.
They are two class methods and one instance method that for create matrices and do the matrix multiplication operation.
The method for matrics multiplication doesn't work well, the result from it is wrong.
+ (NSMutableArray *)arrayOfWidth:(NSInteger)width andHeight:(NSInteger)height {
return [[self alloc] initWithWidth:width andHeight:height];
}
- (id)initWithWidth:(NSInteger)width andHeight:(NSInteger)height {
if((self = [self initWithCapacity:height])) {
for(int i = 0; i < height; i++) {
NSMutableArray *inner = [[NSMutableArray alloc] initWithCapacity:width];
[self addObject:inner];
}
}
return self;
}
+ (NSMutableArray *)matrixA:(NSMutableArray *)matrixA multiplyMatrixB:(NSMutableArray *)matrixB {
int aRow = [matrixA count];
int aColumn = [[matrixA objectAtIndex:0] count];
int bRow = [matrixB count];
int bColumn = [[matrixB objectAtIndex:0] count];
NSMutableArray *newArray = [NSMutableArray arrayOfWidth:aRow andHeight:bColumn];
for (int i = 0; i < aRow; i++) {
for (int j = 0; j < bColumn; j++) {
double sum = 0.0;
for (int k = 0; k < aColumn; k++) {
NSMutableArray *innerA = [matrixA objectAtIndex:i];
double numA = [[innerA objectAtIndex:k] doubleValue];
NSMutableArray * innerB = [matrixB objectAtIndex:k];
double numB = [[innerB objectAtIndex:j] doubleValue];
sum += numA * numB;
}
NSNumber *result = [NSNumber numberWithDouble:sum];
[[newArray objectAtIndex:i] insertObject:result atIndex:j];
}
}
return newArray;
}
Is there something wrong with the code?
And how can I fix it?
//First, I create a array to hold the numbers
NSNumber *num11 = [NSNumber numberWithDouble:-2.0];
NSNumber *num12 = [NSNumber numberWithDouble:1.0];
NSNumber *num13 = [NSNumber numberWithDouble:-1.0];
NSNumber *num14 = [NSNumber numberWithDouble:2.0];
NSNumber *num21 = [NSNumber numberWithDouble:-7.0];
NSNumber *num22 = [NSNumber numberWithDouble:0.0];
NSNumber *num23 = [NSNumber numberWithDouble:-1.0];
NSNumber *num24 = [NSNumber numberWithDouble:-4.0];
NSNumber *num31 = [NSNumber numberWithDouble:-2.0];
NSNumber *num32 = [NSNumber numberWithDouble:-1.0];
NSNumber *num33 = [NSNumber numberWithDouble:0.0];
NSNumber *num34 = [NSNumber numberWithDouble:-2.0];
NSNumber *num41 = [NSNumber numberWithDouble:-3.0];
NSNumber *num42 = [NSNumber numberWithDouble:-2.0];
NSNumber *num43 = [NSNumber numberWithDouble:0.0];
NSNumber *num44 = [NSNumber numberWithDouble:-3.0];
NSMutableArray *temp = [NSMutableArray arrayWithObjects:num11, num12, num13, num14, num21, num22, num23, num24, num31, num32, num33, num34, num41, num42, num43, num44, nil];
//Second, I create the matrix and get the elements from that array
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
double c = [[temp objectAtIndex:4*i+j] doubleValue];
NSNumber *object = [NSNumber numberWithDouble:c];
[[matrix objectAtIndex:i] insertObject:object atIndex:j];
}
}
//Then, I do the multiplication for matrix and itself
NSMutableArray *multiMatrix = [NSMutableArray matrixA:matrix multiplyMatrixB:matrix];
//get all the elements from the multiMatrix
double m11 = [[[multiMatrix objectAtIndex:0] objectAtIndex:0] doubleValue];
double m12 = [[[multiMatrix objectAtIndex:0] objectAtIndex:1] doubleValue];
double m13 = [[[multiMatrix objectAtIndex:0] objectAtIndex:2] doubleValue];
double m14 = [[[multiMatrix objectAtIndex:0] objectAtIndex:3] doubleValue];
double m21 = [[[multiMatrix objectAtIndex:1] objectAtIndex:0] doubleValue];
double m22 = [[[multiMatrix objectAtIndex:1] objectAtIndex:1] doubleValue];
double m23 = [[[multiMatrix objectAtIndex:1] objectAtIndex:2] doubleValue];
double m24 = [[[multiMatrix objectAtIndex:1] objectAtIndex:3] doubleValue];
double m31 = [[[multiMatrix objectAtIndex:2] objectAtIndex:0] doubleValue];
double m32 = [[[multiMatrix objectAtIndex:2] objectAtIndex:1] doubleValue];
double m33 = [[[multiMatrix objectAtIndex:2] objectAtIndex:2] doubleValue];
double m34 = [[[multiMatrix objectAtIndex:2] objectAtIndex:3] doubleValue];
double m41 = [[[multiMatrix objectAtIndex:3] objectAtIndex:0] doubleValue];
double m42 = [[[multiMatrix objectAtIndex:3] objectAtIndex:1] doubleValue];
double m43 = [[[multiMatrix objectAtIndex:3] objectAtIndex:2] doubleValue];
double m44 = [[[multiMatrix objectAtIndex:3] objectAtIndex:3] doubleValue];
//Or you can use the NSLog to check the result
NSString *lineOne = [NSString stringWithFormat:#"%f, %f, %f, %f", m11, m12, m13, m14];
NSString *lineTwo= [NSString stringWithFormat:#"%f, %f, %f, %f", m21, m22, m23, m24];
NSString *lineThree = [NSString stringWithFormat:#"%f, %f, %f, %f", m31, m32, m33, m34];
NSString *lineFour = [NSString stringWithFormat:#"%f, %f, %f, %f", m41, m42, m43, m44];
#rooftop, that's all the code
If you're on iOS you might want to consider the matrix routines in GLKit
If you are familiar with MATLAB's vector operations (even if you are not), I would recommend you to check the Accelerate Framework, it is an optimized framework for digital signal processing.
Two great advantages:
They have that operation already implemented.
It's a more efficient way to do it, but apparently not for small matrixes, see the comments for further detail.
This is probably the function you are looking for:
vDSP_mmul: Performs an out-of-place multiplication of two matrices; single precision.
void vDSP_mmul (
float *__vDSP_a,
vDSP_Stride __vDSP_aStride,
float *__vDSP_b,
vDSP_Stride __vDSP_bStride,
float *__vDSP_c,
vDSP_Stride __vDSP_cStride,
vDSP_Length __vDSP_M,
vDSP_Length __vDSP_N,
vDSP_Length __vDSP_P
);
Parameters
__vDSP_a
Input matrix A.
__vDSP_aStride
The stride within __vDSP_a. For example if stride is 2, every second element is used.
__vDSP_b
Input matrix B.
__vDSP_bStride
The stride within __vDSP_b. For example if stride is 2, every second element is used.
__vDSP_c
The result matrix.
__vDSP_M
The number of rows in matrix A.
__vDSP_N
The number of columns in matrix B.
__vDSP_P
The number of columns in matrix A and the number of rows in matrix B.
Discussion
This function multiplies an M-by-P matrix (A) by a P-by-N matrix (B) and stores the results in an M-by-N matrix (C).
This performs the following operation:
On the other side if writing the method yourself is a requirement, this post won't help you at all.
There are mainly two errors here:
In the main program, you did not declare matrix. You know how to fix this problem.
As you create the matrix, if you already initialize the matrix to zeros, insertingObject will make the matrix of size '4x8', and not '4x4'.
[[matrix objectAtIndex:i] insertObject:object atIndex:j];
In your matrix multiplication method, you also insertObject into an existing matrix, making its size '4x8' instead of '4x4'.
To fix this second problem, you need to replace method insertObject:atIndex, with replaceObjectAtIndex:withObject.
That should solve the problem.

[OBJ-C][iOS] Getting floating point from NSArray - Problem

I’ve recently stuck at a problem. Here is the thing, I’m trying to get a float object from NSArray that holds it, and all I can get is (null). Obviously not the thing that I want to receive. Look at the snippet of code:
h = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithFloat:1.0],[NSNumber numberWithFloat:1.0],[NSNumber numberWithFloat:1.0], nil];
x = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithFloat:1.0],[NSNumber numberWithFloat:2.0], nil];
y = [[NSMutableArray alloc] init];
int step = 15; // That is just a random value, will depend on size of h and x.
for (int i = 0; i < step; ++i) {
NSLog(#"step = %i", i);
NSMutableArray *xTemp = [[NSMutableArray alloc] initWithArray:x];
NSMutableArray *hTemp = [[NSMutableArray alloc] initWithArray:h];
for (int j = 0; j < 3; ++j) {
float xToMul = [[xTemp objectAtIndex:j] floatValue];
float hToMul = [[hTemp objectAtIndex:(j+i)] floatValue];
NSLog(#"xToMul = %#", xToMul);
NSLog(#"hToMul = %#", hToMul);
}
NSLog(#"\n");
}
And the resul is:
xToMul = (null)
hToMul = (null)
and all I need those values is to do some easy math.
Thanks.
M.R.
Here's your problem:
float xToMul = [[xTemp objectAtIndex:j] floatValue]; float hToMul = [[hTemp objectAtIndex:(j+i)] floatValue];
NSLog(#"xToMul = %#", xToMul); NSLog(#"hToMul = %#", hToMul);
%# is for objects that support -description. float is not an object at all. This code sends the float a -description message, which it can't respond to.
There's two ways to solve this.
The first is to make xToMul and hToMul objects instead of floats and keep the format string.
id xToMul = [xTemp objectAtIndex:j];
id hToMul = [hTemp objectAtIndex:(j+i)];
NSLog(#"xToMul = %#", xToMul);
NSLog(#"hToMul = %#", hToMul);
The second is to keep them as floats but fix the format string:
float xToMul = [[xTemp objectAtIndex:j] floatValue];
float hToMul = [[hTemp objectAtIndex:(j+i)] floatValue];
NSLog(#"xToMul = %f", xToMul);
NSLog(#"hToMul = %f", hToMul);
If you're planning to do math with the floats, you probably want to pick this option.
Another interesting point is this loop:
for (int j = 0; j < 3; ++j) {
This will step through j with three values: 0, 1 and 2. That corresponds to the first, second and third item in NSArray. You have two items in x and three in h. I'm guessing this is just a simplification of your original code, but in both cases it's one short. j of 2+1 will access the 4th item in h, and j of 2 will access the 3rd item in x.