Convert a string in char to array in MATLAB - arrays

I have a list of strings in a char array:
'gvs(0.000000000000000e+000, 1.601985139535780e+002)'
'gvs(-5.000000000000000e-005, 1.365231866954370e+002)'
'gvs(-1.000000000000000e-004, 1.169431404340180e+002)'
'gvs(-5.000000000000000e-004, 3.187711314514890e+001)'
'gvs(-2.000000000000000e-004, 8.589930648472340e+001)'
Which I am trying to convert to an array of just the numbers (ignoring gvs, the comma and the brackets), but I can't quite work out what I'm doing wrong?
cols = length(Variables) + length(Parameters);
% currently unused
rows = length(Results);
for a = 1:rows;
Res(a,:) = sscanf ((Results{a,1}(1,:)),'%*s %f %f');
end
I've also tried textscan, but I can't get that to work right either
for a = 1:rows;
Res = cell (textscan ((Results{a,1}(1,:)),'%*s %f %f','Delimiter', {'(',' '},'MultipleDelimsAsOne',1));
end
Any help much appreciated!
Thanks

Replace
Res(a,:) = sscanf ((Results{a,1}(1,:)),'%*s %f %f');
with
Res(a,:) = sscanf ((Results{a,1}(1,:)),'gvs(%f, %f)');

