This one of the things that has always bothered me about Matlab. I understand why arrays start at 1 and not at 0 like in any other programming language, but why is != ~= in Matlab?
The tilde character (~) is generally used as the bitwise NOT operator.
As the ! character is reserved for an other usage (OS command), I guess it's not a bad choice.
In mathematical logic ~ is an old-fashioned way to write ¬
In logic tilde can mean "not", which may be confusing as in math tilde can be "equivalence" or "approx". However, it is found on more keyboards than the less ambiguous ¬. Watch out, as tilde can also mean bitwise not :)
Why is .not..eq. represented by ~= ? For the same reason that it is not represented as =!= or /= or any of the hundred and one other conventions used in programming languages.
And the twiddle, or ~, is widely used in logic texts to mean NOT.
Related
Let's assume a is a constant and x is my variable with respect to time, so basically x(t).
Then in Maxima , what is the best way to replace 'diff(a*x,t) with a*'diff(x,t) automatically without use subst command.
The reason I don't to use subst is that I have many variables and higher order derivatives. It is not efficient to use subst to replace all the occurrences.
Thanks.
UPDATE
I have tried with depends(x,t) command, but it only works with the simple case. Here is an minimal example of my situation.
depends([x,y],t);
eq1:diff(x,t)-b=c;
eq2:subst([x=a*y],eq1);
sol_dy=solve(eq2,diff(y,t))
Of course here a,b,c are constants and x, y are variables on t.
Maxima can not solve diff(y,t) directly. How do deal with it?
I see that 'diff(...) (i.e. derivative noun expression) isn't linear (doesn't distribute over + and doesn't factor out constants) but diff(...) (verb expression) is linear. That's a misfeature, at least.
I was going to suggest declare(nounify(diff), linear) but that makes derivatives come out as 0 in your example ... this is probably a bug, I'll have to think more about it.
Try ev(eq2, nouns); to re-evaluate the derivatives as verbs -- I think that should cause the constant to factor out.
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)
I spent a couple of hours debugging a problem that I would have thought would have been a syntax error.
a = zeros(3);
for i=1:1size(a,2) % note the missing colon between 1 and size(a,2)
i
end
The following only displays
ans = 3
1
Essentially, it seems Matlab/Octave parses the above as:
for i=1:1
size(a,2)
i
end
Note however that
i=1:1size(a,2)
produces a syntax error. Is there a good reason that Matlab/Octave has this for loop syntax? Is there something that it's supposed to make easier? Just curious if anyone else has any thoughts about it. Thanks.
It is indeed a bit of a surprise that Matlab's syntax allows this. I don't know why this is allowed. One reason might be to allow for-loops on one line:
>> for i=1:3 disp(i);end
1
2
3
But interestingly, removing the space is not allowed:
>> for i=1:3disp(i);end
for i=1:3disp(i);end
|
Error: Unexpected MATLAB operator.
This reason for this is probably that a number followed by d is another way of writing a floating point number (3d10 == 3e10), so the parser/tokenizer initially thinks you define a number, but then gets confused when it sees the i. Daniel's example with fprintf does work, since a number followed by an f is not a valid number, so the tokenizer understands that you started a new token.
I guess that many years ago (>30?), when they defined matlab's syntax, they did not foresee that this could introduce this kind of hard-to-spot problems. I guess matlab was originally written by engineers for engineers, and not by someone who knows how to design a general purpose programming language. Other languages like C or Python use punctuation to separate loop conditions from loop body, so there is no ambiguity. I don't know if it is still possible to correct Matlab's syntax, since it might break old code that relies on the current behavior.
At least, if you use a recent version of Matlab, the editor warns for various problems in your code. Paying attention to the small red dashes in the right hand border could have saved you a few hours of debugging time (but maybe you were using octave). I try to make it a habit to fix all the warnings it indicates. For your code, it shows the following:
Your code is equivalent to
a = zeros(3);
for i=1:1
size(a,2)
i
end
There are some places where everyone would use newline or white space, but the parser itself does not require.
A minimal loop:
for i=1:3fprintf('%d',i),end
but I recommend to use at least a comma seperated version, everything else is horrible to read:
for i=1:3,fprintf('%d',i),end
When teaching people about Matlab, it would be very nice if I could refer to Matlab's colon operator as something other than just "the colon operator". As you can read on this Mathworks blog, the operator has a number of different contexts. I'm referring specifically to the first use on that list, creating a list of numbers.
Does anyone have a clever phrase they use to refer to this operation?
I would call it the "range operator".
Linear Space Vector Generator would also do I think ...
There is one thing I do not like on Matlab: It tries sometimes to be too smart. For instance, if I have a negative square root like
a = -1; sqrt(a)
Matlab does not throw an error but switches silently to complex numbers. The same happens for negative logarithms. This can lead to hard to find errors in a more complicated algorithm.
A similar problem is that Matlab "solves" silently non quadratic linear systems like in the following example:
A=eye(3,2); b=ones(3,1); x = A \ b
Obviously x does not satisfy A*x==b (It solves a least square problem instead).
Is there any possibility to turn that "features" off, or at least let Matlab print a warning message in this cases? That would really helps a lot in many situations.
I don't think there is anything like "being smart" in your examples. The square root of a negative number is complex. Similarly, the left-division operator is defined in Matlab as calculating the pseudoinverse for non-square inputs.
If you have an application that should not return complex numbers (beware of floating point errors!), then you can use isreal to test for that. If you do not want the left division operator to calculate the pseudoinverse, test for whether A is square.
Alternatively, if for some reason you are really unable to do input validation, you can overload both sqrt and \ to only work on positive numbers, and to not calculate the pseudoinverse.
You need to understand all of the implications of what you're writing and make sure that you use the right functions if you're going to guarantee good code. For example:
For the first case, use realsqrt instead
For the second case, use inv(A) * b instead
Or alternatively, include the appropriate checks before/after you call the built-in functions. If you need to do this every time, then you can always write your own functions.