Get all top level entry values from NotesView - categories

What is the easiest way to get all top level entry values from a notes view? I have found the property "TopLevelEntryCount" returning the number of alle categories, but I want the values, too.
To iterate the view entries and column values need too much time.
Set ecl = view.Allentries
Set ve = ecl.Getfirstentry()
While Not(ve Is Nothing)
If IsArray(ve.Columnvalues(0)) Then
If flag = "" Then
arr = ve.Columnvalues(0)
Else
arr = ArrayUnique(ArrayAppend(arr, ve.Columnvalues(0)))
End If
Else
'error if arr is not already an array
arr = ArrayUnique(ArrayAppend(arr, ve.Columnvalues(0)))
End If
flag = "1"
Set ve = ecl.Getnextentry(ve)
Wend
Anyone know a faster way? It must not be written in LotusScript, actually I would prefer Java, JS or SSJS.

Idea 1: You can use the NotesViewNavigator class, and call the getFirst() and getNextCategory() methods. This should be faster than walking all the entries.
Idea 2: You can use NotesSession.Evaluate() with a formula that does an #Unique on #DbColumn for the first column of view. That should bring you back an array, and you can get the ubound of the array. Formulas tend to be very fast, but evaluate() has to compile them first, so I don't know if this will be faster or not. The disadvantage of this approach is that for very large views, this could exceed formula language's size limits. But if it does prove to be faster, you could catch the exception and fall-back to the slower method of iterating.

Richard's response is perfect!
For a java version it's almost the same:
see the Domino help for getNextCategory the given example below ViewNavigator really answer your need: link here
The evaluate method is also available in java Session

Related

How to set a name for the cell

I have a cell array. when I want create a cell array that its name is : '0691008752' in this case an error :"Invalid field name"
cellUsers.('0691008752') = ....
I know the reason for this error is that a number is called. But I do not know how I can set this name for the cell.
I agree with the comments above, prepending the field with a letter is the best solution for this problem..
One way to make this consistent is to use:
fname = matlab.lang.makeValidName('0691008752')
Its not widely known but you can have fields which begin with number - its bad practice and will almost certainly leads to bugs....
So how to do it, 1st you need to use mex, if you see the mathworks mex example and modify the appropriate line:
memcpy(fieldnames[0],"Doublestuff",sizeof("Doublestuff"));
to:
memcpy(fieldnames[0],"01234",sizeof("01234"));
After compiling and running you get:
Note: You can only access it through dynamic fields names. To update the field you must use mex.

matlab: check which lines of a path are used - graphshortestpath

The related problem comes from the power Grid in Germany. I have a network of substations, which are connected according to the Lines. The shortest way from point A to B was calculated using the graphshortestpath function. The result is a path with the used substation ID's. I am interested in the Line ID's though, so I have written a sequential code to figure out the used Line_ID's for each path.
This algorithm uses two for loops. The first for-loop to access the path from a cell array, the second for-loop looks at each connection and searches the Line_ID from the array.
Question: Is there a better way of coding this? I am looking for the Line_ID's, graphshortestpath only returns the node ID's.
Here is the main code:
for i = i_entries
path_i = LKzuLK_path{i_entries};
if length(path_i) > 3 %If length <=3 no lines are used.
id_vb = 2:length(path_i) - 2;
for id = id_vb
node_start = path_i(id);
node_end = path_i(id+1);
idx_line = find_line_idx(newlinks_vertices, node_start, ...
node_end);
Zuordnung_LKzuLK_pathLines(ind2sub(size_path,i),idx_line) = true;
end
end
end
Note: The first and last enrty of path_i are area ID's, so they are not looked upon for the search for the Line_ID's
function idx_line = find_line_idx(newlinks_vertices, v_id_1, v_id_2)
% newlinks_vertices includes the Line_ID, and then the two connecting substations
% Mirror v_id's in newlinks_vertices:
check_links = [newlinks_vertices; newlinks_vertices(:,1), newlinks_vertices(:,3), newlinks_vertices(:,2)];
tmp_dist1 = find(check_links(:,2) == v_id_1);
tmp_dist2 = find(check_links(tmp_dist1,3) == v_id_2,1);
tmp_dist3 = tmp_dist1(tmp_dist2);
idx_line = check_links(tmp_dist3,1);
end
Note: I have already tried to shorten the first find-search routine, by indexing the links list. This step will return a short list with only relevant entries of the links looked upon. That way the algorithm is reduced of the first and most time consuming find function. The result wasn't much better, the calculation time was still at approximately 7 hours for 401*401 connections, so too long to implement.
I would look into Dijkstra's algorithm to get a faster implementation. This is what Matlab's graphshortestpath uses by default. The linked wiki page probably explains it better than I ever could and even lays it out in pseudocode!

Spark caching strategy

