Disable MATLAB's implicit expansion - matlab

Recently, in R2016b a feature was added to MATLAB, which is causing a lot of headaches in the school where I teach.
Nowadays formulae, which traditionally would be considered illegal or at least shady maths are executed successfully:
[1, 2] + [3, 4]' -> [4, 5; 5, 6]
[1, 2]' + [3, 4, 5] -> [4, 5, 6; 5, 6, 7]
So adding a row vector to a column vector is treated as an addition of two matrices one can get from repeating the vectors up to the "suitable" dimensions. In older versions this would have produced an error message informing that the addition of matrices with different dimensions is not possible.
I think asking why is a bit broad, although if you do know why, I'd love to know. Instead I will ask, is there a way to disable this functionality? To novice programmers this is a world of hurt when the conventional mathematics doesn't seem to be in line and the resulting matrix often goes unnoticed causing errors only later on.
I can not see this being a useful part of MATLAB syntax and behavior, as it requires too much interpretation, reading into the intention of the programmer. repmat is there for a reason, and a dedicated function could be introduced to accommodate for the need of this thing.

As mentioned by #PhelypeOleinik, this is (since R2016b) a core part of the language, and for good reasons, as detailed in the blog post referred to.
However, if you REALLY want to disable it...
Make a folder somewhere on your path, called #double.
In this folder, make a file plus.m.
In the file, put something like the following:
function out = plus(in1, in2)
% do some things here
out = builtin('plus', in1, in2)
Where I have a comment above, you can put whatever code you like: which could include code that checks the inputs for the "size-compatibility" rules you want, and errors if it doesn't meet them.
Do something similar for the functions minus, times, ldivide, rdivide, power, and other functions you want to modify.
PS please don't actually do this, the developers worked very hard to implement implicit expansion, and they'll cry if they see you disabling it like this...

This feature was introduced in Matlab R2016b. In older versions, this expansion had to be done either with repmat or with bsxfun. Newer versions feature this implicit expansion of dimensions to vectorize the calculation.
In this blog post Steve Eddins, from MathWorks says that:
Other people thought that the new operator behavior was not sufficiently based on linear algebra notation. However, instead of thinking of MATLAB as a purely linear algebra notation, it is more accurate to think of MATLAB as being a matrix and array computation notation.
and it really does make sense in a computational context. I can say that for my uses, this implicit expansion does make things easier very often.
Of course, seeing this from the point of view of algebra, it doesn't make sense. But if you think about it, most computer language notation wouldn't make sense.
And since this is now part of the language, it shouldn't be possible to disable the feature (until Yair Altman tries to do so :P).

Related

matlab running all linprog algortithms (is there a matlab-list of algorithms?)

Matlab offers multiple algorithms for solving Linear Programs.
For example Matlab R2012b offers: 'active-set', 'trust-region-reflective', 'interior-point', 'interior-point-convex', 'levenberg-marquardt', 'trust-region-dogleg', 'lm-line-search', or 'sqp'.
But other versions of Matlab support different algorithms.
I would like to run a loop over all algorithms that are supported by the users Matlab-Version. And I would like them to be ordered like the recommendation order of Matlab.
I would like to implement something like this:
i=1;
x=[];
while (isempty(x))
options=optimset(options,'Algorithm',Here_I_need_a_list_of_Algorithms(i))
x = linprog(f,A,b,Aeq,beq,lb,ub,x0,options);
end
In 99% this code should be equivalent to
x = linprog(f,A,b,Aeq,beq,lb,ub,x0,options);
but sometimes the algorithm gives back an empty array because of numerical problems (exitflag -4). If there is a chance that one of the other algorithms can find a solution I would like to try them too.
So my question is:
Is there a possibility to automatically get a list of all linprog-algorithms that are supported by the installed Matlab-version ordered like Matlab recommends them.
I think looping through all algorithms can make sense in other scenarios too. For example when you need very precise data and have a lot of time, you could run them all and than evaluate which gives the best results.
Or one would like to loop through all algorithms, if one wants to find which algorithms is the best for LPs with a certain structure.
There's no automatic way to do this as far as I know. If you really want to do it, the easiest thing to do would be to go to the online documentation, and check through previous versions (online documentation is available for old versions, not just the most recent release), and construct some variables like this:
r2012balgos = {'active-set', 'trust-region-reflective', 'interior-point', 'interior-point-convex', 'levenberg-marquardt', 'trust-region-dogleg', 'lm-line-search', 'sqp'};
...
r2017aalgos = {...};
v = ver('matlab');
switch v.Release
case '(R2012b)'
algos = r2012balgos;
....
case '(R2017a)'
algos = r2017aalgos;
end
% loop through each of the algorithms
Seems boring, but it should only take you about 30 minutes.
There's a reason MathWorks aren't making this as easy as you might hope, though, because what you're asking for isn't a great idea.
It is possible to construct artificial problems where one algorithm finds a solution and the others don't. But in practice, typically if the recommended algorithm doesn't find a solution this doesn't indicate that you should switch algorithms, it indicates that your problem wasn't well-formulated, and you should consider modifying it, perhaps by modifying some constraints, or reformulating the objective function.
And after all, why stop with just looping through the alternative algorithms? Why not also loop through lots of values for other options such as constraint tolerances, optimality tolerances, maximum number of function evaluations, etc.? These may have just as much likelihood of affecting things as a choice of algorithm. And soon you're running an optimisation algorithm to search through the space of meta-parameters for your original optimisation.
That's not a great plan - probably better to just choose one of the recommended algorithms, stick to that, and if things don't work out then focus on improving your formulation of the problems rather than over-tweaking the optimisation itself.

