Matrix math fundamental to machine learning implementations

matrixMultiplyWe are building our first Swift app for the iPhone / iPad with machine learning “at the edge” – i.e. on the device.

As anyone who has tried to implement even the most basic Machine Learning algorithms knows, you need a good library for reading in data to matrices, saving data, manipulating matrices and doing basic stuff such as transpose and multiplication, to even get off the starting block with your sanity intact.

When starting out we could not find  an easy (and free) to use Swift library to help us do Matrix manipulations, so we wrote our own. You can download the Swift file here:

SMatric Class - Swift Matrix manipulation library (170 downloads)

 

The library is implemented as a Swift Class, each instance of the class is a Matrix. Most methods are non-destructive, i.e. they return a new object rather than manipulating the old, while some are destructive for performance reasons. The class links to the Accelerate framework which means that heavy calculations make use of the Vector support of the CPU. This speeds stuff up nicely.  Because we wrote the SMatrix class with a view to running it on iPhones and iPads, we did not make use of Graphics Card libraries such as CUDA or OPEN-CL. If rewriting for the desktop, adding that support would make good sense.

Feel free to download and use the library in any way you see fit. We have made it available under the Lesser GNU General Public Licence, so you can include it in projects, modify it and distribute it.  If you want support or would like us to make additions or changes, we are happy to provide that under commercial conditions. Get in touch on:

contact@societas.mobi

Happy Coding!

BT, December 13, 2015

UIAlertView deprecated in iOS9 – our workaround

MyAlertView

When moving an objective-c application to iOS 9 you will have to deal with the depreciation of UIAlertView.  If your apps have few uses of AlertView this is a small problem and manually replacing your UIAlertView code with UIAlertController is the way to go.

When we started the move of BeamWriter to iOS 9 however, xCode gave us close to 200 ‘UIAlertView id deprecated, use UIAlertController instead’ warnings, and we did not have the patience to re-write all that code manually.

Luckily most of our uses of UIAlertView were pretty basic  –  usually only the single dismiss button, and only occasionally with other buttons requiring a delegate.  We therefore decided to write a ‘wrap’ for UIAlertController which would allow us to rename our calls to UIAlertView, keep the old delegate callbacks and be good.   Here is what we did:

Create a new Class ‘MyAlertView’ with header MyAlertView.h:

#import <UIKit/UIKit.h>

@class MyAlertView;

@protocol MyAlertViewDelegate <NSObject>

@optional

-(void)alertView:(MyAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;

@end

@interface MyAlertView : UIViewController

/**
Holds the alert controller actually used to display the alert.
*/
@property UIAlertController *myAlertController;

/**
    The delegate if one specified. This will be called with the button pressed

*/
@property id<MyAlertViewDelegate> delegate;


-(id)initWithTitle: (NSString *)title message: (NSString *)message delegate: (id<MyAlertViewDelegate>) delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles: (NSString *) otherButtonTitle, ...;


-(void)show: (UIViewController *)v ;

@end

With Implementation MyAlertView.m:

#import "MyAlertView.h"
#import "stdio.h"

@implementation MyAlertView

-(id)initWithTitle: (NSString *)title message: (NSString *)message delegate: (id<MyAlertViewDelegate>) delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles: (NSString *) otherButtonTitle, ...
{
    self=[super init];

    if (self) {

        [self setMyAlertController:[UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]];

        UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleDefault

                                                              handler:^(UIAlertAction * action) { [self clicked:0]; }];

        [[self myAlertController] addAction:defaultAction];

        // Add buttons for button number two .. n if present.

        int count = 0;
        va_list ap;
        va_start(ap, otherButtonTitle);
        id object = otherButtonTitle;
        while (object) {           

            // Create a button with the argument

            defaultAction = [UIAlertAction actionWithTitle:(NSString *)object style:UIAlertActionStyleDefault

                                                   handler:^(UIAlertAction * action) { [self clicked:(NSInteger)count + 1]; }];

            [[self myAlertController] addAction:defaultAction];
            ++count;
            object = va_arg(ap, id);

        }

        va_end(ap);

        // set the delegate
        [self setDelegate:delegate];
    }

    return self;

}

-(void)show: (UIViewController *)v
{

    [v presentViewController:[self myAlertController] animated:YES completion:nil];

}


/**
 Method to call when a button is clicked. If the delegate is set, the delegate's alertView:(MyAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;

 is called with the index of the button. If the delegate is not set, nothing is done.
 */

-(void)clicked:(NSInteger)i
{

    if ([self delegate]) {

        [[self delegate] alertView:self clickedButtonAtIndex:i];

    }
}

@end

Finally you need to:

  1. Include MyAlertView.h in the files where you currently use UIAlertView.
  2. Add ‘MyAlertViewDelegate’ to the list of delegates of any class where you currently have ‘UIAlertViewDelegate’  (yes – search/replace…)
  3. Replace all references to ‘UIAlertView’ with ‘MyAlertView’
  4. Replace the calls you currently have to [‘yourUIAlertView’ show] – i.e the code that with UIAlertView causes the alert to be shown – with [‘yourMyAlertView show:self] OR [‘yourMyAlertView show:’any UIViewController’].  UIAlertController which is actually used to show the alert needs to be called FROM a UIViewController that is in the controller hierarchy (this is the big change). It was previously possible to present alerts from non-view controllers. That is no longer the case.

That’s it.  This small ‘wrap around’ saved us many hours of tedious re-coding.