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)
Related
everyone!
I've posted a similar problem, initially on Stackexchange; it was moved here and can be found at the link: Declaring a functional recursive sequence in Matlab I'm trying to do something similar in this post, but I've figured that Matlab isn't the place to do it. I'll have to use Pari-GP; and at this point there's no two ways about it.
This is essentially a coding project I've made for myself; which is to effectively numerically evaluate a certain construction of the Tetration function. I've been able to code it fairly well in MatLab; the trouble is, as we are dealing with large numbers like e^e^e^e^e^e^e; these short circuit in MatLab. Pari-GP has a much better understanding of numbers which would usually cause overflows; and I'm now fully realizing why it's used consistently by the Tetration community.
Nonetheless, the Matlab code works for small numbers and numbers with a niceness to them (well placed imaginary argument). For completeness of this question; the github repository for the matlab code is https://github.com/JmsNxn92/Recursive_Tetration This isn't the code we want though; I've optimized it further; this isn't up to date totally. But for the purpose of this question, it's enough.
Now, I'm not the best programmer. I haven't programmed since '09, maybe; but I still know my way around. But it's more that I have the framework of coding; and less the actual syntax. Imagine being well acquainted with french philosophy and french writing; but stumbling your words when ordering a cafe.
As to that, I'll stop beating around the bush, and get to the question.
If I define a function beta_function in Pari-GP and write it as,
beta_function(z,l,n) =
{
out = 0;
for(i=0,n-1,
out = exp(out)/(exp(l*(n-i-z)) +1));
out;
}
Everything is good, and it works. Now the code for beta_function in MatLab isn't very different. There's nothing more complex being added. As I originally asked for MatLab, I'm asking again for Pari-GP. This is how to code a function tau_K(z,l,n,k); which is perfectly doable. I'm just missing something obvious.
The code for tau_K(z,l,n,k) in MatLab is attached below. A friendly person on here explained how to do this in MatLab; for those of you interested, I wasn't really defining the recursion properly beforehand. Here is the current MatLab code I'm using,
function f = tau_K(z,l,n,k)
if k == 1
f = -log(1+exp(-l*z));
return
end
f = log(1 + tau_K(z+1,l,n,k-1)./beta_function(z+1,l,n)) - log(1+exp(-l*z));
end
The question is simple. How would one define this recursion in Pari-GP; how do you code this in Pari-GP?
Everything seems to be collapsing towards a return value at 0, when I try to directly translate this code. And honest to god; I know it's just because I'm making some syntax error in how I'm calling the output into the next iteration. I've tried everything I could think of. And the tutorials, they don't seem to be helping. I've tried next to everything. And at this point, I know I'm missing something stupid syntactically.
I'm just hoping someone here would be so helpful as to explain this to me like I'm in kindergarten. I've heard that tail recursion is important here. And if so, how would I code this in? Simply add in a variable which keeps track of everything?
Again, thanks if you got this far into the question.
When asking questions, it would help if you would provide expected output for some specified given arguments, otherwise it is hard to test. I don't know MATLAB, but your functions could be written in PARI:
beta_function(z,l,n)={
my(out = 0);
for(i=0,n-1,
out = exp(out)/(exp(l*(n-i-z)) +1));
out;
}
tau_K(z,l,n,k)={
if(k == 1,
-log(1+exp(-l*z)),
log(1 + tau_K(z+1,l,n,k-1)/beta_function(z+1,l,n)) - log(1+exp(-l*z))
)
}
In the beta_function, it is important to put my() around out = 0. This keeps the variable local to the function. Failure to do this, means that out will be a global variable, and many subtle bugs can arise.
PARI is a functional programming language which means you often don't need to assign things explicitly to temporary variables. For example if will return a value and this can be returned from your tau_K function (in your MATLAB code you assign to a temporary variable f, but in PARI this is not necessary).
There are no issues with calling a function recursively. In this case, tau_K can just call itself as needed.
In the MATLAB program you have ./. I don't know what this means - I have replaced by / which is just the normal division operator.
Before running you will need to set some precision for the numeric operations. The easiest way to achieve this is to enter \p100 at the PARI-GP prompt. (or \p1000 if you need a 1000 decimal digits of precision). It is possible to control precision dynamically, if you need some part of the calculation performed at high precision and other parts at a lower precision or if the precision needs to be dependent on n.
My question is that given an array A, how can you give another array identical to A except changing all negatives to 0 (without changing values in A)?
My way to do this is:
B = A;
B(B<0)=0
Is there any one-line command to do this and also not requiring to create another copy of A?
While this particular problem does happen to have a one-liner solution, e.g. as pointed out by Luis and Ian's suggestions, in general if you want a copy of a matrix with some operation performed on it, then the way to do it is exactly how you did it. Matlab doesn't allow chained operations or compound expressions, so you generally have no choice but to assign to a temporary variable in this manner.
However, if it makes you feel better, B=A is efficient as it will not result in any new allocated memory, unless / until B or A change later on. In other words, before the B(B<0)=0 step, B is simply a reference to A and takes no extra memory. This is just how matlab works under the hood to ensure no memory is wasted on simple aliases.
PS. There is nothing efficient about one-liners per se; in fact, you should avoid them if they lead to obscure code. It's better to have things defined over multiple lines if it makes the logic and intent of the algorithm clearer.
e.g, this is also a valid one-liner that solves your problem:
B = subsasgn(A, substruct('()',{A<0}), 0)
This is in fact the literal answer to your question (i.e. this is pretty much code that matlab will call under the hood for your commands). But is this clearer, more elegant code just because it's a one-liner? No, right?
Try
B = A.*(A>=0)
Explanation:
A>=0 - create matrix where each element is 1 if >= 0, 0 otherwise
A.*(A>=0) - multiply element-wise
B = A.*(A>=0) - Assign the above to B.
This question already has answers here:
Dynamic variables matlab
(2 answers)
Closed 8 years ago.
I was wondering how I can use a for loop to create multiple matrix when given a certain number.
Such as If 3 was given I would need three matricies called: C1, C2 and C3.
k = 3
for i = 1:K
C... = [ ]
end
Not sure how to implement this.
The first thing coming in mind is the eval function mentioned by Dennis Jaheruddin, and yes, it is bad practice. So does the documentation say:
Why Avoid the eval Function?
Although the eval function is very powerful and flexible, it not
always the best solution to a programming problem. Code that calls
eval is often less efficient and more difficult to read and debug than
code that uses other functions or language constructs. For example:
MATLABĀ® compiles code the first time you run it to enhance performance for future runs. However, because code in an eval
statement can change at run time, it is not compiled.
Code within an eval statement can unexpectedly create or assign to a variable already in the current workspace, overwriting existing
data.
Concatenating strings within an eval statement is often difficult to read. Other language constructs can simplify the syntax in your
code.
The "safer" alternative is the function assignin:
The following will do exactly what you want:
letter = 'C';
numbers = 1:3;
arrayfun(#(x) assignin('base',[letter num2str(x)],[]),numbers)
I know cases where you need to create variables likes this, but in most cases it is better and more convenient to use cell arrays or structs.
The trick is to use a cell array:
k=3
C=cell(k,1)
for t=1:k
C{t}= rand(t)
end
If each matrix is of equal size, you would probably just want a three dimensional matrix rather than a cell array.
You now have one cell array,but can access the matrices like this:
C{2} %Access the second matrix.
The use of eval is almost inevitable in this case:
k = 3;
for i = 1:k
eval(sprintf('C%d = [];', i));
end;
Mind you that generating variable names for data storage rather than indexing them (numerically -- see the solution of Dennis Jaheruddin based on cell arrays -- or creating a dynamic struct with named fields that store the data) is almost always a bad idea. Unless you do so to cope up with some weird scripts that you don't want to / cannot modify that need some variables already created in the global workspace.
This question may initially appear similar to this other question but my situation is a little bit different.
I have a function 'deriv' that takes a symbolic expression as its input, then takes the first derivative of that symbolic expression. That derivative is then converted into an anonymous function using matlabFunction(), and is then evaluated over an array of points. I also use the anonymous function later in some other code.
The problem I'm having is that sometimes the input symbolic expression happens to be linear, and thus the derivative is constant; therefore the anonymous function is also a constant. When I evaluate the anonymous function over the array of points, I only get one output instead of an array of outputs.
Here's some code showing what I'm doing. For the sake of simplicity here, let's assume that the symbolic input expressions will involve only one symbolic variable called q.
function[derivFun,derivVals] = deriv(input)
derivSym = diff(input,q);
derivFun = matlabFunction(derivSym,'vars',q);
evalPoints = [1;2;3;4;5]; %in my true application, a much larger array
derivVals = derivFun(evalPoints);
end
So if the input is q^2, then the output derivVals will be [2;4;6;8;10]. But if the input happens to be, say, 3*q, then derivVals will be 3 (just a single scalar). What I'd like is for derivVals to be [3;3;3;3;3].
That is, I'd like derivVals to be the same size as evalPoints even if the input function happens to be linear (or constant). And I don't know ahead of time what the input expression will be.
Can anyone give suggestions for a scheme that would do that? I understand that a constant anonymous function will just return a single constant scalar, regardless of the size of its input. What I'm hoping for is perhaps some way to recognize when the anonymous function is constant and then still cause derivVals to be the same size as evalPoints.
I know that I could use a for loop to evaluate derivFun for every row of evalPoints, but I'd like to avoid using such a loop if possible.
Thank you for your time and consideration.
I think that this is a slightly simpler solution. The issue is that you're using matlabFunction, which simplifies down the equations and doesn't allow much customization. However, you can create an anonymous function of an anonymous function. Just add the this line right after your matlabFunction line:
derivFun = #(evalPoints)derivFun(evalPoints)+zeros(size(evalPoints));
This only evaluates the original derivFun once. However, I do like you symvar solution (just remember that adding zeros is always better than multiplying ones).
Not 100% sure I got the problem correctly.
Would this solve your issue?:
if isscalar(derivVals)
derivVals = repmat(derivVals, size(evalPoints));
end
I am trying to vectorise a for loop. I have a set of coordinates listed in a [68x200] matrix called plt2, and I have another set of coordinates listed in a [400x1] matrix called trans1. I want to create a three dimensional array called dist1, where in dist1(:,:,1) I have all of the values of plt2 with the first value of trans1 subtracted, all the way through to the end of trans1. I have a for loop like this which works but is very slow:
for i=1:source_points;
dist1(:,:,i)=plt2-trans1(i,1);
end
Thanks for any help.
If I understood correctly, this can be easily solved with bsxfun:
dist1 = bsxfun(#minus, plt2, shiftdim(trans1,-2));
Or, if speed is important, use this equivalent version (thanks to #chappjc), which seems to be much faster:
dist1 = bsxfun(#minus, plt2, reshape(trans1,1,1,[]));
In general, bsxfun is a very useful function for cases like this. Its behaviour can be summarized as follows: for any singleton dimension of any of its two input arrays, it applies an "implicit" for loop to the other array along the same dimension. See the doc for further details.
Vectorizing is a good first optimization, and is usually much easier than going all in writing your own compiled mex-function (in c).
However, the golden middle-way for power users is Matlab Coder (this also applies to slightly harder problems than the one posted, where vectorization is more or less impossible). First, create a small m-file function around the slow code, in your case:
function dist1 = do_some_stuff(source_points,dist1,plt2,trans1)
for i=1:source_points;
dist1(:,:,i)=plt2-trans1(i,1);
end
Then create a simple wrapper function which calls do_some_stuff as well as defines the inputs. This file should really be only 5 rows, with only the bare essentials needed. Matlab Coder uses the wrapper function to understand what typical proper inputs to do_some_stuff are.
You can now fire up the Matlab Coder gui from the Apps section and simply add do_some_stuff under Entry-Point Files. Press Autodefine types and select your wrapper function. Go to build and press build, and you are good to go! This approach usually bumps up the execution speed substantially with almost no effort.
BR
Magnus