Disable Matlab R2016b implicit expansion [duplicate]

Recently, in R2016b a feature was added to MATLAB, which is causing a lot of headaches in the school where I teach.
Nowadays formulae, which traditionally would be considered illegal or at least shady maths are executed successfully:
[1, 2] + [3, 4]' -> [4, 5; 5, 6]
[1, 2]' + [3, 4, 5] -> [4, 5, 6; 5, 6, 7]
So adding a row vector to a column vector is treated as an addition of two matrices one can get from repeating the vectors up to the "suitable" dimensions. In older versions this would have produced an error message informing that the addition of matrices with different dimensions is not possible.
I think asking why is a bit broad, although if you do know why, I'd love to know. Instead I will ask, is there a way to disable this functionality? To novice programmers this is a world of hurt when the conventional mathematics doesn't seem to be in line and the resulting matrix often goes unnoticed causing errors only later on.
I can not see this being a useful part of MATLAB syntax and behavior, as it requires too much interpretation, reading into the intention of the programmer. repmat is there for a reason, and a dedicated function could be introduced to accommodate for the need of this thing.
As mentioned by #PhelypeOleinik, this is (since R2016b) a core part of the language, and for good reasons, as detailed in the blog post referred to.
However, if you REALLY want to disable it...
Make a folder somewhere on your path, called #double.
In this folder, make a file plus.m.
In the file, put something like the following:
function out = plus(in1, in2)
% do some things here
out = builtin('plus', in1, in2)
Where I have a comment above, you can put whatever code you like: which could include code that checks the inputs for the "size-compatibility" rules you want, and errors if it doesn't meet them.
Do something similar for the functions minus, times, ldivide, rdivide, power, and other functions you want to modify.
PS please don't actually do this, the developers worked very hard to implement implicit expansion, and they'll cry if they see you disabling it like this...
This feature was introduced in Matlab R2016b. In older versions, this expansion had to be done either with repmat or with bsxfun. Newer versions feature this implicit expansion of dimensions to vectorize the calculation.
In this blog post Steve Eddins, from MathWorks says that:
Other people thought that the new operator behavior was not sufficiently based on linear algebra notation. However, instead of thinking of MATLAB as a purely linear algebra notation, it is more accurate to think of MATLAB as being a matrix and array computation notation.
and it really does make sense in a computational context. I can say that for my uses, this implicit expansion does make things easier very often.
Of course, seeing this from the point of view of algebra, it doesn't make sense. But if you think about it, most computer language notation wouldn't make sense.
And since this is now part of the language, it shouldn't be possible to disable the feature (until Yair Altman tries to do so :P).

Numerical Integral of large numbers in Fortran 90

