I am trying to compute the code seen below, in a more clever way, using MatLAB:
f=zeros(5,2) %Values irrelevant.
y = {'A1', 'B1';
f(1,1) f(1,2);
f(2,1) f(2,2);
f(3,1) f(3,2);
f(4,1) f(4,2);
f(5,1) f(5,2)};
What I get out is the f matrix with the text of A1 and B1 above the two vectors.
I suppose there is a simpler way to write this, for more complex purposing, but I've tried any combination of parenthesis, brackets and curly brackets, num2str that I could think of.
Any suggestions?
The simplest solution is to use num2cell and concatenate the result with the strings:
y = [{'A1', 'B1'}; num2cell(f)];
Example
>> f = reshape(1:10, 2, [])';
>> y = [{'A1', 'B1'}; num2cell(f)]
y =
'A1' 'B1'
[ 1] [ 2]
[ 3] [ 4]
[ 5] [ 6]
[ 7] [ 8]
[ 9] [10]
Related
I want to compile this list comprehension:
>> lc [reduce [x y] | x in [1 2 3] y in [4 5 6]]
== [[1 4] [1 5] [1 6] [2 4] [2 5] [2 6] [3 4] [3 5] [3 6]]
in:
collect [
foreach x [1 2 3] [
foreach y [4 5 6] [
keep/only reduce [x y]]]]
or:
>> lc [reduce [x y] | x in range [1 5] y in range reduce[1 x] if x + y > 4]
== [[3 2] [3 3] [4 1] [4 2] [4 3] [4 4] [5 1] [5 2] [5 3] [5 4] [5 5]...
in:
collect [
foreach x range [1 5] [
foreach y range reduce [1 x] [
if x + y > 4 [keep/only reduce [x y]]]]]
or:
>> lc/flat [reduce [x y] | x in range [1 5] y in range reduce [1 x] if x + y > 4]
== [3 2 3 3 4 1 4 2 4 3 4 4 5 1 5 2 5 3 5 4 5 5]
in:
collect [
foreach x range [1 5] [
foreach y range reduce [1 x] [
if x + y > 4 [keep reduce [x y]]]]]
My ugly implementation in Red is:
fx: func [code] [func [x] code]
lc: function [list-comp /flat] [ ; list-comp = [code | generators [opt if test]]
flat: any [flat false]
var: none
part-gen: part-if: rest: code: []
rule-var: [set var word! 'in]
list: copy []
generator+if: [copy part-gen to 'if copy part-if to end]
generator: [copy part-gen to end]
emit: fx [append/only list x]
parse list-comp [
copy code to '| skip [
generator+if
|
generator ]
]
parse part-gen [
some [
rule-var (emit var) copy rest to [rule-var | end ] (emit rest)
]
]
option: either flat [copy [keep]] [copy [keep/only]]
code: append option code
if part-if <> [] [code: append/only part-if code]
foreach [l v] reverse list [code: compose [foreach (v) (l) (reduce [code])]]
collect code
]
; from hof.r
range: func [
{Makes a block containing a range of ord! values.
Format: .. [1 5] == [1 2 3 4 5]
.. [1 3 6] == [1 2 5]
.. [2 2 6] == [2 2 2 2 2 2]
}
xs [block!] {either [start end] or [start next end]}
/local range x1 x2 delta result [block!]
][
range: reduce xs
x1: range/1
either range/3 [
x2: range/3
delta: (range/2 - x1)
][
x2: range/2
delta: 1
]
;result: make block! (x2 - x1) / delta
result: copy []
either delta <> 0 [
result: reduce [x1]
loop x2 - x1 [
append result delta + last result
]
][
loop absolute x2 [
insert tail result x1
]
]
result
]
The program does not flow, it is full of variables, of if and append (I had difficulty with parse; compose, in this case, is limited).
Is there a more "rebolish" way (in rebol2/rebol3/red/ren-c) to resolve this problem?
Update: My implementation of the 'compiler' is only an indication of what I intend to do. I am not asking for a correction of my program (I could not even report it) but for a solution that better uses parse and builds the code more clearly.
List-comprehension is a great exercise in dialect building: it's moderately small, has a well-defined purpose and, in general, serves as a code kata for aspiring young Grasshopper โ there is no single "right" way to do it, but many better or worse solutions.
"Rebolish" way would be to stay pragmatic, start with use-cases, and let the problem domain guide you โ perhaps you're solving Euler project and need a set-theoretic library, perhaps what you want are LINQ-like database queries, maybe it's just for the sake of learning and the pleasure of reinventing the wheel, who knows?
While thinking about it, you might realize that you actually don't need list comprehensions, and that's good! The leanest code is the one never being written, and the cleverest solution is the one that nips the problem in the bud by redefining it in simpler terms.
Assuming you're just dabbling with metaprogramming or learning Red without any specific problem in mind, and taking my initial comment with your subsequent edit into account, here are my 2ยข:
Start with a grammar
List comprehension, as a syntactic construct, has a well-defined form. Consulting respective wiki page makes it possible to define a basic grammar right away:
set-builder: [expression '| some generator predicate]
expression: [to '|]
generator: [word! 'in to [generator | predicate | end]]
predicate: ['if to end]
Figure out what to emit
You got that covered already: for each generator in set-builder notation we need an extra layer of foreach; the body of inner foreach should have the form <predicate> [<keep> <expression>].
Define an interface
Instead of /flat I'd use /only, as this is a well-known idiom. Since there are a lot of set-word!s in our function's body, I'll use function constructor:
list: function [spec [block!] /only][...]
Connect the dots
Proceed in baby steps and start simple:
Parse the spec with set-builder and extract the relevant parts for further processing.
Compose extracted parts together.
Step 1
We need to modify our grammar accordingly: add collect / keep where needed and counter edge-cases.
There are 3 parts that we need to extract: expression, generators, and predicate. We can group generators together by adding an extra collect:
set-builder: [collect [expression '| collect some generator predicate]]
expression is straightforward:
expression: [keep to '|]
So as predicate, but we need to keep the if also:
predicate: [ahead 'if keep to end]
But generator is trickier, for two reasons:
There's such a thing called partial match. We cannot just write:
generator: [keep word! 'in keep to [generator | predicate | end]]
When generator or predicate matches inside to, it will recursively keep extra data because of the word! or to end match, messing up the extracted block.
keep behaves differently depending on the number of values being kept: it keeps single value as-is, but groups many of them together.
[1 2 3] -> foreach x [1 2 3] ..., not foreach x 1 2 3 ...
[range [4 5 6]] -> foreach y range [4 5 6] ...
So, what we need is (a) a rule that will check that the thing we look at is indeed a generator, without extracting anything (word! 'in should do) and (b) a slight modification to keep that will always extract a block! โ keep copy dummy-word. Lo and behold:
generator: [keep word! 'in keep copy range to [word! 'in | 'if | end]]
Now mash all of that together:
set-builder: [collect [expression '| collect some generator predicate]]
expression: [keep to '|]
generator: [keep word! 'in keep copy range to [word! 'in | 'if | end]]
predicate: [ahead 'if keep to end]
set [expression ranges: clause:] parse spec set-builder
Note that I use set-word!s inside a block to subvert function to our cause. ranges contains, well, ranges, each in turn containing a word to iterate with and a range itself. clause is either a block! (if it was present in spec) or none! (if there wasn't any).
Step 2
First thing first, we compose the body block of inner foreach:
body: [<clause> [<keep> <expression>]]
This leads to:
body: compose/deep [(any [clause 'do]) [(pick [keep/only keep] only) (expression)]]
Which covers two extra cases: the absence of predicate (unconditional evaluation) and the presence of /only refinement.
Let's figure out how each layer of subsequent foreach looks like:
layer: [foreach <word> <range> <body>]
<word> can be used as-is; <range> might be spliced; <body> is either a body or an innermost layer. Because of the range splicing (i.e. peeling off an extra layer of [...] from extracted data), we cannot use compose/only, so we need wrap <body> in a block and use compose/deep:
layer: [foreach (word) (range) [(body)]]
One last thing: we extracted data from top to bottom, but we need to accrue it the other way around, by layering foreach one on another, starting with body. So we need to reverse the block of ranges:
foreach [range word] reverse ranges [...]
All set! Now just slap collect on top and track body to wrap over on next iteration:
collect foreach [range word] reverse ranges [body: compose/deep layer]
And the whole thing is:
list: function [
"List comprehension"
spec [block!]
/only
][
#1
set-builder: [collect [expression '| collect some generator predicate]]
expression: [keep to '|]
generator: [keep word! 'in keep copy range to [word! 'in | 'if | end]]
predicate: [ahead 'if keep to end]
set [expression ranges: clause:] parse spec set-builder
#2
body: compose/deep [(any [clause 'do]) [(pick [keep/only keep] only) (expression)]]
layer: [foreach (word) (range) [(body)]]
collect foreach [range word] reverse ranges [body: compose/deep layer]
]
Examples:
>> list [as-pair x y | x in [1 2 3] y in [4 5 6]]
== [1x4 1x5 1x6 2x4 2x5 2x6 3x4 3x5 3x6]
>> list/only [reduce [x y] | x in range [1 5] y in range reduce [1 x] if x + y > 4]
== [[3 2] [3 3] [4 1] [4 2] [4 3] [4 4] [5 1] [5 2] [5 3] [5 4] [5 5]]
Is it good? If it helped you to grok Red, Parse and dialects just a little bit, then I think it might be. Is it bad? If so, then you can learn from my mistakes and do better.
In any case, if you find yourself struggling with Parse, there is a reference documentation in the pipeline that you might want to skim through and parse Gitter room where you can ask for help.
Once you refactored your code and is happy with it, share the joy in Red community chat and get some feedback. Until then, take care!
I'm fairly new to coding in the python3 language. I'm trying to construct a function that takes two vectors and subtracts them. Any help would be great. Thank you in advance.
Write a function vecSubtract(vector01, vector02) which takes in two vectors as arguments, and returns the vector which is equal to vector01-vector02.
def vecSubtract(vector01,vector02):
for i in range(min(len(vector01), len(vector02))):
result = [vector01[i]-vector02[i] ]
return result
vector01 = [3, 3, 3]
vector02 = [4, 4, 4]
print(vecSubtract(vector01,vector02))
While you are looping over the vectors (lists actually), you are overwriting your result variable every time.
You probably want to use a list comprehension instead.
def vecSubtract(vector01, vector02):
result = [vector01[i] - vector02[i] for i in range(min(len(vector01), len(vector02)))]
return result
vector01 = [3, 3, 3]
vector02 = [4, 4, 4]
print(vecSubtract(vector01,vector02))
If you really want to use a for loop, you should use result.append() instead of overwriting the variable every time.
Also, it is probably not right to allow subtraction of vectors of different lengths by ignoring the surplus elements in the longer vector. Instead you should probably test that the two vectors are the same length and have the script throw an error if they are not.
I have:
AB_xy = [4, 3, 5, 9, 10]
And I want to access AB_xy elements by combining its name from two separate strings something like this:
['AB' '_xy'](1)
I would like this to return 4 as it would be done by AB_xy(1)but this doesnt work. Suggestions ?
Here, eval would work, if you also include the index
AB_xy = [4, 3, 5, 9, 10];
eval(['AB', '_xy(1)'])
ans =
4
But in general eval should be avoided as there are other alternatives.
Perhaps you could consider making AB a struct with xy as a field.
AB.xy = [4, 3, 5, 9, 10];
and use dynamic field reference
str = 'xy';
AB.(str)(1)
ans =
4
It sounds lika an eval problem.
s = strcat('AB', '_xy', '(', '1', ')')
eval(s)
Of course, just substitute the strings in strcat to variables holding the string(s) you would like to concatenate.
And I agree fully with #BillBokeey. eval is usually a code smell.
I'm at the beginning with the MATLAB software ,and I have two questions:
1) If I want to print a matrix, preceeded by a string, using the fprintf command, how can I do?
For example, to print a matrix alone, I use
fprintf([repmat('%d\t', 1, size(r, 2)) '\n'], r');
But how can I print a string followed by the matrix, all togheter in fprintf, without usind the disp function ?
For example, if I want to print:
>>The matrix you inserted is [1 3; 4 6]
2) How can I do the same thing with vectors (I know it's only a particular case of matrix) ?
I actually use, for example:
>>vectorname=[1 5 2];
>>strtrim(sprintf('%d ', vectorname));
And it's ok for the only numbers of the vector, but If I insert a string in spintf the result is:
>>vectorname=[1 5 2];
>>strtrim(sprintf('Your vector is: %d ', vectorname))
>>Your vector is 1 Your vector is 5 Your vector is 2
How can I inglobe the numbers, one ofter the other, with only one command (sprintf, fprintf, ecc.)??
Thank you very much for the help!
In both cases you can use mat2str.
First case:
input_mat = [1 3; 4 6];
sprintf(['The matrix you inserted is ' mat2str(input_mat)])
ans =
The matrix you inserted is [1 3;4 6]
Second case:
vectorname=[1 5 2];
sprintf(['Your vector is: ', mat2str(vectorname)])
ans =
Your vector is: [1 5 2]
I have recently been perplexed by some of the behavior of sprintf. It appears to be inconsistent in my view and I haven't been able to exactly determine the logic behind some of its behavior. Here is one case that baffles me
C = [1 + 2i, 3+ 4i, 5+6i, 7+8i, 9+10i];
>> sprintf('%+d%+di\n',real(C(1:2)),imag(C(1:2)))
ans =
+1+3i
+2+4i
>> sprintf('%+d%+di\n',real(C(1:3)),imag(C(1:3)))
ans =
+1+3i
+5+2i
+4+6i
I would've expected it to print my complex numbers as in C. Do I need to explicitly create a new vector of interleaved inputs? I feel this is problematic when different types are involved.
EDIT: What I feel the expected output should be
>> sprintf('%+d%+di\n',real(C(1:2)),imag(C(1:2)))
ans =
+1+2i
+3+4i
>> sprintf('%+d%+di\n',real(C(1:3)),imag(C(1:3)))
ans =
+1+2i
+3+4i
+5+6i
The sprintf command you have provided behaves as sprintf('%+d%+di\n', [1, 3], [2, 4]) since real(C(1:2)) returns [1, 3] and imag(C(1:2)) returns [2, 4] which behaves as you've observed.
What you want to do is: sprintf('%+d%+di\n', [1, 3; 2, 4])
It should be accomplished by either looping over elements of C or with the following sprinf('%+d%+di\n', [real(C(1:2)); imag(C(1:2))]).