define a 4th rank tensor in Maple - matlab

I am a newbie in Maple. Could you please help me to convert the following short code from Matlab to Maple:
I=0.0;
for i1=1:3
I(i1,i1,i1,i1)=1.0;
end
I've tried to write it like:
unprotect(I);
I:=0.0;
for i1 from 1 to 3 do
for i2 from 1 to 3 do
for i3 from 1 to 3 do
for i4 from 1 to 3 do
if i1=i2 and i2=i3 and i3=i4 then I[i1,i2,i3,i4]:=1.0;
else I[i1,i2,i3,i4]:=0.0;
end if;
od;
od;
od;
od;
But it gives the following error:
Error, illegal use of an object as a name
Error, illegal use of an object as a name
Can anybody tell me what's wrong?
Thank you,

It'd be easier if you didn't insist on using the name I, which in Maple has the special meaning of the sqrt of -1.
restart;
interface(imaginaryunit=j):
local I:=Array((1..3)$4,datatype=float[8]);
for i1 from 1 to 3 do
I[i1,i1,i1,i1]:=1.0;
end do:
The above produces I as a 4-dimensional Array, where each dimension has a width of three elements. And the three "long diagonal" elements are all initialized to 1.0. And the Array can contain hardware double precision floats. And all the other elements are 0.0 by default.
Is that what you were trying to do?
If you don't insist on calling assigning it to the special name I then things are easier. Eg,
restart;
II:=Array((1..3)$4,datatype=float[8]):
for i1 from 1 to 3 do
II[i1,i1,i1,i1]:=1.0;
end do:
You cannot properly override/disable the special meaning of I merely by unprotecting it. (And even if you could, unprotecting and redefining I is an unworkable idea since a significant portion of Maple commands would then no longer compute properly in the given session.)
Recent versions of Maple allows you to create a so-called top-level "local" instance of that name, which can be used separately from the usual global name I. If you insist on that route, and if your Maple version is recent enough to support that, then you'd probably also want to change the
interface setting for the imaginary unit (sqrt of -1) so that things don't get too confusing. That's why I showed it in the first example above.
But I really think that you'd find things easiest if you just used another name, like II or what have you.
You don't need to put the datatype=float[8] restriction on the Array. But if your subsequent code mimics some (originally) Matlab code then maybe floats are all that will be assigned into the Array. And some operations on Arrays can be much faster, with it. See how it goes.

Related

Using mean function in MATLAB yielding different results [duplicate]

This question already has answers here:
Subscript indices must either be real positive integers or logicals, generic solution
(3 answers)
Closed 3 years ago.
I have just recently started using MATLAB as it's pretty good for machine learning and the like.
Currently, I am working on some type of classification which is pretty long-winded and complicated if I tried to explain everything I am trying to accomplish therefore I will just state the exact code giving me problems.
So, I am given a 1010 x 1764 single type matrix by some function. say the matrix is called train_examples_2_2 as you can see on the right-hand side of the screenshot below.
As you can also see from the screenshot above (on the right-hand side), the calls to mean and std:
mean = mean(train_examples_2_2)
std = std(train_examples_2_2)
Yield the correct results.
However, when I run the same code several times sometimes I get an error on the line mean = mean(train_examples_2_2) stating:
Array indices must be positive integers or logical values.
The exact code I am concerned with is:
mean = mean(train_examples_2_2) % <----- error appears here
std = std(train_examples_2_2)
for i=1:size(train_examples_2_2,1)
train_examples_2_2(i,:) = train_examples_2_2(i,:) - mean;
train_examples_2_2(i,:) = train_examples_2_2(i,:) ./ std;
end
% end of standardisation process
where train_examples_2_2 is provided by some function that I did not create nor can modify.
According to the MATLAB documentation:
If A is a matrix, then mean(A) returns a row vector containing the
mean of each column.
which is what I get the first time I run the code upon opening Matlab but after that, it yields the aforementioned error.
I am using MATLAB R2018b.
I'm I making a simple mistake or could this possibly be a bug?
Thanks for taking the time to help out.
unlike let's say python you shouldn't/can't/mussn't re-define function names or default variables.
mean = mean(train_examples_2_2) % <----- error appears here
matlab doesn't distinguish between the callable mean() function and the variable ```mean``. especially confusing since indexing and calling sth is done by using round brackets.
So....?
call your variable sth. other than mean. mean_ will already do the trick.

Matlab not taking last number in array?

