Is there a better way to write this in Matlab? - matlab

I have this code, but there must be a better efficient to write it:
rt= RealTrans;
rtsize=size(rt);
rtrows=rtsize(1);
Relative_Axis_Moves=[rt(1,1) rt(1,2) rt(1,3) rt(1,4) rt(1,5);
rt(2:rtrows,1)-rt(1:rtrows-1,1) rt(2:rtrows,2)-rt(1:rtrows-1,2)
rt(2:rtrows,3)-rt(1:rtrows-1,3) rt(2:rtrows,4)-rt(1:rtrows-1,4)
rt(2:rtrows,5)-rt(1:rtrows-1,5)];
There are two rows in the matrix. The first row ends at rt(1,5).
I also have the following code:
p1size=size(p1);
p1rows=p1size(1);
flank_edge_point=[0 0 0; p1(2:p1rows,2)-p1(1:p1rows-1,2) xy(2:p1rows,1)-xy(1:p1rows-1,1) xy(2:p1rows,2)-xy(1:p1rows-1,2); 0 0 xy(p1rows,2)];
How do i get xy(p1rows,2) value in matlab without p1rows?
I also have the code below which relies on the number of rows:
RAMrow=size(Relative_Axis_Moves);
RAMrow=RAMrow(1);
for i=1:RAMrow
L(i)= norm(Relative_Axis_Moves(i,:));
end
L=L';
L(RAMrow+1)= 0;
Any way to write this code more succinctly and efficiently would be greatly appreciated.

Most likely, there will be more than two rows in Relative_Axis_Moves, since the differences in the second row evaluate to arrays.
Anyway, a compact way of writing this is
Relative_Axis_Moves = [RealTrans(1,1:5);diff(RealTrans(:,1:5),1,1)];

Related

Matlab: efficienting portion of code, random start

I have the following code that generates a matrix of 15 blocks that will then be used in a Montecarlo approach as multiple starting points. How can I get the same exact result in a smarter way?
assume that J=15*100 are the total simulation and paramNum the number of parameters
[10^-10*ones(paramNum,round(J/15)) 10^-9*ones(paramNum,round(J/15)) 10^-8*ones(paramNum,round(J/15)) 10^-7*ones(paramNum,round(J/15)) 10^-6*ones(paramNum,round(J/15)) 10^-5*ones(paramNum,round(J/15)) rand*10^-5*ones(paramNum,round(J/15)) 10^-4*ones(paramNum,round(J/15)) rand*10^-4*ones(paramNum,round(J/15)) 10^-3*ones(paramNum,round(J/15)) 10^-2*ones(paramNum,round(J/15)) 10^-1*ones(paramNum,round(J/15)) 10^-abs(randn/2)*ones(paramNum,round(J/15))];
you could do
v = 10.^[-10:-5 rand*10^-5 -4:-1 10^-abs(randn/2)];
repmat(repelem(v, 1, round(J/15)), paramNum) .* ...
repmat(ones(paramNum,round(J/15)), numel(v))
Or mimic the repmat/repelem functionality with a for loop. The first is shorter, the later is more understandable.
By the way... it's less than 15 blocks...

MATLAB Structure array blackjack

I'm writing a program to play blackjack and one of the functions calculates the score. It takes in an input which is a structure array of cards and one of the attributes is value (for an ace the value is 11). My function is supposed to determine if the total of the values is over 21 and if 1 of the cards is an ace, then the ace's value is changed to 1. Can anyone help me figure this out please?
for index=1:length(input)
if(input(input).value == 11)
input(index).value = 1;
end;
end;
You're not actually summing the cards in your original snippet. You also seem to have a typo in input(input), I think this should be input(index). If you wanted to do it with a for loop like you have, you'd do something like this:
total = 0;
for index=1:length(input)
if(input(index).value == 11)
input(index).value = 1;
end;
total = total + input(index);
end;
The more MATLAB way of doing things would be to avoid loops by using the sum in-built command.

z3py: How to implement a counter in z3?