so I have the following Integral that i need to do numerically:
Int[Exp(0.5*(aCosx + bSinx + cCos2x + dSin2x))] x=0..2Pi
The problem is that the output at any given value of x can be extremely large, e^2000, so larger than I can deal with in double precision.
I havn't had much luck googling for the following, how do you deal with large numbers in fortran, not high precision, i dont care if i know it to beyond double precision, and at the end i'll just be taking the log, but i just need to be able to handle the large numbers untill i can take the log..
Are there integration packes that have the ability to handle arbitrarily large numbers? Mathematica clearly can.. so there must be something like this out there.
Cheers
This is probably an extended comment rather than an answer but here goes anyway ...
As you've already observed Fortran isn't equipped, out of the box, with the facility for handling such large numbers as e^2000. I think you have 3 options.
Use mathematics to reduce your problem to one which does (or a number of related ones which do) fall within the numerical range that your Fortran compiler can compute.
Use Mathematica or one of the other computer algebra systems (eg Maple, SAGE, Maxima). All (I think) of these can be integrated into a Fortran program (with varying degrees of difficulty and integration).
Use a library for high-precision (often called either arbitray-precision or multiple-precision too) arithmetic. Your favourite search engine will turn up a number of these for you, some written in Fortran (and therefore easy to integrate), some written in C/C++ or other languages (and therefore slightly harder to integrate). You might start your search at Lawrence Berkeley or the GNU bignum library.
(Yes I know that I wrote that you have 3 options, but your question suggests that you aren't ready to consider this yet) You could write your own high-/arbitrary-/multiple-precision functions. Fortran provides everything you need to construct such a library, there is a lot of work already done in the field to learn from, and it might be something of interest to you.
In practice it generally makes sense to apply as much mathematics as possible to a problem before resorting to a computer, that process can not only assist in solving the problem but guide your selection or construction of a program to solve what's left of the problem.
I agree with High Peformance Mark that the best option here numerically is to use analytics to scale or simplify the result first.
I will mention that if you do want to brute force it, gfortran (as of 4.6, with the libquadmath library) has support for quadruple precision reals, which you can use by selecting the appropriate kind. As long as your answers (and the intermediate results!) don't get too much bigger than what you're describing, that may work, but it will generally be much slower than double precision.
This requires looking deeper at the problem you are trying to solve and the behavior of the underlying mathematics. To add to the good advice already provided by Mark and Jonathan, consider expanding the exponential and trig functions into Taylor series and truncating to the desired level of precision.
Also, take a step back and ask why you are trying to accomplish by calculating this value. As an example, I recently had to debug why I was getting outlandish results from a property correlation which was calculating vapor pressure of a fluid to see if condensation was occurring. I spent a long time trying to understand what was wrong with the temperature being fed into the correlation until I realized the case causing the error was a simulation of vapor detonation. The problem was not in the numerics but in the logic of checking for condensation during a literal explosion; physically, a condensation check made no sense. The real problem was the code was asking an unnecessary question; it already had the answer.
I highly recommend Forman Acton's Numerical Methods That (Usually) Work and Real Computing Made Real. Both focus on problems like this and suggest techniques to tame ill-mannered computations.

Using i and j as variables in MATLAB

i and j are very popular variable names (see e.g., this question and this one).
For example, in loops:
for i=1:10,
% Do something...
end
As indices into a matrix:
mat(i, j) = 4;
Why shouldn't they be used as variable names in MATLAB?
Because i and j are both functions denoting the imaginary unit:
http://www.mathworks.co.uk/help/matlab/ref/i.html
http://www.mathworks.co.uk/help/matlab/ref/j.html
So a variable called i or j will override them, potentially silently breaking code that does complex maths.
Possible solutions include using ii and jj as loop variables instead, or using 1i whenever i is required to represent the imaginary unit.
It is good practice to avoid i and j variables to prevent confusion about them being variables or the imaginary unit.
Personally, however, I use i and j as variables quite often as the index of short loops. To avoid problems in my own code, I follow another good practice regarding i and j: don't use them to denote imaginary numbers. In fact, MATLAB's own documentation states:
For speed and improved robustness, you can replace complex i and j by 1i.
So rather than avoiding two very commonly used variable names because of a potential conflict, I'm explicit about imaginary numbers. It also makes my code more clear. Anytime I see 1i, I know that it represents sqrt(-1) because it could not possibly be a variable.
In old versions of MATLAB, there used to be a good reason to avoid the use of i and j as variable names - early versions of the MATLAB JIT were not clever enough to tell whether you were using them as variables or as imaginary units, and would therefore turn off many otherwise possible optimizations.
Your code would therefore get slower just by the very presence of i and j as variables, and would speed up if you changed them to something else. That's why, if you read through much MathWorks code, you'll see ii and jj used fairly widely as loop indices. For a while, MathWorks might even have unofficially advised people to do that themselves (although they always officially advise people to program for elegance/maintainability rather than to whatever the current JIT does, as it's a moving target each version).
But that's rather a long time ago, and nowadays it's a bit of a "zombie" issue that is really much less important than many people still think, but refuses to die.
In any recent version, it's really a personal preference whether to use i and j as variable names or not. If you do a lot of work with complex numbers, you may want to avoid i and j as variables, to avoid any small potential risk of confusion (although you may also/instead want to only use 1i or 1j for even less confusion, and a little better performance).
On the other hand, in my typical work I never deal with complex numbers, and I find my code more readable if I feel free to use i and j as loop indices.
I see a lot of answers here that say It is not recommended... without saying who's doing that recommending. Here's the extent of MathWorks' actual recommendations, from the current release documentation for i:
Since i is a function, it can be overridden and used as a variable. However, it is best to avoid using i and j for variable names if you intend to use them in complex arithmetic. [...] For speed and improved robustness, you can replace complex i and j by 1i.
As described in other answers, the use of i in general code is not recommended for two reasons:
If you want to use the imaginary number, it can be confused with or overwritten by an index
If you use it as an index it can overwrite or be confused with the imaginary number
As suggested: 1i and ii are recommended. However, though these are both fine deviations from i, it is not very nice to use both of these alternatives together.
Here is an example why (personally) I don't like it:
val2 = val + i % 1
val2 = val + ii % 2
val2 = val + 1i % 3
One will not easily be misread for two or three, but two and three resemble each other.
Therefore my personal recommendation would be: In case you sometimes work with complex code, always use 1i combined with a different loop variable.
Examples of single letter indices that for if you don't use many loop variables and letters suffice: t,u,k and p
Example of longer indices: i_loop,step,walk, and t_now
Of course this is a matter of personal taste as well, but it should not be hard to find indices to use that have a clear meaning without growing too long.
It was pointed out that 1i is an acceptable and unambiguous way to write sqrt(-1), and that as such there is no need to avoid using i. Then again, as Dennis pointed out, it can be hard to see the difference between 1i and ii. My suggestion: use 1j as the imaginary constant where possible. It's the same trick that electrical engineers employ - they use j for sqrt(-1) because i is already taken for current.
Personally I never use i and j; I use ii and jj as shorthand indexing variables, (and kk, ll, mm, ...) and 1j when I need to use complex numbers.
Confusion with the imaginary unit has been well covered here, but there are some other more prosaic reasons why these and other single-letter variable names are sometimes discouraged.
MATLAB specifically: if you're using coder to generate C++ source from your MATLAB code (don't, it's horrible) then you are explicitly warned not to reuse variables because of potential typing clashes.
Generally, and depending on your IDE, a single-letter variable name can cause havoc with highlighters and search/replace. MATLAB doesn't suffer from this and I believe Visual Studio hasn't had a problem for some time, but the C/C++ coding standards like MISRA, etc. tend to advise against them.
For my part I avoid all single-letter variables, despite the obvious advantages for directly implementing mathematical sources. It takes a little extra effort the first few hundred times you do it, but after that you stop noticing, and the advantages when you or some other poor soul come to read your code are legion.
By default i and j stand for the imaginary unit. So from MATLAB's point of view, using i as a variable is somehow like using 1 as a variable.
Any non-trivial code contains multiple for loops, and the best practices recommend you use a descriptive name indicative of its purpose and scope. For times immemorial (and unless its 5-10 lines script that I am not going to save), I have always been using variable names like idxTask, idxAnotherTask and idxSubTask etc.
Or at the very least doubling the first letter of the array it is indexing e.g. ss to index subjectList, tt to index taskList, but not ii or jj which doesn't help me effortlessly identify which array they are indexing out of my multiple for loops.
Unless you are a very confused user I think there is very little risk in using variable names i and j and I use them regularly. I haven't seen any official indication that this practice should be avoided.
While it's true that shadowing the imaginary unit could cause some confusion in some context as mentioned in other posts, overall I simply don't see it as a major issue. There are far more confusing things you can do in MATLAB, take for instance defining false=true
In my opinion the only time you should probably avoid them is if your code specifically deals with imaginary numbers.

Using MATLAB's plotting features as an interactive part of a Fortran program

Although many of you will have a decent idea of what I'm aiming at, just from reading the title -- allow me a simple introduction still.
I have a Fortran program - it consists of a program, some internal subroutines, 7 modules with its own procedures, and ... uhmm, that's it.
Without going into much detail, for I don't think it's necessary at this point, what would be the easiest way to use MATLAB's plotting features (mainly plot(x,y) with some customizations) as an interactive part of my program ? For now I'm using some of my own custom plotting routines (based on HPGL and Calcomp's routines), but just as part of an exercise on my part, I'd like to see where this could go and how would it work (is it even possible what I'm suggesting?). Also, how much effort would it take on my part ?
I know this subject has been rather extensively described in many "tutorials" on the net, but for some reason I have trouble finding the really simple yet illustrative introductory ones. So if anyone can post an example or two, simple ones, I'd be really grateful. Or just take me by the hand and guide me through one working example.
platform: IVF 11.something :) on Win XP SP2, Matlab 2008b
The easiest way would be to have your Fortran program write to file, and have your Matlab program read those files for the information you want to plot. I do most of my number-crunching on Linux, so I'm not entirely sure how Windows handles one process writing a file and another reading it at the same time.
That's a bit of a kludge though, so you might want to think about using Matlab to call the Fortran program (or parts of it) and get data directly for plotting. In this case you'll want to investigate Creating Fortran MEX Files in the Matlab documentation. This is relatively straightforward to do and would serve your needs if you were happy to use Matlab to drive the process and Fortran to act as a compute service. I'd look in the examples distributed with Matlab for simple Fortran MEX files.
Finally, you could call Matlab from your Fortran program, search the documentation for Calling the Matlab Engine. It's a little more difficult for me to see how this might fit your needs, and it's not something I'm terribly familiar with.
If you post again with more detail I may be able to provide more specific tips, but you should probably start rolling your sleeves up and diving in to MEX files.
Continuing the discussion of DISLIN as a solution, with an answer that won't fit into a comment...
#M. S. B. - hello. I apologize for writing in your answer, but these comments are much too short, and answering a question in the form of an answer with an answer is ... anyway ...
There is the Quick Plot feature of DISLIN -- routine QPLOT needs only three arguments to plot a curve: X array, Y array and number N. See Chapter 16 of the manual. Plus only several additional calls to select output device and label the axes. I haven't used this, so I don't know how good the auto-scaling is.
Yes, I know of Quickplot, and it's related routines, but it is too fixed for my needs (cannot change anything), and yes, it's autoscaling is somewhat quircky. Also, too big margins inside the graf.
Or if you want to use the power of GRAF to setup your graph box, there is subroutine GAXPAR to automatically generate recommended values. -2 as the first argument to LABDIG automatically determines the number of digits in tick-mark labels.
Have you tried the routines?
Sorry, I cannot find the GAXPAR routine you're reffering to in dislin's index. Are you sure it is called exactly like that ?
Reply by M.S.B.: Yes, I am sure about the spelling of GAXPAR. It is the last routine in Chapter 4 of the DISLIN 9.5 PDF manual. Perhaps it is a new routine? Also there is another path to automatic scaling: SETSCL -- see Chapter 6.
So far, what I've been doing (apart from some "duck tape" solutions) is
use dislin; implicit none
real, dimension(5) :: &
x = [.5, 2., 3., 4., 5.], &
y = [10., 22., 34., 43., 15.]
real :: xa, xe, xor, xstp, &
ya, ye, yor, ystp
call setpag('da4p'); call metafl('xwin');
call disini(); call winkey('return');
call setscl(x,size(x),'x');
call setscl(y,size(y),'y')
call axslen(1680,2376) !(8/10)*2100 and 2970, respectively
call setgrf('name','name','line','line')
call incmrk(1); call hsymbl(3);
call graf(xa, xe, xor, xstp, ya, ye, yor, ystp); call curve(x,y,size(x))
call disfin()
end
which will put the extreme values right on the axis. Do you know perhaps how could I go to have one "major tick margin" on the outside, as to put some area between the curve and the axis (while still keeping setscl's effects) ?
Even if you don't like the built-in auto-scaling, if you are already using DISLIN, rolling your own auto-scaling will be easier than calling Fortran from MATLAB. You can use the Fortran intrinsic functions minval and maxval to find the smallest and largest values in the data, than write a subroutine to round outwards to "nice" round values. Similarly, a subroutine to decide on the tick-mark spacing.
This is actually not so easy to accomplish (and ideas to prove me wrong will be gladly appreciated). Or should I say, it is easy if you know the rough range in which your values will lie. But if you don't, and you don't know
whether your values will lie in the range of 13-34 or in the 1330-3440, then ...
... if I'm on the wrong track completely here, please, explain if you ment something different. My english is somewhat lacking, so I can only hope the above is understandable.
Inside a subroutine to determine round graph start/end values, you could scale the actual min/max values to always be between 1 and 10, then have a table to pick nice round values, then unscale back to the correct range.
--
Dump Matlab because its proprietary, expensive, bloated/slow and codes are not easy to parallelize.
What you should do is use something on the lines of DISLIN, PLplot, GINO, gnuplotfortran etc.