I've got a Subscripted assignment dimension mismatch problem.
I've already localized the issue, and know exactly what is going on, I just don't know why.
Here's the problematic piece of code:
mFrames(:,i) = vSignal(round(start:1:frameLength*samplingRate));
start=start+frameShift*samplingRate;
frameLength = frameLength+frameShift;
I've already checked what's going on in debugmode; usually my resulting column length of mFrames is 128, this stays the same until i=1004. Then, my column length changes to 127.
I've checked the values involved while in debug mode, and it simply does not make sense what is going on. At i==1004 start=32097 and frameLength*samplingRate=32224.
That's a difference of 127 meaning 128 points, that should work.
BUT when i assign a vector A=round(start:1:frameLength*samplingRate)
OR B=start:1:frameLength*samplingRate
In both cases I get a vector going from 32097 to 32223. This ALTHOUGH when I give in frameLength*samplingRate matlab is giving me 32224.
In other words, matlab is telling me it's using one number, but when I test I find it's using a different one.
Any help appreciated.
I suspect your 32224 is not actually 32224. MATLAB's default format only displays so many decimal places, so when dealing with floating point numbers, what is printed on screen is not necessarily the "exact" value.
Let's go back a step and look at how the synatx x = start:step:end works.
1:1:10 should give us numbers in steps of 1 from 1 to 10. Fair enough, that makes sense. What if we set the end value to something that's slightly above 10?
e.g.:
1:1:10.1
Well, it still gives us 1:1:10, (or 1:10, 1 being the default step) because we can't have values higher than the end-point, so 11 isn't a correct step.
So what about this:
1:1:9.99
Spoiler: it's the same as 1:9
And this?
1:1:9.9999999
Yep, still 1:9
But if we do this:
a = 9.9999999;
Then with default format, the value of a will be shown on the command line and in your list of workspace variables as 10.0000.
Now, if frameLength and samplingRate are both stored as floating point numbers, it's possible that the number you see as 32224 is not 32224 but very slightly below that. You can check this by changing your default format - e.g. format long at the command line - to show more decimal places.
The simplest solution is probably to do something like:
B=start:1:round(frameLength*samplingRate)
Or try to store the relevant values as integers (e.g., uint32).

Error in creating an array of even numbers

I don't know where am I doing wrong in this code.
I wanted to create an array of even nos. so I wrote the following code in matlab:
A=[];
n=2;
while n!=5
if n%2==0
A=[A n];
n++;
else
n++;
end
end
disp(A)
The following gets displayed as output:
2 3 4
I can't understand why all nos. between 1 to 5 are being displayed.
can anyone please explain where am I wrong.......
I think you're going wrong very early. Try this
A = 2:2:8
then go to the Matlab documentation and read about the colon operator. Then forget C and C++ (what's with all those n++ and the other syntax elements from foreign languages ?). Then forget about loops and learn about vectorisation, you'll get a lot more out of Matlab, with a lot less effort, that way.
I don't know where am I doing wrong in this code.
In MATLAB, the not-equal-to operator is ~=; != is invalid MATLAB syntax.
If you want to increment a variable n, you need to write n = n + 1; n++ is invalid MATLAB syntax.
The % character starts a line comment; it is not the modulo operator. Instead, you want to use either the rem function or the mod function (which are equivalent for nonnegative inputs).
Besides, you don't need a loop for creating such a simple row vector, in which elements follow an arithmetic sequence. Just use MATLAB's colon operator:
<start> : <step> : <bound>
or, more simply
<start> : <bound>
where the step is taken as 1.
Here, either
2:2:8
or
2 * (1 : 4)
will do the trick.

the where statement from f90 to matlab conversion

This is a part from a Fortran 90 code.
where (abs(A-B)>e)
no_converge=1
elsewhere
no_converge=0
end where
A and B are arrays of some particular dimensions, and e is a scalar. I have to say that I am not that familiar with either programming languages.
I have used the f2matlab but it does very poor job on this Fortran statement.
I am wondering whether the equivalent for a Matlab is something like this:
if abs(A-B)>e
no_converge=1 ;
else
no_converge=0 ;
end
Is this correct ?
The no_converge is a scalar (integer in Fortran declarations), used at different sections in order to begin some other loops.
I will really appreciate any suggestions here, and please let me know whether more information is needed.
Not correct, no. In the Fortran no_converge ought to be an array of the same size (and shape) as A and B; its elements will be set to 1 where abs(A-B)>e and 0 elsewhere. So in your Matlab code no_converge shouldn't be a scalar but an array. However, without sight of your declarations I'm just making educated guesses. Show us some (more) code.
I don't have Matlab on this computer so can't check, but if memory serves me well you can do something very similar, like this
no_converge(abs(A-B)>e) = 1
no_converge(abs(A-B)<=e) = 0
provided that no_converge is, as in the Fortran case, an array of the same size and shape as A and B.
The WHERE statement in Fortran sort of combines a loop with a conditional, but only for assignments.
no_convergence in the Fortran code must be a vector with (at least) the same extend as A and B. So, the code you provided is certainly incorrect.
I don't know whether you can do something similar in Matlab, but you can always do a explicit loop and test for convergence element-wise.
There WHERE construct in Fortran can be replaced by a MERGE one-liner which f2matlab may be better able to translate:
no_converge = merge(1,0,abs(A-B)>e)

Matlab: `gfrank` over GF(2^m)

I've been working with matrices over GF(2) in Matlab. Well, I've been working with 0/1 matrices that I've been treating as being defined over GF(2). I was surprised/happy to see that Matlab provides some functionality in the Communications System Toolbox for working over finite fields. In particular, if I want to find the rank of a matrix over a finite field, there are a couple of methods: (1) use gfrank on the matrices that I already have defined, or (2) use rank on a Galois field array (created with gf). For matrices over GF(2), the former method seems to be significantly faster; however, there's a problem...
The documentation for gfrank says that the function doesn't work over fields of the form GF(2^m). I double checked on a toy example, and specifying GF(2) as the field to work over seems to output correct results. Moreover, the function's m-file specifies GF(2) as the default field (by specifying the second argument as 2 if nargin < 2). Something has to be wrong here, and it seems to be the documentation. However, I'd hate to assume that the documentation is wrong only to find out much later that the computation doesn't always work over GF(2^m). Does anybody know for sure what's wrong here? Thanks for your help.