Create a multidimensional symbolic array in Matlab 2013b - arrays

According to the Matlab R2016a documentation, a symbolic multidimensional array can be comfortably created by using the sym command as follows:
A = sym('a',[2 2 2])
and the output is
A(:,:,1) =
[ a1_1_1, a1_2_1;
a2_1_1, a2_2_1]
A(:,:,2) =
[ a1_1_2, a1_2_2;
a2_1_2, a2_2_2]
However, I'm using Matlab 2013b and this command doesn't work for multiple dimensions. Is there any other way to create such variables for the 2013b version?

I'm not yet using R2016a, but looking around the code for the sym class (type edit sym in your Command Window), it's not too hard to write one's own function to do this:
function s = ndSym(x,a)
a = a(:).';
format = repmat('%d_',[1 numel(a)]);
x = [x format(1:end-1)];
s = cellfun(#createCharArrayElement,num2cell(1:prod(a)),'UniformOutput',false);
s = sym(reshape(s,a));
function s = createCharArrayElement(k)
[v{1:numel(a)}] = ind2sub(a,k);
s = sprintf(x,v{:});
end
end
You can the test it via A = ndSym('A',[2 2 2]), which returns:
A(:,:,1) =
[ A1_1_1, A1_2_1]
[ A2_1_1, A2_2_1]
A(:,:,2) =
[ A1_1_2, A1_2_2]
[ A2_1_2, A2_2_2]
This function should work for arrays with an arbitrary number of dimensions. I tested it in R2013b and R2015b. However, note that the function above doesn't incorporate any input validation and many of the options/niceties supported by sym. These could be added. Also, be aware that many pre-R2016a symbolic math functions may not support such multi-dimensional arrays.

Related

Spliting arrays at specific sizes

Let's say i have an array with 10 elments:
arr = [1,2,3,4,5,6,7,8,9,10]
Then I want to define a function that takes this arr as parameter to perform
a calculation, let's say for this example the calculation is the difference of means, for example:
If N=2 (That means group the elements of arr in groups of size 2 sequentially):
results=[]
result_1 = 1+2/2 - 3+4/2
result_2 = 3+4/2 - 5+6/2
result_3 = 5+6/2 - 7+8/2
result_4 = 7+8/2 - 9+10/2
The output would be:
results = [-2,-2,-2,-2]
If N=3 (That means group the elements of arr in groups of size 3 sequentially):
results=[]
result_1 = 1+2+3/3 - 4+5+6/3
result_2 = 4+5+6/3 - 7+8+9/3
The output would be:
results = [-3,-3]
I want to do this defining two functions:
Function 1 - Creates the arrays that will be used as input for 2nd function:
Parameters: array, N
returns: k groups of arrays -> seems to be ((length(arr)/N) - 1)
Function 2 - Will be the fucntion that gets the arrays (2 by 2) and perfoms the calculations, in this case, difference of means.
Parameters: array1,array2....arr..arr..
returns: list of the results
Important Note
My idea is to apply these fucntions to a stream of data and the calculation will be the PSI (Population Stability Index)
So, if my stream has 10k samples and I set the first function to N=1000, then the output to the second function will be 1k samples + next 1k samples.
The process will be repetead till the end of the datastream
I was trying to do this in python (I already have the PSI code ready) but now I decided to use Julia for it, but I am pretty new to Julia. So, if anyone can give me some light here will be very helpfull.
In Julia if you have a big Vector and you want to calculate some statistics on groups of 3 elements you could do:
julia> a = collect(1:15); #creates a Vector [1,2,...,15]
julia> mean.(eachcol(reshape(a,3,length(a)÷3)))
5-element Vector{Float64}:
2.0
5.0
8.0
11.0
14.0
Note that both reshape and eachcol are non-allocating so no data gets copied in the process.
If the length of a is not divisible by 3 you could truncate it before reshaping - to avoid allocation use view for that:
julia> a = collect(1:16);
julia> mean.(eachcol(reshape(view(a,1:(length(a)÷3)*3),3,length(a)÷3)))
5-element Vector{Float64}:
2.0
5.0
8.0
11.0
14.0
Depending on what you actually want to do you might also want to take a look at OnlineStats.jl https://github.com/joshday/OnlineStats.jl
Well, I use JavaScript instead Of Python, But it would be same thing in python...
You need a chunks function, that take array and chunk_size (N), lets say chunks([1,2,3,4], 2) -> [[1,2], [3,4]]
we have a sum method that add all element in array, sum([1,2]) -> 3;
Both JavaScript and python support corouting, that you can use for lazy evaluation, And its called Generator function, this type of function can pause its execution, and can resume on demand! This is useful for calculate stream of data.
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Javascript Doesn't support `chunks` method yet, So we need to create one...
Array.prototype.chunks = function* (N) {
let chunk = [];
for (let value of this) {
chunk.push(value)
if (chunk.length == N) {
yield chunk;
chunk = []
}
}
}
Array.prototype.sum = function () {
return this.reduce((a, b) => a + b)
}
function* fnName(arr, N) {
let chunks = arr.chunks(N);
let a = chunks.next().value.sum();
for (let b of chunks) {
yield (a / N) - ((a = b.sum()) / N)
}
}
console.log([...fnName(arr, 2)])
console.log([...fnName(arr, 3)])

how i can use ListOfArrays in Kotlin

I have been working mainly in JAVA but now I need to program some small things in kotlin. Among other things I am trying to convert the result of a database query into a list of array. The result of the database query has 4 columns, the number of rows I can not predict.
I have tried the following:
var output: mutableList<List<String>>
var output = mutableListOf<String>()
var output = mutableListOf<ArrayList>
List<List<String>> listOfLists = new ArrayList<List<String>>()
What I would like to do is this:
output.add(arrayOf("Field1", "Filed2", "Field3", "Field4"))
It can't be that hard, can it?
A list of arrays can be expressed as List<Array<T>>.
So if you want a mutable list to which you can add arrays of strings, simply do:
var output = mutableListOf<Array<String>>()
output.add(arrayOf("Field1", "Filed2", "Field3", "Field4"))
That being said, why do you want to use arrays? It's generally more convenient to work with lists, unless you're constrained by another API.
In kotlin you should use lists where you can. What you are trying to create is:
val output = mutableListOf<List<String>>()
output.add(listOf("Field1", "Filed2", "Field3", "Field4"))
If you are iterating through some other list to create your data for output you could do something like:
val otherList = listOf<String>("a", "b", "v")
val output = otherList.map { otherListData ->
listOf(otherListData + 1, otherListData + 2, otherListData + 3, otherListData + 4)
}
In which case you would only have immutable lists.

Create a 2D list with variable length [torch]

I want to create a 2D list that can have elements of variable lengths inside, for example, if I have a 10x10 list in MATLAB, I can
define it with:
z = cell(10,10)
and start assigning some elements by doing this:
z{2}{3} = ones(3,1)
z{1}{1} = zeros(100,1)
z{1}{2} = []
z{1}{3} = randn(20,1)
...
What is the optimal way to define such empty 2D list in torch? Moreover, is there a way to exploit the tensor structure to do this?
In python, I can do something along this to define an empty 10x10 2D list:
z = [[None for j in range(10)] for i in range(10)]
My best guess for torch is doing something like
z = torch.Tensor(10,10)
for i=1,10 do
for j=1,10 do
z[{{i},{j}}] = torch.Tensor()
end
end
but, this does not work, and defining a tensor inside a tensor seems like a bad idea ...
This is a follow up to the question asked here (however in the link it is asked in python): Create 2D lists in python with variable length indexed vectors
From the documentation I've read, tensors only support primitive numeric data types. You won't be able to use tensor for your intended usage. Leverage tables.
local function makeMatrix(initialVal, ...)
local isfunc = type(initialVal) == "function"
local dimtable = {...}
local function helper(depth)
if depth == 0 then
return isfunc and initialVal() or initialVal
else
local plane = {}
for i = 1, dimtable[depth] do
plane[i] = helper(depth-1)
end
return plane
end
end
return helper(#dimtable)
end
p = makeMatrix(0, 2, 3, 5) -- makes 3D matrix of size 2x3x5 with all elements initialized to 0
makeMatrix(torch.Tensor, m ,n)
Answer from Torch's Google Group forums. Agreeing that tables is the solution:
z = {}
for i=1,10 do
z[i] = {}
for j=1,10 do
z[i][j] = torch.Tensor()
end
end

6- or more dimensional Arrays in Scala

I was looking into multi-dimensional Arrays in Scala and came across some easy ways to create multi-dimensional Arrays. Namely:
val my3DimensionalArray = Array.ofDim[Int](3,4,5)
//array with dimensions 3 x 4 x 5
Or even
val myFilledArray = Array.fill[Int](3,4,5)(0)
//Array of same dimension filled with 0's
However this only works for 1 - 5 dimensional Arrays:
val my6DimensionalArray = Array.ofDim[Int](3,3,3,3,3,3) //Error
So how do people usually deal with creating higher dimensinoal Arrays? Is this left to 3rd party libraries to implement, or are there other data structures that Scala encourages us to use instead of high dimensional Arrays?
// create array of 5-dim-array => 6 dim array
Array.tabulate(3)(_ => Array.ofDim[Int](3,3,3,3,3))
Array.ofDim implementation uses this this pattern. see https://github.com/scala/scala/blob/v2.11.6/src/library/scala/Array.scala#L216-234
If you really want arbitrary numbers of dimensions, you typically use a single flat array with a second array that indexes by dimension to get to the element you want. So, for instance,
class MultiArray(dims: Array[Int]) {
private val array = new Array[Double](dims.product)
private def arrayIndex(index: Array[Int]) = {
var i = index.length - 1
var k = index(i)
var n = 1
while (i > 0) {
n *= dims(i)
k += n * index(i-1)
i -= 1
}
k
}
def apply(index: Array[Int]) = array(arrayIndex(index))
def update(index: Array[Int], value: Double) {
array(arrayIndex(index)) = value
}
}
would be a start. There are various mathematics libraries that do this sort of thing (IIRC Apache Commons Math does I can't quickly find a Java mathematics library that does, but ImgLib2 uses similar techniques for image data (they do local chunking also)). It's not really a generally useful thing to do, which is why you tend to find it in maths libraries.

Declare sparse array in coffeescript

In Javascript I can declare a sparse array like:
a = [, 1]
But that gives an error in Coffeescript. So how can I create sparse arrays in Coffeescript?
I want to do it in a single assignment and not like:
a = []
a[1] = 1
Probably not possible.
But you can always embed javascript:
`a = [, 1]`

Resources