I want to design logics similar to a counter in Z3py.
If writing python script, we usually define a variable "counter" and then keep incrementing it when necessary. However, in Z3, there is no variant. Therefore, instead of defining an variant, I define a trace of that variant.
This is a sample code. Suppose there is an array "myArray" of size 5, and the elements in the array are 1 or 2. I want to assert a constraint that there must be two '2's in "myArray"
from z3 import *
s = Solver()
myArray = IntVector('myArray',5)
for i in range(5):
s.add(Or(myArray[i]==1,myArray[i]==2))
counterTrace = IntVector('counterTrace',6)
s.add(counterTrace[0]==0)
for i in range(5):
s.add(If(myArray[i]==2,counterTrace[i+1]==counterTrace[i]+1,counterTrace[i+1]==counterTrace[i]))
s.add(counterTrace[5]==2)
print s.check()
print s.model()
My question is that is this an efficient way of implementing the concept of counter in Z3? In my real problem, which is more complicated, this is really inefficient.
You can do this but it is much easier to create the sum over myArray[i] == 2 ? 1 : 0. That way you don't need to assert anything and you are dealing with normal expressions.

Finding the block using row and column indices - Sudoku Scala

I am new to Scala and am implementing a Sudoku solver. I have a method which returns the set of all possible values a particular element int the grid can take and it works. However, I think that there is a much better way to do this. The problem arises when I try to check the values of other elements in the same block. Is there any other way (than the one shown below) I can find a relationship between the row, column and block to result in cleaner code?
Note that r and c are the row and column indices, respectively, and are given as parameters to the function.
val i=
if(r==0|r==1|r==2){
if(c==0||c==1||c==2)
0
else if(c==3|c==4|c==5)
1
else
2
} else if (r==3|r==4|r==5){
if(c==0||c==1||c==2)
3
else if(c==3||c==4||c==5)
4
else
5
} else {
if(c==0||c==1||c==2)
6
else if(c==3||c==4||c==5)
7
else
8
}
def i(r:Int,c:Int) = r/3*3 + c/3
Although you'll probably want to find a better name/ add comments, it's not really the most intuitive function...

How to extract year from a dates cell array in MATLAB?

i have a cell array as below, which are dates. I am wondering how can i extract the year at the last 4 digits? Could anyone teach me how to locate the year in the string? Thank you!
'31.12.2001'
'31.12.2000'
'31.12.2004'
'31.12.2003'
'31.12.2002'
'31.12.2000'
'31.12.1999'
'31.12.1998'
'31.12.1997'
'31.12.2005'
'31.12.2004'
'31.12.2003'
'31.12.2002'
'31.12.2001'
'31.12.2000'
'31.12.1999'
'31.12.1998'
'31.12.2005'
'31.12.2004'
'31.12.2003'
'31.12.2002'
'31.12.2005'
Example cell array:
A = {'31.12.2001'; '31.12.2002'; '31.12.2003'};
Apply some regular expressions:
B = regexp(A, '\d\d\d\d', 'match')
B = [B{:}];
EDIT: I never realized that matlab will "nest" an extra layer of cells until I tested this. I don't like this solution as much now that I know the second line is necessary. Here is an alternative approach that gets you the years in numeric form:
C = datevec(A, 'dd.mm.yyyy');
C = C(:, 1);
SECOND EDIT: Suprisingly, if your cell array has less than 10000 elements, the regexp approach is faster on my machine. But the output of it is another cell array (which takes up much more memory than a numeric matrix). You can use B = cell2mat(B) to get a character array instead, but this brings the two approaches to approximately equal efficiency.
Just to add a fun answer, designed to take the OP to the stranger regions of Matlab:
C = char(C);
y = (D(:,7:end)-'0') * 10.^(3:-1:0).'
which is an order of magnitude faster than anything posted in the other answers :)
Or, to stay a bit closer to home,
y = cellfun(#(x)str2double(x(7:end)),C);
or, yet another regexp variation:
y = str2num(char(regexprep(C, '\d+\.\d+\.','')));
Assuming your matrix with dates is M or a cell array C:
In case your data is in a cell array start with
M = cell2mat(C)
Then get the relevant part
Y=M(:,end-4:end)
If required you can even make the year a number
Year = str2num(Y)
Using regexp this will works also with dates with slightly different formats, like 1.1.2000, which can mess with you offsets
res = regexp(dates, '(?<=\d+\.\d+\.)\d+', 'match')