I have a Spark driver that goes like this:
EDIT - earlier version of the code was different & didn't work
var totalResult = ... // RDD[(key, value)]
var stageResult = totalResult
do {
stageResult = stageResult.flatMap(
// Some code that returns zero or more outputs per input,
// and updates `acc` to number of outputs
...
).reduceByKey((x, y) => x.sum(y))
totalResult = totalResult.union(stageResult)
} while(stageResult.count() > 0)
I know from properties of my data that this will eventually terminate (I'm essentially aggregating up the nodes in a DAG).
I'm not sure of a reasonable caching strategy here - should I cache stageResult each time through the loop? Am I setting up a horrible tower of recursion, since each totalResult depends on all previous incarnations of itself? Or will Spark figure that out for me? Or should I put each RDD result in an array and take one big union at the end?
Suggestions will be welcome here, thanks.
I would rewrite this as follows:
do {
stageResult = stageResult.flatMap(
//Some code that returns zero or more outputs per input
).reduceByKey(_+_).cache
totalResult = totalResult.union(stageResult)
} while(stageResult.count > 0)
I am fairly certain(95%) that the stageResult DAG used in the union will be the correct reference (especially since count should trigger it), but this might need to be double checked.
Then when you call totalResult.ACTION, it will put all of the cached data together.
ANSWER BASED ON UPDATED QUESTION
As long as you have the memory space, then I would indeed cache everything along the way as it stores the data of each stageResult, unioning all of those data points at the end. In fact, each union does not rely on the past as that is not the semantics of RDD.union, it merely puts them together at the end. You could just as easily change your code to use a val due to RDD immutability.
As a final note, maybe the DAG visualization will help understand why there would not be recursive ramifications:

Debugging a for loop in matlab

I've been looking throught the documentation, but can't seem to find the bit I want.
I have a for loop and I would like to be able to view every value in the for loop.
for example here is a part of my code:
for d = 1 : nb
%for loop performs blade by blade averaging and produces a column vector
for cc = navg : length(atbmat);
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg;
atbvec2(:,cc) = atb2;
end
%assigns column vector 'atbvec2' to the correct column of the matrix 'atbmat2'
atbmat2(d,1:length(atbvec2)) = atbvec2;
end
I would like to view every value of atb2. I'm a python user(new to MATLAB) and would normally use a simple print statement to find this.
I'm sure there is a way to do it, but I can't quite find how.
Thankyou in advance.
you can use disp in Matlab to print to the screen but you might want to use sprintf first to format it nicely. However for debugging you're better off using a break point and then inspect the variable in the workspace browser graphically. To me, this is one of Matlab's best features.
Have a look at the "Examine Values" section of this article
The simplest way to view it everywhere is to change this line:
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg;
Into this, without semicolon:
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg
That being said, given the nature of your calculation, you could get the information you need as well by simply storing every value of abt2 and observing them afterwards. This may be done in atbmat2 already?
If you want to look at each value at the time it happens, consider setting a breakpoint or conditional breakpoint after the line where abt2 is assigned.

iterating over multiple intervals Matlab

I'd like to make a loop in Matlab that would work only over user specified intervals of time, instead of simply the whole time. How can one write this loop condition?
regards
Generally you and iterate multiple ways. There are two main ways that I can think of off the top of my head. I will also open this up for community wiki so others can just easily edit this as well.
First, using a simple For loop.
The general syntax is for index = 1:someValue
someValue can really be anything that is greater than 1 in this case. Many times it's simply the last index value of a matrix you're wanting to traverse.
You can modify this as well though! Let's say you want every 3rd index starting with the 2nd position in the matrix. All you have to do is: for index = 2:3:someValue The 3 here tells the loop that it should add 3 to the index at the end of each loop iteration until you get to (or surpass) someValue.
Yet another modfication is traversing backwards. In this case you start at the 'end' and move to the beginning. It would look like this: for index = someValue:-1:1 You can also do every 4th index while going backwards for index = someValue:-4:1.
Obviously you can replace the value between the two : to be a step size that you want. You just have to be aware of potential indexing issues that can arrise. Namely trying to index out of bounds of the matrix or potentially going negative.
Secondly here you can modify the value within the loop itself. Generally this isn't the best idea when you're using a for loop as the value of your indexing variable will be changed by the loop as well as by you within the loop. Many times you'll see this done with a while loop or a do while combo.
A few examples are as follows:
index = 0;
do
{
% some operations
index = index + aNumber;
}while(index <= someValue)
In the above example the loop will continue to loop until the index value index becomes greater than or equal to someValue at the end of the current iteration of the loop. This type of loop will ALWAYS, and I repeat ALWAYS execute at least once.
index = 0;
while(index <= someValue)
{
%some operations
index = index + aNumber;
}
In this case the loop will continue to loop while index satisfies the logical statement here. If the statement isn't true when you try to run the loop for the first time it will not execute at all.
Hope this helps and feel free to ask for any additional clarification if you want it!
Others, please feel free to edit to add additional information or clean up what I might have not explained fully =)
Do you mean something like this:
for i = [1:5 7:10 12:14 21:22]
do_func(i)
end
or even
for i = [1:5 4:7 19:-1:15]
do_func(i)
end
?
If you only want to perform an action when a certain condition is true in a loop, you just need something like:
for i=1:length(arr)
if condition(arr(i))
do_something(arr(i));
end
end