Access a variable in Matlab using strcat - string

I have a situation where I want have many temperatures placed in column vectors, for example T101, T102, … and I would like to access these using a string cat command and place them in another vector. I created a simplified example to show what I am trying to achieve.
clc
clear all
T102 = [5; 8; 20; 21];
P102 = [T102;1]
P102 = [strcat('T','102');1]
However, I am receiving an error for the second time I define P102 because it has now become the string 'T102' and I want it to become the variable T102 and not the string.

I am not sure what you are trying to do and if it’s the right way.
But to answer your question you should use eval:
P102 = [eval(strcat('T','102'));1];

Related

Is it possible to Add 0 in Double Var in VB Net

I'm trying to add 0 before each number I'm having but it seems it's not working because I'm using double. I'm using double so I can input numbers such as 1.5 (hours) and translate it to seconds, minutes, and hours (Output should be 0 seconds, 30 minutes, and 1 hour and 01:30:00). I'm having no problems with the first output but I can't seem to do the second output (The desired 01:30:00 only displays 1:30:0). What I did first is I tried to convert the double variable to int32 then to string but it seems to not work. Here's the code:
If SecondsRemainder >= 0 And SecondsRemainder < 10 Then
SecondsRemainder = Convert.ToInt32(SecondsRemainder)
SecondsRemainder.ToString.PadLeft(2, "0")
End If
This line of code:
SecondsRemainder.ToString.PadLeft(2, "0")
Doesn't seem to do anything, am I missing something out? Or is there any other way I can do? Looking forward to your answers!
Let's look at this line piece by piece, and see what it actually does:
SecondsRemainder.ToString.PadLeft(2, "0")
We start with the SecondsRemainder variable. This variable is still a Double, in spite of the earlier code using Convert.ToInt32(). Remember, at it's core VB.Net is a statically typed language! When you declare a variable with a specific type, the variable's type can never change.
We now call the .ToString() method for this variable. Note this really is a method, not a property. Good practice for .Net is to include the parentheses when calling methods, even though they aren't strictly required with VB. If I reviewed that code, I'd ask you to change it to show the parentheses. Remember, we're also getting the Double version of this method, rather than the Integer version. You're probably okay here, but the double version can do weird things for formatting you might not expect from an integer.
Finally, we take the string result from the previous method and call PadLeft(). This mostly does what you expect. However, there is no overload that takes a number and a string. Frankly, I'm surprised this even compiles, and it tells me you likely don't have Option Strict set correctly. No self-respecting programmer runs with Option Strict Off anymore. The correct way to call this function is like this:
.PadLeft(2, "0"c)
Where the c suffix gives you a character value rather than a string value.
And that's it. We're done. This function returns a result. It does not modify the calling variable. So we've done all this work, and discard the result without actually changing anything.
What I would do to fix your issue is declare a new string variable to receive the result. Then I would use this code to assign to it:
'Create a string variable to hold your string result
Dim RemainderString As String = ""
'Use double literals to compare with double variables!
If SecondsRemainder >= 0.0 And SecondsRemainder < 10.0 Then
'Use a format string directly from the initial double value to create your string result
' and don't forget to assign it to a variable
RemainerString = SecondsRemainder.ToString("00")
End If
You may also want to use Math.Round() first, as this code would still create "01" from a 1.9999 input.
Finally, I'm wondering how you're using this SecondsRemainder value. VB.Net has a whole set of methods for building date and time strings and values, and a variable name like SecondsRemainder sounds like you're doing something the hard way that could be much MUCH easier.
I'm wondering if the answer is that you are approaching the problem incorrectly. You seem to be computing some time value. If so use TimeSpan.
Dim ts As TimeSpan = TimeSpan.FromHours(1.51#)
' ts.TotalSeconds
' ts.Seconds
Dim s As String = ts.ToString("hh\:mm\:ss")

Find specific string in vector column Matlab

In my program I need to ask the user a string (ex: 'C4') and then obtain the corresponding index to that string on the following vector:
labels=['C2';'C#2';'D2';'D#2';'E2';'F2';'F#2';'G2';'G#2';'A2';'A#2';'B2';'C3';'C#3';'D3';'D#3';'E3';'F3';'F#3';'G3';'G#3';'A3';'A#3';'B3';'C4';'C#4';'D4';'D#4';'E4';'F4';'F#4';'G4';'G#4';'A4';'A#4';'B4';'C5';'C#5';'D5';'D#5';'E5';'F5';'F#5';'G5';'G#5';'A5';'A#5';'B5'];
To ask the string is simple, used input and it worked on octave, but to find the index I couldn't make it work. I tried using find, find(ismember( and also with a for cycle but nothing seems to work.
Appreciate the help
Thanks.
Use strcmp (and note labels should be a cell array, as the strings have different lengths):
labels = {'C2';'C#2';'D2';'D#2';'E2';'F2';'F#2';'G2';'G#2';'A2';'A#2';'B2';'C3';'C#3';'D3';'D#3';'E3';'F3';'F#3';'G3';'G#3';'A3';'A#3';'B3';'C4';'C#4';'D4';'D#4';'E4';'F4';'F#4';'G4';'G#4';'A4';'A#4';'B4';'C5';'C#5';'D5';'D#5';'E5';'F5';'F#5';'G5';'G#5';'A5';'A#5';'B5'};
str = 'C4';
index = find(strcmp(str,labels));
You can use strcmpi instead of strcmp if case is not important.

String matching without using builtin functions

I want to search for a query (a string) in a subject (another string).
The query may appear in whole or in parts, but will not be rearranged. For instance, if the query is 'da', and the subject is 'dura', it is still a match.
I am not allowed to use string functions like strfind or find.
The constraints make this actually quite straightforward with a single loop. Imagine you have two indices initially pointing at the first character of both strings, now compare them - if they don't match, increment the subject index and try again. If they do, increment both. If you've reached the end of the query at that point, you've found it. The actual implementation should be simple enough, and I don't want to do all the work for you ;)
If this is homework, I suggest you look at the explanation which precedes the code and then try for yourself, before looking at the actual code.
The code below looks for all occurrences of chars of the query string within the subject string (variables m; and related ii, jj). It then tests all possible orders of those occurrences (variable test). An order is "acceptable" if it contains all desired chars (cond1) in increasing positions (cond2). The result (variable result) is affirmative if there is at least one acceptable order.
subject = 'this is a test string';
query = 'ten';
m = bsxfun(#eq, subject.', query);
%'// m: test if each char of query equals each char of subject
[ii jj] = find(m);
jj = jj.'; %'// ii: which char of query is found within subject...
ii = ii.'; %'// jj: ... and at which position
test = nchoosek(1:numel(jj),numel(query)).'; %'// test all possible orders
cond1 = all(jj(test) == repmat((1:numel(query)).',1,size(test,2)));
%'// cond1: for each order, are all chars of query found in subject?
cond2 = all(diff(ii(test))>0);
%// cond2: for each order, are the found chars in increasing positions?
result = any(cond1 & cond2); %// final result: 1 or 0
The code could be improved by using a better approach as regards to test, i.e. not testing all possible orders given by nchoosek.
Matlab allows you to view the source of built-in functions, so you could always try reading the code to see how the Matlab developers did it (although it will probably be very complex). (thanks Luis for the correction)
Finding a string in another string is a basic computer science problem. You can read up on it in any number of resources, such as Wikipedia.
Your requirement of non-rearranging partial matches recalls the bioinformatics problem of mapping splice variants to a genomic sequence.
You may solve your problem by using a sequence alignment algorithm such as Smith-Waterman, modified to work with all English characters and not just DNA bases.
Is this question actually from bioinformatics? If so, you should tag it as such.

Conditionals for data type in gnuplot functions

I would like to define a function which returns the string "NaN" or sprintf("%g",val) depending on whether val is a string or a numeric value. Initially I was trying to test if val was defined (using the gnuplot "exists" function) but it seems that I cannot pass any undefined variable to a function (an error is issued before the function is evaluated). Therefore: is there a way to test inside a function whether the argument is a string or numeric?
I search for a function isstring which I can use somehow like
myfunc(val)=(isstring(val)?"NaN":sprintf("%g",val))
The goal is to output the values of variables without risking errors in case they are undefined. However I need it as a function if I want a compact code for many variables.
Gnuplot doesn't really have the introspection abilities that many other languages have. In fact, it treats strings and numbers (at least integers) very similarly:
print "1"+2 #prints 3
a=1
print "foo".a #prints foo1
I'm not exactly sure how this is implemented internally. However, what you're asking is very tricky to get to work.
Actually, I think your first attempt (checking if a variable exists) is more sensible as type-checking in gnuplot is impossible*. You can pass the variable name to the function as a string, but the problem is that you don't seem to have a handle on the value. All seems lost -- But wait, gnuplot has an eval statement which when given a string will evaluate it. This seems great! Unfortunately, it's a statement, not a function (so it can't be used in a function -- argv!). The best solution I can come up with is to write a function which returns an expression that can be evaluated using eval. Here goes:
def exists_func(result,var)=sprintf("%s=exists('%s')?sprintf('%g',var):'NaN'",result,var,var)
Now when you want to use it, you just prefix it with eval
a=3
eval exists_func("my_true_result","a")
print my_true_result #3
eval exists_func("my_false_result","b")
print my_false_result #NaN
This goes against the grain a little bit. In most programming languages, you'd probably want to do something like this:
my_true_result=exists_func(a)
But alas, I can't figure out how to make that form work.
Of course, the same thing goes here that always goes with eval. Don't use this function with untrusted strings.
*I don't actually know that it's impossible, but I've never been able to get it to work
EDIT
In response to your comment above on the question, I think a function like this would be a little more intuitive:
def fmt(x)=(x==x)?sprintf("%g",x):"NaN"
With this function, your "sentinal/default" value should be NaN instead of "undefined", but it doesn't seem like this should make too much of a difference...(Really, if you're willing to live with "nan" instead of "NaN" you don't need this function at all -- sprintf will do just fine. (Note that this works because according to IEEE, NaN doesn't equal anything (even itself)).
You helped me a lot these days with gnuplot. I want to give you something back because I have found a solution to check if a variable is numeric or not. This helps to decide which operators can be used on it (e.g. == for numbers, eq for strings).
The solution is not very simple, but it works. It redirects gnuplot's print command to a temp file, writes the variable to the file with print myvar and evaluates the file's first line with system("perl -e '<isnumeric(line#1 in temp file)?>' ") (<> is pseudo-code). Let me know if there's room for imrpovements and let me hear your suggestions!
Example: myvar is a float. Any integer (1 or "1") or string value ("*") works too!
myvar = -2.555
# create temporary file for checking if variables are numeric
Int_tmpfle = "tmp_isnumeric_check"
# redirect print output into temp file (existing file is overwritten)
set print Int_tmpfle
# save variable's value to file
print myvar
# check if file is numeric with Perl's 'looks_like_number' function
isnumeric = system("perl -e 'use Scalar::Util qw(looks_like_number); \
open(FLE,".Int_tmpfle."); $line = < FLE >; \
if (looks_like_number($line) > 0) {print qq(y)} ' ")
# reset print output to < STDOUT> (terminal)
set print "-"
# make sure to use "," when printing string and numeric values
if (isnumeric eq "y") {print myvar," is numeric."} else {print myvar," is not numeric."}

Parsing strings in Fortran

I am reading from a file in Fortran which has an undetermined number of floating point values on each line (for now, there are about 17 values on a line). I would like to read the 'n'th value on each line to a given floating point variable. How should i go about doing this?
In C the way I wrote it was to read the entire line onto the string and then do something like the following:
for(int il = 0; il < l; il++)
{
for(int im = -il; im <= il; im++)
pch = strtok(NULL, "\t ");
}
for(int im = -l; im <= m; im++)
pch = strtok(NULL, "\t ");
dval = atof(pch);
Here I am continually reading a value and throwing it away (thus shortening the string) until I am ready to accept the value I am trying to read.
Is there any way I can do this in Fortran? Is there a better way to do this in Fortran? The problem with my Fortran code seems to be that read(tline, '(f10.15)') tline1 does not shorten tline (tline is my string holding the entire line and tline1 what i am trying to parse it into), thus I cannot use the same method as I did in my C routine.
Any help?
The issue is that Fortran is a record-based I/O system while C is stream-based.
If you have access to a Fortran 2003 compliant compiler (modern versions of gfortran should work), you can use the stream ACCESS specifier to do what you want.
An example can be found here.
Of course, if you were really inclined, you could just use your C function directly from Fortran. Interfacing the two languages is generally simple, typically only requiring a wrapper with a lowercase name and an appended underscore (depending on compiler and platform of course). Passing arrays or strings back and forth is not so trivial typically; but for this example that wouldn't be needed.
Once the data is in a character array, you can read it into another variable as you are doing with the ADVANCE=no signature, ie.
do i = 1, numberIWant
read(tline, '(F10.15)', ADVANCE="no") tline1
end do
where tline should contain your number at the end of the loop.
Because of the record-based I/O, a READ statement will typically throw out what is after the end of the record. But the ADVANCE=no tells it not to.
If you know exactly at what position the value you want starts, you can use the T edit descriptor to initiate the next read from that position.
Let's say, for instance, that the width of each field is 10 characters and you want to read the fifth value. The read statement will then look something like the following.
read(file_unit, '(t41, f10.5)') value1
P.s.: You can dynamically create a format string at runtime, with the correct number after the t, by using a character variable as format and use an internal file write to put in this number.
Let's say you want the value that starts at position n. It will then look something like this (I alternated between single and double quotes to try to make it more clear where each string starts and stops):
write(my_format, '(a, i0, a)') "(t", n, ', f10.5)'
read(file_unit, my_format) value1

Resources