Playing with matrix and putting in number values

I would like to have a matrix such as X
I have a word ABCD
this word has a sign number 12
The matrix X is made as
X=zeros(5,5)
I have desided that it will be like:
start A B C D
start 0 0 0 0 0
A 0 0 0 0 0
B 0 0 0 0 0
C 0 0 0 0 0
D 0 0 0 0 0
I will go from start to A and put the number 12 in X(start,A) position
then I go from A to B and put the number 12 in X(A,B) position
and so on
the rows are from and columns are to
How can I put the number in those positions, and how can I tell the matrix that for example position X(3,3) should be used and put number in if, in the given word you came to something like BB, or as in this example we have ABCD, how can I tell the matrix that when you come to CD then put a value of 12 in X(4,5)?
The matrix X here needs to understand that if I start a word with A so it put a number 12 in position X(1,2) then I come to AB, so I come from A to B, so the value 12 should be put in X(2,3) and so on until ABCD word is done (which means do this once for BC and once for CD, and save the the matrix X with the new valuses of 12 it god in those positions.
A bit difficult to explain, but I hope it makes sence

 Accepted Answer

There seems to be a few things missing from your description, such as where the number 12 comes from, and how you want to handle the situation where a sequence of letters is repeated (if the string was ABABABA for example). But, this code will do what you indicated, and you will have to work out the remaining details.
word = 'ABCD';
magicNumber = 12;
% Start by assigning a unique index to each unique letter.
[uniqueLetters,~,ind] = unique(word);
X = zeros(numel(uniqueLetters)+1);
% Increment the unique indices to account for the "start" index.
ind = ind(:)'+1;
% Append "1" to the beginning to indicate "start".
ind = [1 ind];
% Loop through the vector of indices, recording the pairings.
for p = 1:numel(word)
% Note this just overwrites the previous value if a pairing of letters
% is repeated.
X(ind(p),ind(p+1)) = magicNumber;
end
disp(X)
% For fun, put this into a table, so you have nice row and column headers.
labels = ["Start"; string(uniqueLetters')];
tbl = array2table(X,"RowNames", labels, "VariableNames", labels);
disp(tbl)

5 Comments

Your code looks magnificent, can you expalain these lines in the code please:
[uniqueLetters,~,ind] = unique(word);
and
ind = ind(:)'+1;
and
ind = [1 ind];
and
X(ind(p),ind(p+1))
Is 'ind' a word, or is it a function, what does it do for example in [uniqueLetters,~,ind]
and what is uniqueLetters?
I also need to ask if I already had a matrix as:
X = zeros(95,95);
and I would need to read from a file which has these three lines in it:
12 matthew
10 jonathan
5 david
so instead of the number 12, I would need to add 12, 10, 5 to the matrix, such as the same way the code above did for ABCD and the number 12, but for next line read from the file, I will add 10 to those positions to which it applies to, and for david I will also add 5 to positions to which it applies to.
so for example as 'at' is in both matthew and jonathan, the value in the X(a,t) will at the end be 22 and it needs to be stored in the matrix. I will write the matrix then to a file.
I tried to do some changes to the code so that in a matrix with 95 rows and 95 columns it would save those values which apply to same positions, but my for loop is some how not functioning.
Here instead of reading from a file we can imagine this matrix if it makes it easier:
a = [12 matthew
10 jonathan
5 david];
*The matrix X is 95 x 95 because including the start point, it counts from the 33 ascii to the 126 ascii.
The file I will read from will be long, but here I have just extracted three values.
I treid to add the values by changing the inside of for loop to this:
X(ind(i),ind(i+1)) = X(ind(i),ind(i+1))+ number;
*number is gotton from where we have 12, or 10 or 5 in this a matrix (which I will replace with a longer file). These numbers coud be such as 23347 but I choose easy numbers for the matter of this question
My result will only be stored one time I think and as:
disp(X);
Columns 1 through 17
0 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0
could you help this please
*and we won't need the row and column headers, as I will only save the values inside the matrix into a file.
Starting with unique
word = 'ABCD';
[uniqueLetters,~,ind] = unique(word);
This code isn't strictly necessary in your example case (with the string 'ABCD'), but it is there in case the letters are not sorted or there are duplicate letters. I'm not 100% sure what your requirements are, so this line may need to be modified based on your desired requirements.
The variable word is a character vector with 1 element per letter. The unique function takes that vector and returns a new vector called uniqueLetters that has all the unique letters in the word. In this case, uniqueLetters is just 'ABCD' because there are no duplicate letters. However, if you imagine a word that was CABDABCCDAA, then the output from unique would be 'ABCD' because those are the four unique letters. If you want them sorted in the original order ('CABD') then you can call unique(word, 'stable').
The third output from unique is a little tricky. It is the indices into uniqueLetters that would be needed to reconstruct the original vector. This is easier to explain with an example. Imagine word was 'BADC'. The uniqueLetters would be 'ABCD'. If you wanted to get back to the original word from uniqueLetters, you would resample using the vector [2143]. In other words: The second letter (B) followed by the first letter (A) followed by the fourth letter (D) followed by the third letter (C).
word = 'ABCD';
[uniqueLetters,~,ind] = unique(word)
uniqueLetters = 'ABCD'
ind = 4×1
1 2 3 4
uniqueLetters(ind) % returns 'ABCD'
ans = 'ABCD'
This may make more sense with the more complicated example of CABDABCCDAA. To recreate that original string from ABCD, you can use the variable ind like this:
word = 'CABDABCCDAA';
[uniqueLetters,~,ind] = unique(word);
disp(ind') % ind basically represents the original string as indexes into the alphabet
3 1 2 4 1 2 3 3 4 1 1
uniqueLetters(ind) % returns 'CABDABCCDAA'
ans = 'CABDABCCDAA'
Manipulating the ind variable
Once you've run unique, the ind variable is a vector with numbers representing each letter in the input word. 1 for the first letter in the set of letters ('A') 2 for the second letter in the set of letters ('B'), etc.
There are two problems with this vector:
  1. The vector is a column vector instead of a row vector. For whatever reason, the output from unique is a column instead of a row vector. We need to transpose the column vector back into a row vector. That isn't strictly necessary, I could have used another approach.
  2. MATLAB is 1-based, and you want your first element to be "Start" (not "A"). This means the first character ("A") should be 2 (not 1). The second character ("B") should be 3, etc.
To apply both these fixes, I am using this line of code:
ind = ind(:)'+1;
This is actually doing three operations, let me break them into those separate operations:
% Force 'ind' to be a column vector. Because 'ind' is already a column
% vector, this isn't actually doing anything. This is protective
% programming. If, for whatever reason, 'ind' were a row vector, this line
% of code guarantees it is converted into a column vector.
ind = ind(:);
% Now that we have guaranteed that 'ind' is a column vector, transpose it
% back into a row vector. Once this line runs, we are guaranteed to have a
% row vector.
ind = ind';
% Now we need to apply the offset so the first letter is 2, the second
% letter is 3, etc.
ind = ind + 1;
Adding start to your "word"
At this point, your word has been converted from a character vector ('ABCD') into a vector of indices ([1 2 3 4]) then incremented by one to get the indices [2 3 4 5].
Your question wanted to track the "start" character as though it were a distinct character at the beginning of the word. This line of code is simply appending "1" to the beginning of the vector. Now that "2" represents the first character ("A"), "1" can represent "Start".
ind = [1 ind];
The output is now just [1 2 3 4 5], representing '<start>ABCD'.
Updating your matrix
All that is left is to update your matrix. You have a 5 x 5 matrix, and you want to set each value based on pairs of values. There are 5 characters, '<start>ABCD', represented by ind = [1 2 3 4 5]. We are looping through them, starting with p = 1. You want to look at pairs of letters, so I'm looking at ind(p) (the first letter) and ind(p+1) (the second letter). The loop runs 4 times:
  1. p = 1, so you are working with the first letter (<start>) and the second letter ('A'), and setting X(1,2) = 12, signifying that A (character 2) occurred after the <start> (character 1).
  2. p = 2, so you are working with the second letter ('A') and the third letter ('B'), and setting X(2,3) = 12, signifying that B (character 3) occurred after the A (character 2).
  3. etc.
@Nicle Davidson Your new question is quite a bit more complicated than your existing question. I suggest you post a new question to MATLAB Answer (you can refer back to this question) with the code you've written so far.
Some tips: If you had mentioned you were interested in the ASCII values, that actually makes things a touch easier. MATLAB character vectors store the ASCII code internally, and you can perform math on those values. To convert the ASCII codes 33 (!) through 126 (~) into the numbers 2 through 94 you can just "subtract" ! from your vector:
word = 'Hello, World!';
double(word) % See the numeric representation (ASCII) for each character.
ans = 1×13
72 101 108 108 111 44 32 87 111 114 108 100 33
word-'!'
ans = 1×13
39 68 75 75 78 11 -1 54 78 81 75 67 0
There are a few options for storing your list of word -> number pairings. My suggestion is just two vectors: One with your words, another with the corresponding numbers. For example:
words = ["matthew", "jonathan", "david"];
numbers = [12 10 5];
I hope that helps you get a little farther along.
Thank you @Benjamin Kraus for your precious answer, your time and effort.
The addition problem however is left as if we go back to the last question it is needed to add the number to those positions say we have 12 Ellen then X(start,E) should be 12, X(E,l) should be 12 etc.
Then we come to next line in the file, and it is 15 Lenon, so X(start,L) should be 15, X(L,e) should be 15, 'but' now X(e,n) should be 12+15 also 27, then again X(n,o) should be 15 etc.
It will symbolizes how many times for example the combination which starts from 'n' and goes to 'o' is used. In the first word it was used 12 times, the number 12 stands for this. In the second word/or the line of text we read from text document, it has been used 15 times. So therefor we should keep track of how many times the combination is used.
I will make a new post for this, as you mentioned. Do you know how should I refer to this post? Is there any reference number or any special way to do so
I am thankful for your answer as I learnt a lot, and I will choose accept, however the problem is not solved yet.
Any help would be appreciated. Please see the link to the question further:
https://se.mathworks.com/matlabcentral/answers/1459764-working-with-numbers-and-matrix

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!