280 lines
9.1 KiB
Mathematica
280 lines
9.1 KiB
Mathematica
|
|
#import "Algorithm20.h"
|
||
|
|
|
||
|
|
@implementation Algorithm20
|
||
|
|
|
||
|
|
- (instancetype)init {
|
||
|
|
self = [super init];
|
||
|
|
if (self) {
|
||
|
|
self.X = [[ParamX alloc] init];
|
||
|
|
self.iValueManager = [[IValueManager alloc] init];
|
||
|
|
self.rfManager = [[ReferenceManager alloc] init];
|
||
|
|
self.calIValue = [NSMutableArray array];
|
||
|
|
}
|
||
|
|
return self;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (IValue *)getInitParam {
|
||
|
|
return [self.iValueManager getPreIValue];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setInitParam:(IValue *)iValue {
|
||
|
|
[self.iValueManager setPreIValue:iValue];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)addRef:(NSNumber *)value time:(NSDate *)time {
|
||
|
|
[self.rfManager addReference:value.doubleValue time:time];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (NSNumber *)calcBloodGlucose:(double)current datetime:(NSDate *)datetime {
|
||
|
|
NSNumber *bgValue = @(0.0);
|
||
|
|
IValue *cur_data = [[IValue alloc] initWithCurrentTime:datetime current:@(current)];
|
||
|
|
IValue *i4_data = nil;
|
||
|
|
[self.rfManager findReferenceByDate:datetime];
|
||
|
|
|
||
|
|
if ([self.rfManager isCalK]) {
|
||
|
|
i4_data = [self calKValueAlgorithm:cur_data];
|
||
|
|
} else {
|
||
|
|
i4_data = [self I4Algorith:cur_data];
|
||
|
|
}
|
||
|
|
|
||
|
|
if ([self.rfManager isCalK]) {
|
||
|
|
bgValue = @([self.rfManager getRefValue].value);
|
||
|
|
} else if ([self.rfManager isWaitCalK]) {
|
||
|
|
bgValue = @([self.rfManager getRefValue].value);
|
||
|
|
[i4_data setRfTime:[self.rfManager getRefValue].time];
|
||
|
|
[i4_data setRf:@([self.rfManager getRefValue].value)];
|
||
|
|
} else if ([i4_data getK] != nil) {
|
||
|
|
bgValue = @([i4_data.getI4 doubleValue] / [i4_data.getK doubleValue]);
|
||
|
|
}
|
||
|
|
|
||
|
|
bgValue = [self roundDouble:bgValue.doubleValue precision:1];
|
||
|
|
if ((current >= 600.0) || (current <= 30.0)) {
|
||
|
|
bgValue = @(0.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
[i4_data setBg:bgValue];
|
||
|
|
[self.iValueManager setPreIValue:i4_data];
|
||
|
|
|
||
|
|
NSString *rft = [i4_data getRfTime] == nil ? @"" : [self dateformate:[i4_data getRfTime]];
|
||
|
|
|
||
|
|
NSLog(@"%@\t%@\t%@", [i4_data getCurrent], [self dateformate:[i4_data getCurrentTime]], bgValue);
|
||
|
|
return bgValue;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (NSNumber *)calcBloodGlucose:(double)current index:(NSInteger)index {
|
||
|
|
NSNumber *bgValue = @(0.0);
|
||
|
|
IValue *cur_data = [[IValue alloc] initWithCurrentTime:nil current:@(current)];
|
||
|
|
IValue *i4_data = nil;
|
||
|
|
[self.rfManager findReferenceByIndex:index];
|
||
|
|
|
||
|
|
if ([self.rfManager isCalK]) {
|
||
|
|
i4_data = [self calKValueAlgorithm:cur_data];
|
||
|
|
} else {
|
||
|
|
i4_data = [self I4Algorith:cur_data];
|
||
|
|
}
|
||
|
|
|
||
|
|
if ([self.rfManager isCalK]) {
|
||
|
|
bgValue = @([self.rfManager getRefValue].value);
|
||
|
|
} else if ([self.rfManager isWaitCalK]) {
|
||
|
|
bgValue = @([self.rfManager getRefValue].value);
|
||
|
|
[i4_data setRfTime:[self.rfManager getRefValue].time];
|
||
|
|
[i4_data setRf:@([self.rfManager getRefValue].value)];
|
||
|
|
} else if ([i4_data getK] != nil) {
|
||
|
|
bgValue = @([i4_data.getI4 doubleValue] / [i4_data.getK doubleValue]);
|
||
|
|
}
|
||
|
|
|
||
|
|
bgValue = [self roundDouble:bgValue.doubleValue precision:1];
|
||
|
|
if ((current >= 600.0) || (current <= 30.0)) {
|
||
|
|
bgValue = @(0.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
[i4_data setBg:bgValue];
|
||
|
|
[self.iValueManager setPreIValue:i4_data];
|
||
|
|
[self.calIValue addObject:i4_data];
|
||
|
|
|
||
|
|
return bgValue;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (NSMutableArray<NSNumber *> *)calculateBloodGlucose:(NSInteger)index refValue:(NSNumber *)refValue values:(NSMutableArray<NSNumber *> *)values {
|
||
|
|
[self.rfManager addCurrentReference:refValue.doubleValue index:index];
|
||
|
|
|
||
|
|
NSMutableArray<NSNumber *> *dataList = [NSMutableArray array];
|
||
|
|
for (NSInteger i = 0; i < values.count; i++) {
|
||
|
|
NSNumber *electricValue = values[i];
|
||
|
|
NSNumber *bgValue = [self calcBloodGlucose:electricValue.doubleValue index:(index + i)];
|
||
|
|
[dataList addObject:bgValue];
|
||
|
|
}
|
||
|
|
|
||
|
|
return dataList;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (IValue *)calTest:(double)current datetime:(NSDate *)datetime {
|
||
|
|
NSNumber *bgValue = @(0.0);
|
||
|
|
IValue *cur_data = [[IValue alloc] initWithCurrentTime:datetime current:@(current)];
|
||
|
|
IValue *i4_data = nil;
|
||
|
|
[self.rfManager findReferenceByDate:datetime];
|
||
|
|
|
||
|
|
if ([self.rfManager isCalK]) {
|
||
|
|
i4_data = [self calKValueAlgorithm:cur_data];
|
||
|
|
} else {
|
||
|
|
i4_data = [self I4Algorith:cur_data];
|
||
|
|
}
|
||
|
|
|
||
|
|
if ([self.rfManager isCalK]) {
|
||
|
|
bgValue = @([self.rfManager getRefValue].value);
|
||
|
|
} else if ([self.rfManager isWaitCalK]) {
|
||
|
|
bgValue = @([self.rfManager getRefValue].value);
|
||
|
|
[i4_data setRfTime:[self.rfManager getRefValue].time];
|
||
|
|
[i4_data setRf:@([self.rfManager getRefValue].value)];
|
||
|
|
} else if ([i4_data getK] != nil) {
|
||
|
|
bgValue = @([i4_data.getI4 doubleValue] / [i4_data.getK doubleValue]);
|
||
|
|
}
|
||
|
|
|
||
|
|
bgValue = [self roundDouble:bgValue.doubleValue precision:1];
|
||
|
|
if ((current >= 600.0) || (current <= 30.0)) {
|
||
|
|
bgValue = @(0.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
[i4_data setBg:bgValue];
|
||
|
|
[self.iValueManager setPreIValue:i4_data];
|
||
|
|
|
||
|
|
NSString *rft = [i4_data getRfTime] == nil ? @"" : [self dateformate:[i4_data getRfTime]];
|
||
|
|
|
||
|
|
NSLog(@"%@\t%@\t%@", [i4_data getI0], [i4_data getI1], [i4_data getI2], [i4_data getI3], [i4_data getI4], [i4_data getK], [i4_data getRf], [i4_data getBg], [i4_data getCurrent], [self dateformate:[i4_data getCurrentTime]], [i4_data getRf], rft);
|
||
|
|
|
||
|
|
return i4_data;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (IValue *)calKValueAlgorithm:(IValue *)cur_data {
|
||
|
|
NSNumber *kValue = @(0.0);
|
||
|
|
cur_data = [self calI4ForK:cur_data];
|
||
|
|
kValue = [cur_data getK];
|
||
|
|
I4Algorithm *i4Temp = nil;
|
||
|
|
|
||
|
|
if (kValue.doubleValue >= 10.0 && kValue.doubleValue <= 20.0) {
|
||
|
|
[cur_data setK:kValue];
|
||
|
|
return cur_data;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (kValue.doubleValue < 10.0) {
|
||
|
|
[cur_data setI4:@([cur_data.getI3 doubleValue] - [I4Algorithm I4_20].value)];
|
||
|
|
kValue = @([cur_data.getI4 doubleValue] / [self.rfManager getRefValue].value);
|
||
|
|
i4Temp = [I4Algorithm I4_20];
|
||
|
|
} else if (kValue.doubleValue > 20.0) {
|
||
|
|
[cur_data setI4:@([cur_data.getI3 doubleValue] - [I4Algorithm I4_60].value)];
|
||
|
|
kValue = @([cur_data.getI4 doubleValue] / [self.rfManager getRefValue].value);
|
||
|
|
i4Temp = [I4Algorithm I4_60];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (kValue.doubleValue >= 7.5 && kValue.doubleValue <= 25.0) {
|
||
|
|
[cur_data setK:kValue];
|
||
|
|
[cur_data setBgCurrent:i4Temp.value];
|
||
|
|
return cur_data;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (kValue.doubleValue < 7.5) {
|
||
|
|
[cur_data setI4:@([cur_data.getI3 doubleValue] - [I4Algorithm I4_0].value)];
|
||
|
|
kValue = @([cur_data.getI4 doubleValue] / [self.rfManager getRefValue].value);
|
||
|
|
i4Temp = [I4Algorithm I4_0];
|
||
|
|
} else if (kValue.doubleValue > 25.0) {
|
||
|
|
[cur_data setI4:@([cur_data.getI3 doubleValue] - [I4Algorithm I4_80].value)];
|
||
|
|
kValue = @([cur_data.getI4 doubleValue] / [self.rfManager getRefValue].value);
|
||
|
|
i4Temp = [I4Algorithm I4_80];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (kValue.doubleValue > 2.5 && kValue.doubleValue < 40.0) {
|
||
|
|
[cur_data setK:kValue];
|
||
|
|
[cur_data setBgCurrent:i4Temp.value];
|
||
|
|
}
|
||
|
|
|
||
|
|
return cur_data;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (int)calRoc {
|
||
|
|
if (self.calIValue == nil) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
NSInteger size = self.calIValue.count;
|
||
|
|
if (size == 0 || size <= 2) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
double b0 = [[self.calIValue[size - 3] getBg] doubleValue];
|
||
|
|
double b1 = [[self.calIValue[size - 2] getBg] doubleValue];
|
||
|
|
double b2 = [[self.calIValue[size - 1] getBg] doubleValue];
|
||
|
|
|
||
|
|
if (b0 == 0.0 || b1 == 0.0 || b2 == 0.0) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
double roc = (0.3 * ((b1 - b0) / 3.0)) + (0.7 * ((b2 - b1) / 3.0));
|
||
|
|
|
||
|
|
if (roc >= 0.1) {
|
||
|
|
return 1;
|
||
|
|
} else if (roc > 0.05 && roc < 0.1) {
|
||
|
|
return 2;
|
||
|
|
} else if (roc >= -0.05 && roc <= 0.05) {
|
||
|
|
return 3;
|
||
|
|
} else if (roc > -0.1 && roc < -0.05) {
|
||
|
|
return 4;
|
||
|
|
} else if (roc <= -0.1) {
|
||
|
|
return 5;
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (IValue *)calI4ForK:(IValue *)cur_data {
|
||
|
|
IValue *I4_redta = [self I4Algorith:cur_data];
|
||
|
|
NSNumber *kValue = @([I4_redta.getI4 doubleValue] / [self.rfManager getRefValue].value);
|
||
|
|
[I4_redta setK:kValue];
|
||
|
|
return I4_redta;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (IValue *)I4Algorith:(IValue *)cur_data {
|
||
|
|
IValue *prev_data = [self.iValueManager getPreIValue];
|
||
|
|
|
||
|
|
[cur_data setI0:[cur_data getCurrent]];
|
||
|
|
|
||
|
|
[cur_data setI1:@([cur_data.getI0 doubleValue] * (1.0 + self.X.X1 * (32.0 - self.X.X2)))];
|
||
|
|
|
||
|
|
if (prev_data != nil && [prev_data getI3] != nil) {
|
||
|
|
[cur_data setI3:@(self.X.X4 * [cur_data.getI1 doubleValue] + (1.0 - self.X.X4) * [prev_data.getI3 doubleValue])];
|
||
|
|
[cur_data setBgCurrent:[prev_data getBgCurrent]];
|
||
|
|
[cur_data setK:[prev_data getK]];
|
||
|
|
|
||
|
|
if ([cur_data getRf] != nil && [cur_data getRf].doubleValue != 0.0) {
|
||
|
|
[cur_data setRf:[prev_data getRf]];
|
||
|
|
[cur_data setRfTime:[prev_data getRfTime]];
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
[cur_data setBgCurrent:[I4Algorithm I4_40].value];
|
||
|
|
[cur_data setI3:[cur_data getI1]];
|
||
|
|
}
|
||
|
|
|
||
|
|
[cur_data setI4:@([cur_data.getI3 doubleValue] - [cur_data getBgCurrent])];
|
||
|
|
|
||
|
|
return cur_data;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (NSNumber *)roundDouble:(double)val precision:(int)precision {
|
||
|
|
NSNumber *ret = nil;
|
||
|
|
@try {
|
||
|
|
double factor = pow(10.0, precision);
|
||
|
|
ret = @(floor(val * factor + 0.5) / factor);
|
||
|
|
}
|
||
|
|
@catch (NSException *exception) {
|
||
|
|
NSLog(@"%@", exception.reason);
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (NSString *)dateformate:(NSDate *)date {
|
||
|
|
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||
|
|
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
|
||
|
|
return [formatter stringFromDate:date];
|
||
|
|
}
|
||
|
|
|
||
|
|
@end
|