Assuming you have a char array (not a cellstring):
s = ['gvs( 0.000000000000000e+000, 1.601985139535780e+002)'
'gvs(-5.000000000000000e-005, 1.365231866954370e+002)'
'gvs(-1.000000000000000e-004, 1.169431404340180e+002)'
'gvs(-5.000000000000000e-004, 3.187711314514890e+001)'
'gvs(-2.000000000000000e-004, 8.589930648472340e+001)']
Then you can simply textscan():
data = textscan(s','gvs(%f%f)','CollectOutput',1,'Delimiter',',');
data = data{1}
data =
0 160.1985
-0.0001 136.5232
-0.0001 116.9431
-0.0005 31.8771
-0.0002 85.8993
If s is a cellstring, then before calling textscan, convert to char():
s = char(s);

Considering that your string is almost in MATLAB-array compatible format, you could commit a sin and use evalc:
>> s = {
'gvs( 0.000000000000000e+000, 1.601985139535780e+002)'
'gvs(-5.000000000000000e-005, 1.365231866954370e+002)'
'gvs(-1.000000000000000e-004, 1.169431404340180e+002)'
'gvs(-5.000000000000000e-004, 3.187711314514890e+001)'
'gvs(-2.000000000000000e-004, 8.589930648472340e+001)'};
>> C = evalc(['[' regexprep([s{:}], {'gvs\(' '\)'}, {'' ';'}) ']'])
ans =
0 1.601985139535780e+002
-5.000000000000000e-005 1.365231866954370e+002
-1.000000000000000e-004 1.169431404340180e+002
-5.000000000000000e-004 3.187711314514890e+001
-2.000000000000000e-004 8.589930648472340e+001

Related

Assigning variables from a matrix in R

I think I'm incorrectly accessing and assigning variables from a matrix. I understand that arrays, matrices, and tables are different in R. What I want to end up with is an array of values called "c" that has either a 1 or 2 assigning an element from input to either Mew(number 1) or Mewtwo(number 2. I also want the distance from Mew to all other points in an array called dMew as well as dMewtwo an array of the distance from Mewtwo to all other elements in input. What I end up with is NA_real_ for all variables except input. There is a lot of great information on accessing rows or columns of various data structures in R but I'm interested in accessing single elements. Any advice would be most helpful. I apologize if this has been answered before but I couldn't find it anywhere.
#Read input from a csv data file
input = read.csv("~/Desktop/Engineering/iris.csv",head=FALSE)
input = input[c(0:3)]
input = as.matrix(input)
#set random centroids
Mew = input[1,1]
Mewtwo = input[nrow(input),ncol(input)]
#Determine Distance
dist <- function(x, y) {
return(sqrt((x - y)^2))
}
#Determine the clusters
dMew = matrix(,nrow(input), ncol(input))
dMewtwo = matrix(,nrow(input), ncol(input))
c = matrix(,nrow(input), ncol(input))
for (i in 1:nrow(input)) {
for (j in 1:ncol(input)) {
dMew[i,j] = dist(Mew, input[i,j])
dMewtwo[i,j] = dist(Mewtwo, input[i,j])
if (dMew[i,j] > dMewtwo[i,j]) {
c[i,j] = 2
} else {
c[i,j] = 1
}
}
}
#Update the centroids
Mew = mean(dMew)
Mewtwo = mean(dMewtwo)
I have no problem running the code with the following input:
input = data.frame(V1=1:5,V2=1:5,V3=1:5)
so it seems to be a problem related to your data. Also you should avoid using "c" as a variable name and note that dist() is already a function in the stats package. Also, you can avoid the for-loops by using apply() and ifelse():
#Read input from a csv data file
input = data.frame(V1=1:5,V2=1:5,V3=1:5)
input = input[c(1:3)]
input = as.matrix(input)
#set random centroids
Mew = input[1,1]
Mewtwo = input[nrow(input),ncol(input)]
#Determine Distance
dist.eu <- function(x, y) {
return(sqrt((x - y)^2))
}
dMew<-apply(input,c(1,2),dist.eu,Mew)
dMewtwo<-apply(input,c(1,2),dist.eu,Mewtwo)
c.mat<-ifelse(dMew > dMewtwo,2,1)
c.mat

C fprintf %g correspondence in Scala/Java

I have to automatically compare text output from a C program and a conversion to Scala. Unfortunately, I cannot find a way to format double values the same way. In C I have for example:
double diff = -1.0; // just an example
fprintf(stdout, "diff %g\n", diff);
This is written as
diff -1
(no decimal point).
In Scala I have
val diff = -1.0; // just an example
println(f"diff $diff%g\n")
This is written as
diff -1.00000
In other words, the %g formatter doesn't do the same. I am looking at this document, but can't a way to have 100% compatible fprintf format.
Edit: Without using JNI or writing page long special methods.
Scala uses the the Java Formatter class documented here. To get what you want:
scala> "%.0g".format(-1.0)
res0: String = -1
Ok, so this is an identical question with a great answer by #john-douthat, which needs some tiny adjustments:
def ¬(x: Double) = {
val obj = x.toFloat.asInstanceOf[AnyRef]
String.format("%.6g", obj).replaceFirst("\\.?0+(e|$)", "$1")
}
val diff = -1.0
println(s"diff ${¬(diff)}")
println(s"Pi ${¬(math.Pi)}")
Output:
diff -1
Pi 3.14159
There are still some problems, though. For example -3.59847e-10 gets output as -3.59847e-1. This is bug in the regexp for replaceFirst. If someone can fix it better than this, I'd be very happy (regexps have a mental mismatch with me):
def ¬(x: Double) = {
val obj = x.toFloat.asInstanceOf[AnyRef]
val s0 = String.format("%.6g", obj)
val i0 = s0.lastIndexOf('e')
val i = if (i0 < 0) s0.length else i0
s0.substring(0, i).replaceFirst("\\.?0+($)", "$1") + s0.substring(i)
}
Check this
val diff = -1.0 //> diff : Double = -1.0
"diff %g\n".format(diff) //> res6: String = "diff -1.00000
//| "

Dictionary query?

I am using the following code to check for values of 1 or 0 stored in a dictionary file called 'myDict'. At position 'block003stored' is the value 1 and at all the other positions it's 0. If I use the following code I always get 0 returned for all positions:
for (int i = 1 ; i < 100 ; i++) {
if(myDict)
{
UIImageView *imageV = (UIImageView *)[self.view viewWithTag:i];
int myInt = [[myDict objectForKey:#"block%.3istored"] intValue];
NSLog (#"value of i %d", i);
NSLog (#"myInt %d", myInt);
if (myInt == 1) imageV.hidden = FALSE;
}
}
}
However if I change the objectForKey to specifically #"block003stored":
int myInt = [[myDict objectForKey:#"block003stored"] intValue];
I get the correct value of 1 returned. I can't see why the code isn't working when I use the %.3i instead of 001, 002, 003 etc?
Try in a separate line:
NSString *indexStr = [NSString stringWithFormat:#"block%.3dstored", i]; Then use the objectForKey:indexStr];
You were asking the dictionary to get the object with the key of "block%.3istored", which didn't exist. You need to apply formatting to get i in there.
The code in the loop is using #"block%.3istored" as a literal string. There's nothing in what you've written to format the string with the i variable. Look at NSString's stringWithFormat: as a way of dynamically building the key.

How can I apply a low-shelving filter using Visualdsp++?

I'm very new to DSP. And have to solve the following problem: applying the low shelving filter for an array of data. The original data is displayed in fract16 (VisualDSP++).
I'm writing something as below but not sure it's correct or not.
Does the following code have any problem with overflow?
If 1 is true, how should I do to prevent it?
Any advice on this problem?
fract16 org_data[256]; //original data
float16 ArrayA[],ArrayB[];
long tmp_A0, tmp_A1, tmp_A2, tmp_B1, tmp_B2;
float filter_paraA[3], filter_paraB[3]; // correctness: 0.xxxxx
// For equalizing
// Low-Shelving filter
for ( i=0; i<2; i++)
{
tmp_A1 = ArrayA[i*2];
tmp_A2 = ArrayA[i*2+1];
tmp_B1 = ArrayB[i*2];
tmp_B2 = ArrayB[i*2+1];
for(j=0;j<256;j++){
tmp_A0 = org_data[j];
org_data[j] = filter_paraA[0] * tmp_A0
+ filter_paraA[1] * tmp_A1
+ filter_paraA[2] * tmp_A2
- filter_paraB[1] * tmp_B1
- filter_paraB[2] * tmp_B2;
tmp_A2 = tmp_A1;
tmp_B2 = tmp_B1;
tmp_A1 = tmp_A0;
tmp_B1 = org_data[j];
}
ArrayA[i*2] = tmp_A1;
ArrayA[i*2+1] = tmp_A2;
ArrayB[i*2] = tmp_B1;
ArrayB[i*2+1] = tmp_B2;
}
I don't know what the range is for fract16, just -1 to +1 approx?
The section that stands out to me as possibly generating an overflow is assigning org_data[j] but will be dependent on what you know about your input signal and your filter coefficients. If you can ensure that multiplying filter_paraA[2:0] to signal with values tmp_A2..1 = [1,1,1] is < max(fract16) you should be fine regardless of the 'B' side.
I would recommend adding some checks for overflow in your code. It doesn't necessarily have to fix it, but you would be able to identify an otherwise very tricky bug. Unless you need absolute max performance I would even leave the check code in place but with less output or setting a flag that gets checked.
macA = filter_paraA[0] * tmp_A0 + filter_paraA[1] * tmp_A1 \
+ filter_paraA[2] * tmp_A2;
macB = filter_paraB[1] * tmp_B1 - filter_paraB[2] * tmp_B2;
if((macA-macB)>1){
printf("ERROR! Overflow detected!\n");
printf("tmp_A[] = [%f, %f, %f]\n",tmp_A2,tmp_A1,tmp_A0);
printf("tmp_B[] = [%f, %f]\n",tmp_B1,tmp_B0);
printf(" i = %i, j = %i\n",i,j);
}

How do I base58 encode a string?

char (* text)[1][45+1];
text = calloc(5000,(130+1));
strcpy(0[*text],"sometext)");
Now I want to encode "sometext" to base58, however, I do not know how, and oddly enough, there isn't one example of BASE58 in C.
The base58 encoding I'm interested in uses these symbols:
123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ
It's been optimized to lessen the risk of mis-reading, so 0 and 'O' are both gone, for instance.
P.S
Don't mind the weird allocation and declaration of the variables, I was experimenting.
You're not supposed to encode strings, you're supposed to encode integers.
If starting with a string, you must first decide how to interpret it as an integer (might be base128, or something), then re-encode in base58.
Satoshi has the reference implementation (https://github.com/bitcoin/bitcoin/blob/master/src/base58.h)
However, he uses some utility bignum class to do it, and it's in C++. If you have access to a bignum library, you just keep dividing by 58 until the number is broken up. If you don't have a bignum library, AFAIK you're outta luck.
Here's an implementation in PHP for large numbers I've created for Amithings, beyond the integers (Integer -> http://php.net/manual/en/language.types.integer.php).
For example, try the example below (Don't forget to pass your ID to the function in string format. Use the PHP function strval()):
$number = '123456789009876543211234567890';
$result = base58_encode($number);
echo('Encoded: ' . $result . '<br>');
echo('Decoded: ' . base58_decode($result) . '<br>');
Important: You may consider to change this routine by including some sort of key/password/encryption to ensure that others can not decode your database IDs.
function base58_encode($input)
{
$alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
$base_count = strval(strlen($alphabet));
$encoded = '';
while (floatval($input) >= floatval($base_count))
{
$div = bcdiv($input, $base_count);
$mod = bcmod($input, $base_count);
$encoded = substr($alphabet, intval($mod), 1) . $encoded;
$input = $div;
}
if (floatval($input) > 0)
{
$encoded = substr($alphabet, intval($input), 1) . $encoded;
}
return($encoded);
}
function base58_decode($input)
{
$alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
$base_count = strval(strlen($alphabet));
$decoded = strval(0);
$multi = strval(1);
while (strlen($input) > 0)
{
$digit = substr($input, strlen($input) - 1);
$decoded = bcadd($decoded, bcmul($multi, strval(strpos($alphabet, $digit))));
$multi = bcmul($multi, $base_count);
$input = substr($input, 0, strlen($input) - 1);
}
return($decoded);
}
My simple code with Crypto++ library:
string base58_encode(Integer num, string vers)
{
string alphabet[58] = {"1","2","3","4","5","6","7","8","9","A","B","C","D","E","F",
"G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c",
"d","e","f","g","h","i","j","k","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
int base_count = 58; string encoded; Integer div; Integer mod;
while (num >= base_count)
{
div = num / base_count; mod = (num - (base_count * div));
encoded = alphabet[ mod.ConvertToLong() ] + encoded; num = div;
}
encoded = vers + alphabet[ num.ConvertToLong() ] + encoded;
return encoded;
}
It's just for cryptocurrency wallets. string can be changed for other tasks.
Here is an implementation that seems to be pure c.
https://github.com/trezor/trezor-crypto/blob/master/base58.c

Resources